/** * Recurrence gate for celilo#1235: **services never shell out to `tar`; they * use the `tar` package.** * * `tar@^7` is a declared dependency of @celilo/cli, but backup/restore built * tar command lines and handed them to execSync. That made `tar` an undeclared * runtime dependency on a host binary: Essential on Debian, so it never bit, * but a container base image is where "always there" stops being true. The * services now use the library (same shape the hook boundary is moving to via * pack_directory), and this file keeps them there. * * Scoped to apps/celilo/src/services (the surface celilo#1235 covers). Test * files are excluded — they legitimately drive the system tar to cross-check * archives written by the library. */ import { describe, expect, test } from 'bun:test'; import { readFileSync, readdirSync, statSync } from 'node:fs'; import { join } from 'node:path'; function serviceSourceFiles(): string[] { const dir = join(import.meta.dir, '../services'); const walk = (d: string): string[] => readdirSync(d).flatMap((name) => { const path = join(d, name); if (statSync(path).isDirectory()) return walk(path); return name.endsWith('.ts') && !name.endsWith('.test.ts') ? [path] : []; }); return walk(dir); } describe('recurrence gate: services never shell out to tar', () => { test('scans a non-trivial set of service sources (sanity — the scan actually ran)', () => { expect(serviceSourceFiles().length).toBeGreaterThan(10); }); test('no service source passes a "tar ..." string to execSync', () => { const offenders = serviceSourceFiles().filter((path) => /execSync\(\s*[`'"]tar /.test(readFileSync(path, 'utf-8')), ); expect(offenders).toEqual([]); }); });