mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
fix(projects): scope legacy paths to hosts
This commit is contained in:
18
packages/app/src/projects/project-key.test.ts
Normal file
18
packages/app/src/projects/project-key.test.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { describe, expect, test } from "vitest";
|
||||||
|
import { resolveProjectKey } from "./project-key";
|
||||||
|
|
||||||
|
describe("resolveProjectKey", () => {
|
||||||
|
test("keeps legacy path-shaped project IDs local to their host", () => {
|
||||||
|
const resolve = (serverId: string) =>
|
||||||
|
resolveProjectKey({ serverId, projectId: "/workspace/app" });
|
||||||
|
|
||||||
|
expect(resolve("host-a")).not.toBe(resolve("host-b"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("keeps recognized legacy remote project IDs shared across hosts", () => {
|
||||||
|
const resolve = (serverId: string) =>
|
||||||
|
resolveProjectKey({ serverId, projectId: "remote:github.com/acme/app" });
|
||||||
|
|
||||||
|
expect(resolve("host-a")).toBe(resolve("host-b"));
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -5,9 +5,9 @@ export function resolveProjectKey(input: {
|
|||||||
}): string {
|
}): string {
|
||||||
if (input.projectKey) return input.projectKey;
|
if (input.projectKey) return input.projectKey;
|
||||||
// COMPAT(projectKey): added in v0.2.4 on 2026-07-28; remove after 2027-01-28.
|
// COMPAT(projectKey): added in v0.2.4 on 2026-07-28; remove after 2027-01-28.
|
||||||
// Older daemons used remote/path-shaped project IDs as their grouping key. New opaque IDs
|
// Older daemons used recognized remote-shaped project IDs as their grouping key. Their
|
||||||
// must remain host-local when the new field is absent.
|
// path-shaped and opaque IDs are host-local when the new field is absent.
|
||||||
return input.projectId.startsWith("prj_") ? frameHostProjectKey(input) : input.projectId;
|
return input.projectId.startsWith("remote:") ? input.projectId : frameHostProjectKey(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function frameHostProjectKey(input: { serverId: string; projectId: string }): string {
|
export function frameHostProjectKey(input: { serverId: string; projectId: string }): string {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import type { ProjectPlacementPayload } from "@getpaseo/protocol/messages";
|
import type { ProjectPlacementPayload } from "@getpaseo/protocol/messages";
|
||||||
|
import { frameHostProjectKey } from "@/projects/project-key";
|
||||||
import type { WorkspaceDescriptor } from "@/stores/session-store";
|
import type { WorkspaceDescriptor } from "@/stores/session-store";
|
||||||
import { buildProjects } from "./projects";
|
import { buildProjects } from "./projects";
|
||||||
|
|
||||||
@@ -451,7 +452,11 @@ describe("buildProjects", () => {
|
|||||||
const acme = result.projects.find(
|
const acme = result.projects.find(
|
||||||
(project) => project.projectKey === "remote:github.com/acme/app#subdir:packages/client",
|
(project) => project.projectKey === "remote:github.com/acme/app#subdir:packages/client",
|
||||||
);
|
);
|
||||||
const legacy = result.projects.find((project) => project.projectKey === "legacy-project");
|
const legacy = result.projects.find(
|
||||||
|
(project) =>
|
||||||
|
project.projectKey ===
|
||||||
|
frameHostProjectKey({ serverId: "legacy", projectId: "legacy-project" }),
|
||||||
|
);
|
||||||
|
|
||||||
expect(acme?.hosts[0]?.repoRoot).toBe("/worktrees/app/main/packages/client");
|
expect(acme?.hosts[0]?.repoRoot).toBe("/worktrees/app/main/packages/client");
|
||||||
expect(legacy?.hosts[0]?.repoRoot).toBe("/repo/legacy");
|
expect(legacy?.hosts[0]?.repoRoot).toBe("/repo/legacy");
|
||||||
@@ -584,8 +589,8 @@ describe("buildProjects", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(result.projects.map((project) => project.projectKey)).toEqual([
|
expect(result.projects.map((project) => project.projectKey)).toEqual([
|
||||||
"/repo/one",
|
frameHostProjectKey({ serverId: "local", projectId: "/repo/one" }),
|
||||||
"/repo/two",
|
frameHostProjectKey({ serverId: "local", projectId: "/repo/two" }),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -646,7 +651,7 @@ describe("buildProjects", () => {
|
|||||||
"remote:gitlab.com/acme/api",
|
"remote:gitlab.com/acme/api",
|
||||||
"remote:bitbucket.org/acme/cli",
|
"remote:bitbucket.org/acme/cli",
|
||||||
"remote:github.com/acme/web",
|
"remote:github.com/acme/web",
|
||||||
"/repo/local",
|
frameHostProjectKey({ serverId: "local", projectId: "/repo/local" }),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -739,7 +744,9 @@ describe("buildProjects", () => {
|
|||||||
|
|
||||||
expect(result.projects).toHaveLength(1);
|
expect(result.projects).toHaveLength(1);
|
||||||
const summary = result.projects[0];
|
const summary = result.projects[0];
|
||||||
expect(summary?.projectKey).toBe("legacy-project");
|
expect(summary?.projectKey).toBe(
|
||||||
|
frameHostProjectKey({ serverId: "old-daemon", projectId: "legacy-project" }),
|
||||||
|
);
|
||||||
expect(summary?.projectName).toBe("Legacy");
|
expect(summary?.projectName).toBe("Legacy");
|
||||||
expect(summary?.githubUrl).toBeUndefined();
|
expect(summary?.githubUrl).toBeUndefined();
|
||||||
expect(summary?.hosts).toHaveLength(1);
|
expect(summary?.hosts).toHaveLength(1);
|
||||||
@@ -770,7 +777,9 @@ describe("buildProjects", () => {
|
|||||||
|
|
||||||
expect(result.projects).toHaveLength(1);
|
expect(result.projects).toHaveLength(1);
|
||||||
const summary = result.projects[0];
|
const summary = result.projects[0];
|
||||||
expect(summary?.projectKey).toBe("/repo/fresh");
|
expect(summary?.projectKey).toBe(
|
||||||
|
frameHostProjectKey({ serverId: "local", projectId: "/repo/fresh" }),
|
||||||
|
);
|
||||||
expect(summary?.totalWorkspaceCount).toBe(0);
|
expect(summary?.totalWorkspaceCount).toBe(0);
|
||||||
expect(summary?.hosts).toHaveLength(1);
|
expect(summary?.hosts).toHaveLength(1);
|
||||||
// repoRoot must be non-empty or the project settings screen treats the host
|
// repoRoot must be non-empty or the project settings screen treats the host
|
||||||
|
|||||||
Reference in New Issue
Block a user