import { execFileSync } from "node:child_process"; import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import path from "node:path"; import { afterEach, describe, expect, it } from "vitest"; const scriptPath = path.join(process.cwd(), "scripts", "committer"); const tempRepos: string[] = []; function run(cwd: string, command: string, args: string[]) { return execFileSync(command, args, { cwd, encoding: "utf8", }).trim(); } function git(cwd: string, ...args: string[]) { return run(cwd, "git", args); } function createRepo() { const repo = mkdtempSync(path.join(tmpdir(), "committer-test-")); tempRepos.push(repo); git(repo, "init", "-q"); git(repo, "config", "user.email", "test@example.com"); git(repo, "config", "user.name", "Test User"); writeFileSync(path.join(repo, "seed.txt"), "seed\n"); git(repo, "add", "seed.txt"); git(repo, "commit", "-qm", "seed"); return repo; } function writeRepoFile(repo: string, relativePath: string, contents: string) { const fullPath = path.join(repo, relativePath); mkdirSync(path.dirname(fullPath), { recursive: true }); writeFileSync(fullPath, contents); } function commitWithHelper(repo: string, commitMessage: string, ...args: string[]) { return run(repo, "bash", [scriptPath, commitMessage, ...args]); } function committedPaths(repo: string) { const output = git(repo, "diff-tree", "--no-commit-id", "--name-only", "-r", "HEAD"); return output.split("\n").filter(Boolean).toSorted(); } afterEach(() => { while (tempRepos.length > 0) { const repo = tempRepos.pop(); if (repo) { rmSync(repo, { force: true, recursive: true }); } } }); describe("scripts/committer", () => { it("accepts supported path argument shapes", () => { const cases = [ { commitMessage: "test: plain argv", files: [ ["alpha.txt", "alpha\n"], ["nested/file with spaces.txt", "beta\n"], ] as const, args: ["alpha.txt", "nested/file with spaces.txt"], expected: ["alpha.txt", "nested/file with spaces.txt"], }, { commitMessage: "test: space blob", files: [ ["alpha.txt", "alpha\n"], ["beta.txt", "beta\n"], ] as const, args: ["alpha.txt beta.txt"], expected: ["alpha.txt", "beta.txt"], }, { commitMessage: "test: newline blob", files: [ ["alpha.txt", "alpha\n"], ["nested/file with spaces.txt", "beta\n"], ] as const, args: ["alpha.txt\nnested/file with spaces.txt"], expected: ["alpha.txt", "nested/file with spaces.txt"], }, ] as const; for (const testCase of cases) { const repo = createRepo(); for (const [file, contents] of testCase.files) { writeRepoFile(repo, file, contents); } commitWithHelper(repo, testCase.commitMessage, ...testCase.args); expect(committedPaths(repo)).toEqual(testCase.expected); } }); });