testMirrorWholeRepository

tcmts.cli.test.e2e.mirror.testMirrorWholeRepository · #vzvlgyvm · term

A whole repository mirrored: its code, and everything else git keeps as files of the codebase (configuration, scripts, hidden and extensionless files, bytes), but not what git ignores.

import { okIn, tempDir } from "#codebase/tcmts/cli/test/e2e/harness";
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";

export const testMirrorWholeRepository = () => {
  const root = tempDir("mirror repo");
  const repo = path.join(root, "repo");
  const dir = path.join(root, "cb");
  const tcm = (...args: string[]) => okIn(dir, ...args);
  const put = (file: string, text: string | Buffer) => {
    fs.mkdirSync(path.dirname(path.join(repo, file)), { recursive: true });
    fs.writeFileSync(path.join(repo, file), text);
  };
  put(".gitignore", "node_modules/\n");
  put("README.md", "# repo\n\nSee [the guide](docs/guide.md).\n");
  put("LICENSE", "MIT\n");
  put("package.json", JSON.stringify({ type: "module" }));
  put("scripts/run.sh", "#!/bin/sh\necho hi\n");
  put(".github/workflows/ci.yml", "on: push\n");
  put("geo/package.json", JSON.stringify({ name: "geo", type: "module" }));
  put("geo/src/index.ts", "export const square = (x: number): number => x * x;\n");
  put("geo/blob.bin", Buffer.from([0x89, 0x50, 0, 0xff]));
  put("docs/guide.md", "# Guide\n");
  put("node_modules/x/index.js", "module.exports = 1;\n");
  assert.equal(spawnSync("git", ["-C", repo, "init", "-q"]).status, 0);
  fs.mkdirSync(dir);
  tcm("init");
  fs.rmSync(path.join(dir, "scratch.ts"));
  assert.doesNotMatch(tcm("import", repo, "--into", "r", "--mirror"), /warning/);
  const ls = tcm("ls", "r");
  for (const line of [/r\.geo\.square +#\w+ +: \(x: number\) => number/, /r\.README +#\w+ +: md/, /r\.LICENSE +#\w+ +: text/, /r\.gitignore +#\w+ +: text/, /r\.package +#\w+ +: json/, /r\.geo\.package +#\w+ +: json/, /r\.scripts\.run +#\w+ +: sh/, /r\._github\.workflows\.ci +#\w+ +: yml/, /r\.geo\.blob +#\w+ +: bin/, /r\.docs\.guide +#\w+ +: md/]) {
    assert.match(ls, line);
  }
  assert.doesNotMatch(ls, /node_modules|r\.x\b/, "what git ignores isn't the codebase's");
  assert.match(tcm("view", "r.LICENSE"), /^MIT$/m);
  assert.match(tcm("view", "r.geo.blob"), /\(bin, 4 bytes\)/);
  // a file changed outside tcm is followed, one removed goes
  put("LICENSE", "Apache-2.0\n");
  assert.match(tcm("view", "r.LICENSE"), /^Apache-2\.0$/m);
  fs.rmSync(path.join(repo, "scripts"), { recursive: true });
  assert.match(tcm("ls", "r"), /- removed +r\.scripts\.run/);
  assert.doesNotMatch(tcm("ls", "r"), /r\.scripts/);
  assert.match(tcm("mirror", "--check"), /the files hash to what the codebase holds/);
}

uses