saveMerged

tcmts.cli.merge.saveMerged · #24xqhxet · term · runs on the server

uses node:fs

Save text at name (code as #hrkzkwcy writes it, a file's content), as tcm update saves a scratch file (imports nothing in it uses taken out: what either side imports is merged, and one may be the other side's alone), with nothing it says shown: what a merge settles as text, it reports itself. textOnly: only if its code is as it is (only its comments, layout or doc differ). The hash the name holds then, or undefined where it isn't saved (it doesn't typecheck, or its code differs).

import type { Codebase } from "#codebase/tcmts/cli/codebase";
import { fileName } from "#codebase/tcmts/cli/files";
import { pruneUnusedImports, save, withTheirCycles } from "#codebase/tcmts/cli/main";
import { silently } from "#codebase/tcmts/cli/merge";
import type { DefRecord } from "#codebase/tcmts/core/types";
import fs from "node:fs";
import path_1 from "node:path";

export function saveMerged(
  cb: Codebase,
  name: string,
  rec: DefRecord,
  text: string,
  opts: { jsx?: boolean; textOnly?: boolean; command?: string } = {},
): string | undefined {
  const kept = rec.kind === "file";
  const leaf = name.slice(name.lastIndexOf(".") + 1);
  const ns = name.slice(0, Math.max(0, name.lastIndexOf(".")));
  // where scratch files go (so `#codebase` resolves), in a directory of its own, gone afterwards
  const dir = fs.mkdtempSync(path_1.join(cb.sessionDir ?? cb.lay.root, ".merge-"));
  const file = kept
    ? path_1.join(dir, fileName(leaf, rec))
    : path_1.join(dir, `merge${opts.jsx ? ".tsx" : ".ts"}`);
  try {
    return silently(() => {
      fs.writeFileSync(
        file,
        kept
          ? (file.endsWith(".md") ? `<!-- tcm: path ${name} -->\n` : "") + text
          : pruneUnusedImports(file, `${ns ? `// tcm: namespace ${ns}\n` : ""}${text}`).text,
      );
      if (opts.textOnly) {
        const whole = kept ? undefined : withTheirCycles(cb, file, undefined);
        if (!whole || whole.rows.some((r) => r.status !== "identical" && r.status !== "doc"))
          return undefined;
      }
      if (
        !save(
          cb,
          file,
          "update",
          kept ? ns : undefined,
          opts.command ? { command: opts.command } : {},
        )
      )
        return undefined;
      const now = cb.store.hashesAt(name, rec.kind);
      return now.length === 1 ? now[0] : undefined;
    });
  } catch {
    return undefined;
  } finally {
    fs.rmSync(dir, { recursive: true, force: true });
  }
}

uses

used by