todo

tcmts.cli.main.todo · #mty6myxk · term · runs on the server

uses tcmts.cli.style.yellow, which uses node:util

What needs fixing: conflicts, then the dependents that stopped typechecking (the first 20 unless all: one change can break hundreds, and fixing the first often fixes the rest), then code using a version nothing names.

import { needsFixing } from "#codebase/tcmts/cli/codebase";
import type { Codebase } from "#codebase/tcmts/cli/codebase";
import { conflictAt, conflictLine, pendingMerge } from "#codebase/tcmts/cli/merge";
import { bold, dim, green, yellow } from "#codebase/tcmts/cli/style";
import { shortHash } from "#codebase/tcmts/core/hash";
import { isConflicted } from "#codebase/tcmts/core/types";
import type { DefKind } from "#codebase/tcmts/core/types";

export function todo(cb: Codebase, all = false) {
  let n = 0;
  const merging = pendingMerge(cb);
  if (merging)
    console.log(
      `${yellow("merging")} ${bold(merging.theirs)} into ${bold(cb.store.branch().name)}: not finished (what's below settles it, and once nothing's left the branch has it; \`tcm merge --abort\` drops it)`,
    );
  const counts = new Map<string, { hash: string; kind: DefKind }[]>();
  for (const r of cb.store.names(undefined, true))
    counts.set(r.path, [...(counts.get(r.path) ?? []), r]);
  for (const [p, rows] of counts) {
    if (!isConflicted(rows.map((r) => r.kind))) continue;
    const c = conflictAt(cb, p);
    if (!c) continue;
    n++;
    // each definition labelled with the side of the merge it came from
    console.log(conflictLine(c));
  }
  // (what's broken now, worked out: not what was recorded once, which a branch gone back leaves behind)
  const broken = needsFixing(cb);
  for (const t of all ? broken : broken.slice(0, 20)) {
    n++;
    const names = cb.store.pathsOf(t.hash);
    console.log(
      `${yellow("needs fixing")} ${bold(names.join(", ") || shortHash(t.hash))}: ${t.message.split("\n")[0]}`,
    );
  }
  if (!all && broken.length > 20)
    console.log(
      dim(
        `  … and ${broken.length - 20} more needing fixing (\`tcm todo --all\` lists them; fixing these often fixes them)`,
      ),
    );
  // not wrong, but worth knowing: code using a version nothing names (left behind by a change it couldn't follow,
  // or one removed with --force, which is meant); one needing fixing is said above (it couldn't follow), and
  // catches up when it's fixed
  const toFix = new Set(broken.map((t) => t.hash));
  const old = cb.store.unnamedUses().filter((u) => !toFix.has(u.hash));
  for (const u of old.slice(0, 20))
    console.log(
      `${dim("uses an unnamed version")} ${bold(u.path)}: ${shortHash(u.uses)} (made as ${u.madeAs})`,
    );
  if (old.length > 20) console.log(dim(`  … and ${old.length - 20} more`));
  if (old.length)
    console.log(
      dim(
        "  (from a change they couldn't follow, or a name removed with --force; if that's not meant, `tcm edit` them, which imports what replaced it by its name where something names that, then `tcm update`)",
      ),
    );
  console.log(
    n
      ? dim(`\nfix with \`tcm edit <name>\`, change the scratch file, then \`tcm update\``)
      : old.length
        ? ""
        : green("nothing to do"),
  );
}

uses

used by