Unify scoped development with ordinary Workspace authoring commands
This commit is contained in:
@@ -16,8 +16,11 @@ export async function prepareDevelopmentSources(options: {
|
|||||||
directory: string;
|
directory: string;
|
||||||
cacheDirectory: string;
|
cacheDirectory: string;
|
||||||
locations?: Record<string, string>;
|
locations?: Record<string, string>;
|
||||||
|
workspaceId?: string;
|
||||||
}) {
|
}) {
|
||||||
const source = workspaceSourcePin(options.source);
|
const source = workspaceSourcePin(options.source);
|
||||||
|
if (options.workspaceId !== undefined && !/^[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/.test(options.workspaceId))
|
||||||
|
throw Error("Development source binding requires a Workspace UUID");
|
||||||
const destination = path.resolve(options.directory);
|
const destination = path.resolve(options.directory);
|
||||||
const cache = path.resolve(options.cacheDirectory);
|
const cache = path.resolve(options.cacheDirectory);
|
||||||
if (cache === destination || cache.startsWith(destination + path.sep))
|
if (cache === destination || cache.startsWith(destination + path.sep))
|
||||||
@@ -43,7 +46,8 @@ export async function prepareDevelopmentSources(options: {
|
|||||||
const parent = path.dirname(destination);
|
const parent = path.dirname(destination);
|
||||||
await mkdir(parent, { recursive: true });
|
await mkdir(parent, { recursive: true });
|
||||||
const staging = await mkdtemp(path.join(parent, ".development-sources-"));
|
const staging = await mkdtemp(path.join(parent, ".development-sources-"));
|
||||||
const workspaceId = randomUUID();
|
// This local association does not create or grant access to a hosted Graph.
|
||||||
|
const workspaceId = options.workspaceId ?? randomUUID();
|
||||||
try {
|
try {
|
||||||
const resources = [];
|
const resources = [];
|
||||||
for (const entry of closure.resources) {
|
for (const entry of closure.resources) {
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ const main = async () => {
|
|||||||
"--dir",
|
"--dir",
|
||||||
...(args[1] !== "restore" ? ["--locations"] : []),
|
...(args[1] !== "restore" ? ["--locations"] : []),
|
||||||
...(args[1] === "checkout" ? ["--repository-prefix"] : []),
|
...(args[1] === "checkout" ? ["--repository-prefix"] : []),
|
||||||
...(args[1] === "develop" ? ["--cache"] : []),
|
...(args[1] === "develop" ? ["--cache", "--workspace-id"] : []),
|
||||||
...(args[1] === "backup" ? ["--output"] : []),
|
...(args[1] === "backup" ? ["--output"] : []),
|
||||||
].includes(args[i]) ||
|
].includes(args[i]) ||
|
||||||
!args[i + 1] ||
|
!args[i + 1] ||
|
||||||
@@ -100,7 +100,11 @@ const main = async () => {
|
|||||||
if (args[1] === "develop") {
|
if (args[1] === "develop") {
|
||||||
if (!flags.get("--cache")) throw Error("source develop requires --cache DIRECTORY");
|
if (!flags.get("--cache")) throw Error("source develop requires --cache DIRECTORY");
|
||||||
const { prepareDevelopmentSources } = await import("./development-sources.js");
|
const { prepareDevelopmentSources } = await import("./development-sources.js");
|
||||||
result = await prepareDevelopmentSources({ ...options, cacheDirectory: path.resolve(flags.get("--cache")!) });
|
result = await prepareDevelopmentSources({
|
||||||
|
...options,
|
||||||
|
cacheDirectory: path.resolve(flags.get("--cache")!),
|
||||||
|
...(flags.has("--workspace-id") ? { workspaceId: flags.get("--workspace-id")! } : {}),
|
||||||
|
});
|
||||||
} else if (args[1] === "backup") {
|
} else if (args[1] === "backup") {
|
||||||
if (!flags.get("--output")) throw Error("source backup requires --output DIRECTORY");
|
if (!flags.get("--output")) throw Error("source backup requires --output DIRECTORY");
|
||||||
const { backupWorkspaceSources } = await import("./source-backup.js");
|
const { backupWorkspaceSources } = await import("./source-backup.js");
|
||||||
|
|||||||
@@ -172,6 +172,27 @@ test("exact source closure recovers through explicitly selected bundles, preserv
|
|||||||
directory: path.join(temporary, "b"),
|
directory: path.join(temporary, "b"),
|
||||||
});
|
});
|
||||||
assert.notEqual(a.workspaceId, b.workspaceId);
|
assert.notEqual(a.workspaceId, b.workspaceId);
|
||||||
|
const assigned = "f8f2f8a3-328c-45a2-847a-31869ad28ce7";
|
||||||
|
const c = await prepareDevelopmentSources({
|
||||||
|
source: root,
|
||||||
|
cacheDirectory: directory,
|
||||||
|
directory: path.join(temporary, "assigned"),
|
||||||
|
workspaceId: assigned,
|
||||||
|
});
|
||||||
|
assert.equal(c.workspaceId, assigned);
|
||||||
|
assert.equal(
|
||||||
|
JSON.parse(await readFile(path.join(c.directory, ".quixos/resource-graph.json"), "utf8")).workspaceId,
|
||||||
|
assigned,
|
||||||
|
);
|
||||||
|
await assert.rejects(
|
||||||
|
prepareDevelopmentSources({
|
||||||
|
source: root,
|
||||||
|
cacheDirectory: directory,
|
||||||
|
directory: path.join(temporary, "invalid"),
|
||||||
|
workspaceId: "not-a-workspace",
|
||||||
|
}),
|
||||||
|
/Workspace UUID/,
|
||||||
|
);
|
||||||
const aRoot = path.join(a.directory, "root"),
|
const aRoot = path.join(a.directory, "root"),
|
||||||
bRoot = path.join(b.directory, "root");
|
bRoot = path.join(b.directory, "root");
|
||||||
assert.equal((await exec("git", ["remote", "get-url", "origin"], { cwd: aRoot })).stdout.trim(), root.repository);
|
assert.equal((await exec("git", ["remote", "get-url", "origin"], { cwd: aRoot })).stdout.trim(), root.repository);
|
||||||
|
|||||||
Reference in New Issue
Block a user