feat(lanes): detect docker-compose database/Redis and wire ENV_REWRITE (A3)

This commit is contained in:
2026-08-04 09:13:20 +07:00
parent 0ecc2eec24
commit c4b11799dc
2 changed files with 173 additions and 5 deletions
+64
View File
@@ -107,3 +107,67 @@ describe("IDENTIFIER_RE", () => {
}
});
});
function writeCompose(repo, servicesYaml) {
fs.writeFileSync(path.join(repo, "docker-compose.yml"), `services:\n${servicesYaml}\n`);
}
describe("detectNode: database + Redis + env wiring", () => {
it("detects a postgres service in docker-compose.yml", () => {
const repo = makeRepo();
writePkg(path.join(repo, "backend"), { start: "node server.js" });
writePkg(path.join(repo, "frontend"), { dev: "vite" });
writeCompose(repo, " postgres:\n image: postgres:16\n");
const facts = detect.detectNode(repo);
assert.equal(facts.database.dbKind, "postgres");
assert.equal(facts.database.dbService, "postgres");
assert.match(facts.database.dbPrefix, /_l$/);
assert.equal(facts.redis, false);
});
it("detects redis independently of postgres", () => {
const repo = makeRepo();
writePkg(path.join(repo, "backend"), { start: "node server.js" });
writePkg(path.join(repo, "frontend"), { dev: "vite" });
writeCompose(repo, " cache_redis:\n image: redis:7\n");
const facts = detect.detectNode(repo);
assert.equal(facts.database, null);
assert.equal(facts.redis, true);
});
it("finds no database when there is no docker-compose.yml", () => {
const repo = makeRepo();
writePkg(repo, { start: "node index.js" });
const facts = detect.detectNode(repo);
assert.equal(facts.database, null);
assert.equal(facts.redis, false);
assert.equal(facts.env, null);
});
it("wires ENV_REWRITE when a database is found and backend/.env.example exists", () => {
const repo = makeRepo();
writePkg(path.join(repo, "backend"), { start: "node server.js" });
writePkg(path.join(repo, "frontend"), { dev: "vite" });
writeCompose(repo, " postgres:\n image: postgres:16\n redis:\n image: redis:7\n");
fs.writeFileSync(path.join(repo, "backend", ".env.example"), "FOO=bar\n");
const facts = detect.detectNode(repo);
assert.equal(facts.env.file, "backend/.env");
assert.equal(facts.env.source, "backend/.env.example");
assert.equal(facts.env.fromExample, true);
assert.deepEqual(facts.env.rewrite, ["DATABASE_URL", "REDIS_URL"]);
});
it("leaves env null when a database is found but there is no .env or .env.example", () => {
const repo = makeRepo();
writePkg(repo, { start: "node index.js" });
writeCompose(repo, " postgres:\n image: postgres:16\n");
assert.equal(detect.detectNode(repo).env, null);
});
it("rejects a docker-compose service name that fails the shell-identifier check", () => {
const repo = makeRepo();
writePkg(repo, { start: "node index.js" });
writeCompose(repo, ' "postgres; rm -rf /":\n image: postgres:16\n');
assert.equal(detect.detectNode(repo).database, null);
});
});