Build composable Camino packages with explicit type and source dependencies

This commit is contained in:
Timothy J. Aveni
2026-09-22 14:42:54 -07:00
parent 7173751f37
commit 82a4542746
30 changed files with 736 additions and 420 deletions
+14 -10
View File
@@ -19,7 +19,7 @@ import { planEvolution, type WorkspaceRevision, type EvolutionReview } from "../
import { withFileLock } from "./file-lock.js";
const execFile = promisify(callback);
type Source = { repository: string; commit: string };
export type UpgradeNode = { kind: "workspace" | "package" | "interface"; directory: string; source: Source };
export type UpgradeNode = { kind: "workspace" | "package" | "interface" | "build"; directory: string; source: Source };
export type UpgradeSpec = {
nodes: UpgradeNode[];
quixos?: Source;
@@ -105,7 +105,7 @@ export const discoverUpgradeSpec = async (workbench: string): Promise<UpgradeSpe
commit: await command(root, "jj", ["--ignore-working-copy", "log", "--no-graph", "-r", "@", "-T", "commit_id"]),
},
},
...graph.resources.map((entry: { kind: "interface" | "package"; directory: string; source: Source }) => ({
...graph.resources.map((entry: { kind: "interface" | "package" | "build"; directory: string; source: Source }) => ({
kind: entry.kind,
source: entry.source,
directory: path.relative(workbench, path.resolve(workbench, entry.directory)),
@@ -139,7 +139,7 @@ export const planPinUpgrades = async (workbenchPath: string, spec: UpgradeSpec):
const keys = new Map<string, string>();
for (const node of spec.nodes) {
validSource(node.source);
if (!["workspace", "package", "interface"].includes(node.kind) || keys.has(sourceKey(node)))
if (!["workspace", "package", "interface", "build"].includes(node.kind) || keys.has(sourceKey(node)))
throw new Error("Duplicate/invalid upgrade resource identity");
keys.set(sourceKey(node), node.directory);
}
@@ -423,14 +423,14 @@ export const applyPinUpgrades = async (
const directory = await location(plan.workbench, node.directory);
const standalone = await compileCapabilityResourceRepository({
rootDirectory: directory,
kind: node.kind as "package" | "interface",
kind: node.kind as "package" | "interface" | "build",
source,
resolveResource,
});
for (const dependency of standalone.resources) resources.set(dependency.key, dependency);
resources.set(key, {
key,
kind: node.kind as "package" | "interface",
kind: node.kind as "package" | "interface" | "build",
source,
directory,
lock: standalone.lock,
@@ -450,11 +450,15 @@ export const applyPinUpgrades = async (
kind: node.kind,
source: node.source,
directory: node.directory,
resourceId:
node.resource.kind === "interface"
? node.resource.revision.interfaceId
: node.resource.revision.packageId,
revisionId: node.resource.revision.revisionId,
...(node.resource.kind === "build"
? {}
: {
resourceId:
node.resource.kind === "interface"
? node.resource.revision.interfaceId
: node.resource.revision.packageId,
revisionId: node.resource.revision.revisionId,
}),
dependencies: [...node.dependencies.entries()].map(([binding, dependency]) => ({
binding,
resourceKey: dependency.key,