mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
fix(migrate): validate source refs and expansions
This commit is contained in:
@@ -118,6 +118,41 @@ test("does not adopt an existing worktree on a different branch", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("does not recreate a missing workspace from a tag", () => {
|
||||
const repo = createRepository("tag-only-workspace", null);
|
||||
execFileSync("git", ["commit", "--allow-empty", "-m", "initial"], {
|
||||
cwd: repo,
|
||||
env: {
|
||||
...process.env,
|
||||
GIT_AUTHOR_NAME: "Paseo Test",
|
||||
GIT_AUTHOR_EMAIL: "test@paseo.local",
|
||||
GIT_COMMITTER_NAME: "Paseo Test",
|
||||
GIT_COMMITTER_EMAIL: "test@paseo.local",
|
||||
},
|
||||
});
|
||||
execFileSync("git", ["tag", "release"], { cwd: repo });
|
||||
|
||||
const inspected = inspectCatalog({
|
||||
repos: [repoRecord("repo", repo)],
|
||||
workspaces: [
|
||||
{
|
||||
id: "workspace-tag-only",
|
||||
repoId: "repo",
|
||||
branch: "release",
|
||||
state: "ready",
|
||||
path: null,
|
||||
archiveCommit: null,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(inspected.projects[0]?.workspaces[0]).toMatchObject({
|
||||
sourceId: "workspace-tag-only",
|
||||
disposition: "missing-ref",
|
||||
notices: [{ code: "missing-workspace-ref" }],
|
||||
});
|
||||
});
|
||||
|
||||
function createRepository(name: string, settings: string | null): string {
|
||||
const repo = mkdtempSync(path.join(os.tmpdir(), `paseo-inspect-${name}-`));
|
||||
cleanup.push(repo);
|
||||
|
||||
@@ -134,7 +134,7 @@ function inspectWorkspace(
|
||||
};
|
||||
}
|
||||
|
||||
if (workspace.branch && refExists(repo.rootPath, workspace.branch)) {
|
||||
if (workspace.branch && localBranchExists(repo.rootPath, workspace.branch)) {
|
||||
return {
|
||||
sourceId: workspace.id,
|
||||
state: "ready",
|
||||
@@ -209,6 +209,17 @@ function refExists(rootPath: string, ref: string): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
function localBranchExists(rootPath: string, branch: string): boolean {
|
||||
const branchName = branch.replace(/^refs\/heads\//, "");
|
||||
if (!branchName) return false;
|
||||
try {
|
||||
git(rootPath, ["show-ref", "--verify", "--quiet", `refs/heads/${branchName}`]);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function safeDirectoryName(workspace: ConductorWorkspaceRecord): string {
|
||||
const candidate = workspace.path ? path.basename(workspace.path.replaceAll("\\", "/")) : "";
|
||||
if (/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(candidate) && candidate !== "." && candidate !== "..") {
|
||||
|
||||
@@ -161,6 +161,7 @@ test("preserves literal or escaped Conductor names and rewrites active variables
|
||||
arithmeticDirect: { command: "serve --port $(( $CONDUCTOR_PORT ))" },
|
||||
arithmeticBraced: { command: "serve --port $(( ${CONDUCTOR_PORT} ))" },
|
||||
arithmeticOffset: { command: "serve --port $(( CONDUCTOR_PORT + 1 ))" },
|
||||
prefixExpansion: { command: "serve --length ${#CONDUCTOR_PORT}" },
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -187,6 +188,12 @@ test("preserves literal or escaped Conductor names and rewrites active variables
|
||||
message:
|
||||
"scripts.arithmeticOffset.port_arithmetic: Conductor port arithmetic is not imported because Paseo reserves one service port.",
|
||||
});
|
||||
expect(inspected.notices).toContainEqual({
|
||||
code: "conductor-setting-unsupported",
|
||||
level: "warning",
|
||||
message:
|
||||
"scripts.prefixExpansion: Unsupported Conductor variables: CONDUCTOR_PORT. Command was not imported.",
|
||||
});
|
||||
});
|
||||
|
||||
test("skips cwd scripts on Windows instead of emitting POSIX shell syntax", () => {
|
||||
|
||||
@@ -613,7 +613,7 @@ function collectConductorVariables(command: string): string[] {
|
||||
const names = new Set<string>();
|
||||
const mask = activeShellMask(command);
|
||||
const direct =
|
||||
/\$\{(CONDUCTOR_[A-Za-z0-9_]+)(?=[^A-Za-z0-9_])|\$(CONDUCTOR_[A-Za-z0-9_]+)(?![A-Za-z0-9_])/g;
|
||||
/\$\{[#!]?(CONDUCTOR_[A-Za-z0-9_]+)(?=[^A-Za-z0-9_])|\$(CONDUCTOR_[A-Za-z0-9_]+)(?![A-Za-z0-9_])/g;
|
||||
for (const match of command.matchAll(direct)) {
|
||||
if (mask[match.index] !== "$") continue;
|
||||
const name = match[1] ?? match[2];
|
||||
|
||||
Reference in New Issue
Block a user