- validateRemoteUrl checks the literal scheme prefix git will receive and refuses %/backslash in the authority (WHATWG normalises https:/host and percent-escapes that git reads differently); route test for EBADURL. - Parent-session scrub also drops AI_AGENT, and GIT_EDITOR when it is Claude Code's `true`. - canonicalCwd resolves a not-yet-existing path through its deepest existing ancestor, so a symlinked parent still yields one lane. - Note the clock-step ceiling on liveServers' boot-time filter. - Docs/header wording: the Active runs count is lane-scoped.
This commit is contained in:
@@ -735,6 +735,15 @@ describe("an unborn repo and `publish`", () => {
|
||||
"https://host/r .git",
|
||||
"https://host/r.git\n",
|
||||
"ssh://-oProxyCommand=x/r.git",
|
||||
// WHATWG parses these as https://host/x, but git sees no "://" and reads
|
||||
// them as scp-like ssh to a host named "https" — the checked string and
|
||||
// the used string must be the same string.
|
||||
"https:/host/r.git",
|
||||
"https:host/r.git",
|
||||
"https:\\\\host\\r.git",
|
||||
// Percent-encoded userinfo/host that git decodes into a leading "-".
|
||||
"ssh://%2DoProxyCommand=x@host/r.git",
|
||||
"ssh://git@%2Dhost/r.git",
|
||||
"-git@host:r.git",
|
||||
"",
|
||||
42,
|
||||
|
||||
@@ -921,6 +921,13 @@ describe("the lane git surface: changes, branches, actions (issue #34)", () => {
|
||||
assert.equal(bogus.body.error.code, "EBADACTION");
|
||||
});
|
||||
|
||||
it("400s a publish to a url that is not https, ssh or scp-like", async () => {
|
||||
const r = await request("POST", `/api/lanes/${laneId}/git/publish`, { url: "file:///tmp/x" });
|
||||
assert.equal(r.status, 400);
|
||||
assert.equal(r.body.error.code, "EBADURL");
|
||||
assert.equal(g(dir, "remote").trim(), "");
|
||||
});
|
||||
|
||||
it("reads the log, one commit's diff, a whole file, the path list and the tree", async () => {
|
||||
const log = await request("GET", `/api/lanes/${laneId}/git/log?limit=5`);
|
||||
assert.equal(log.status, 200);
|
||||
@@ -1442,6 +1449,23 @@ describe("/api/lanes tool tests", () => {
|
||||
assert.equal(second.body.lane.id, first.body.lane.id);
|
||||
});
|
||||
|
||||
it("POST /api/lanes/ensure resolves a symlinked path, existing or not, to one lane", async () => {
|
||||
const real = fs.mkdtempSync(path.join(os.tmpdir(), "lane-real-"));
|
||||
const link = `${real}-link`;
|
||||
fs.symlinkSync(real, link);
|
||||
try {
|
||||
for (const sub of ["", "/not-yet"]) {
|
||||
const first = await request("POST", "/api/lanes/ensure", { cwd: real + sub });
|
||||
const second = await request("POST", "/api/lanes/ensure", { cwd: link + sub });
|
||||
assert.equal(second.body.created, false, sub);
|
||||
assert.equal(second.body.lane.id, first.body.lane.id, sub);
|
||||
}
|
||||
} finally {
|
||||
fs.rmSync(link);
|
||||
fs.rmSync(real, { recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("POST /api/lanes/ensure re-ensuring with the same tool is a no-op", async () => {
|
||||
const first = await request("POST", "/api/lanes/ensure", {
|
||||
cwd: "/tmp/same-tool-lane",
|
||||
|
||||
Reference in New Issue
Block a user