feat(lanes): add isIntegrationEnabled toggle check (F3a)
This commit is contained in:
@@ -111,3 +111,32 @@ describe("resolveProfile — E2 declarations", () => {
|
||||
assert.deepEqual(profile.generatedMergePaths, ["api/openapi.json", "api/client.ts"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isIntegrationEnabled", () => {
|
||||
it("returns false when integrations.env doesn't exist at all", () => {
|
||||
const lane = makeLane();
|
||||
writeProfile(lane.cwd, "PORTS=api\n");
|
||||
assert.equal(profileLib.isIntegrationEnabled(lanesLib.getLane(lane.id), "tracker"), false);
|
||||
});
|
||||
|
||||
it("returns true when <NAME>_ENABLED=1 is set", () => {
|
||||
const lane = makeLane();
|
||||
writeProfile(lane.cwd, "PORTS=api\n");
|
||||
fsMod.writeFileSync(
|
||||
pathMod.join(lane.cwd, ".ccam", "profile", "integrations.env"),
|
||||
"TRACKER_ENABLED=1\nTRACKER_PROJECT=demo\n"
|
||||
);
|
||||
assert.equal(profileLib.isIntegrationEnabled(lanesLib.getLane(lane.id), "tracker"), true);
|
||||
});
|
||||
|
||||
it("returns false when the flag is 0 or absent from an existing file", () => {
|
||||
const lane = makeLane();
|
||||
writeProfile(lane.cwd, "PORTS=api\n");
|
||||
fsMod.writeFileSync(
|
||||
pathMod.join(lane.cwd, ".ccam", "profile", "integrations.env"),
|
||||
"DEV_QC_ENABLED=0\n"
|
||||
);
|
||||
assert.equal(profileLib.isIntegrationEnabled(lanesLib.getLane(lane.id), "dev_qc"), false);
|
||||
assert.equal(profileLib.isIntegrationEnabled(lanesLib.getLane(lane.id), "ci_wait"), false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -195,6 +195,34 @@ function profileSearchPaths(lane) {
|
||||
.map((root) => path.join(root, PROFILE_SUBDIR));
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a named integration is turned on for this lane — reads
|
||||
* .ccam/profile/integrations.env (same two-location search as profile.env:
|
||||
* the lane's own working copy first, the source repo second) and checks
|
||||
* <NAME>_ENABLED=1. A missing file or missing key is off, never an error —
|
||||
* same off-by-default shape every other optional declaration follows.
|
||||
*
|
||||
* @param {object} lane - Lane row (`cwd`, `source_repo`).
|
||||
* @param {string} name - Lowercase integration name, e.g. "tracker", "dev_qc", "ci_wait".
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isIntegrationEnabled(lane, name) {
|
||||
const candidates = [lane.cwd, lane.source_repo].filter(Boolean);
|
||||
const key = `${name.toUpperCase()}_ENABLED`;
|
||||
for (const root of candidates) {
|
||||
const filePath = path.join(root, PROFILE_SUBDIR, "integrations.env");
|
||||
if (!fs.existsSync(filePath)) continue;
|
||||
let declared;
|
||||
try {
|
||||
declared = parseEnvFile(fs.readFileSync(filePath, "utf8"));
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
return declared[key] === "1";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A `harness_spawn` shell function, injected into every hook.
|
||||
*
|
||||
@@ -428,6 +456,7 @@ module.exports = {
|
||||
parseQcBootEnv,
|
||||
resolveProfile,
|
||||
profileSearchPaths,
|
||||
isIntegrationEnabled,
|
||||
hookEnv,
|
||||
runHook,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user