classifyPaths

tcmts.cli.main.classifyPaths · #ckvj7wip · term · runs anywhere

import type { Codebase } from "#codebase/tcmts/cli/codebase";
import type { Row } from "#codebase/tcmts/cli/main";
import { shortHash } from "#codebase/tcmts/core/hash";
import type { DefRecord } from "#codebase/tcmts/core/types";

export function classifyPaths(cb: Codebase, planned: { def: DefRecord; path: string }[]): Row[] {
  return planned.map(({ def, path: p }) => {
    // only definitions in the same space compete: `type User` and `const User` live side by side
    const hs = cb.store.hashesAt(p, def.kind);
    if (hs.length === 1 && hs[0] === def.hash) {
      // the same code with a different doc (or none now): the doc isn't part of the hash, so saving it changes the
      // doc this branch shows
      const stored = cb.store.getDef(def.hash)?.doc;
      return (def.doc || undefined) !== (stored || undefined)
        ? {
            def,
            path: p,
            status: "doc",
            note: !stored ? "doc added" : def.doc ? "doc changed" : "doc removed",
          }
        : { def, path: p, status: "identical" };
    }
    if (hs.length > 1)
      return {
        def,
        path: p,
        status: "conflict",
        note: `resolves the conflict: replaces its ${hs.length} definitions, and re-derives what used them, once`,
      };
    if (hs.length === 1)
      return {
        def,
        path: p,
        status: "update",
        note: `was ${shortHash(hs[0]!)}`,
        retyped: cb.store.getDef(hs[0]!)?.signature !== def.signature,
      };
    const others = cb.store.pathsOf(def.hash);
    if (others.length)
      return { def, path: p, status: "alias", note: `same as ${others.join(", ")}` };
    return { def, path: p, status: "new" };
  });
}

uses

used by