feat(config): every lens off until the repository turns it on
Jorijn: "all lenses off by default and opt in only". Config::Defaults() gives every lens run: false; a config that turns on none - a missing `lenses` key included - has the one problem that names the lenses, so config, freeze and run all stop on it; the template ships every lens off, init says to turn lenses on, and the "no lens runs" preflight names the cause. A consumer config without a `lenses` key now needs one, as the CI smoke test's does. Proven with the lens commit before it: the suite (26 passed), and the dry-run comparison recorded there.
This commit is contained in:
parent
febbfc3fcc
commit
101471d81a
15 changed files with 513 additions and 269 deletions
|
|
@ -120,7 +120,9 @@ namespace Crafter::Review::Config {
|
|||
|
||||
Json Defaults() {
|
||||
Json lenses = Json::object();
|
||||
for (const Plan::Lens& lens : Plan::Lenses) lenses[Plan::LensName(lens.file)] = {{"run", true}, {"environment", lens.env}};
|
||||
// Every lens is off until the repository's config turns it on
|
||||
// (2026-10-31, Jorijn: "all lenses off by default and opt in only").
|
||||
for (const Plan::Lens& lens : Plan::Lenses) lenses[Plan::LensName(lens.file)] = {{"run", false}, {"environment", lens.env}};
|
||||
return {
|
||||
// The integration branch a range is measured against (e.g.
|
||||
// origin/dev): merge-base HEAD <base>.
|
||||
|
|
@ -143,8 +145,8 @@ namespace Crafter::Review::Config {
|
|||
// The commands Gate 0 runs by hand, in order (documentation for the
|
||||
// skill; the driver runs none of them).
|
||||
{"gate0", Json::array()},
|
||||
// Per lens: run (false: left out of every run of this repository)
|
||||
// and environment (Plan::Environments).
|
||||
// Per lens: run (off until true: every lens is opt-in) and
|
||||
// environment (Plan::Environments).
|
||||
{"lenses", lenses},
|
||||
// The database under test, for every lens whose environment
|
||||
// reaches it. The URL reaches a db pass's broker, never a prompt,
|
||||
|
|
@ -237,7 +239,13 @@ namespace Crafter::Review::Config {
|
|||
if (!Dyn::In(Dyn::Get(entry, "environment"), environments)) out.push_back(std::format("lenses.{}.environment must be one of {}", it.key(), EnvironmentNames(", ")));
|
||||
}
|
||||
auto runs = [](const Json& entry) { return entry.is_object() && Dyn::Get(entry, "run") == true; };
|
||||
if (!lenses.empty() && !std::ranges::any_of(lenses, runs)) out.emplace_back("lenses: every lens is off - at least one must run");
|
||||
// Every lens is off until the repository turns it on: a config that
|
||||
// turns on none has nothing to run.
|
||||
if (std::ranges::none_of(Plan::Lenses, [&](const Plan::Lens& lens) { return runs(Dyn::Get(lenses, Plan::LensName(lens.file))); })) {
|
||||
std::vector<std::string> names;
|
||||
for (const Plan::Lens& lens : Plan::Lenses) names.push_back(Plan::LensName(lens.file));
|
||||
out.push_back(std::format("lenses: no lens is on - every lens is off until lenses.<name>.run = true turns it on for this repository ({})", Dyn::Join(names, ", ")));
|
||||
}
|
||||
for (const Plan::Lens& lens : Plan::Lenses) {
|
||||
const Json& entry = Dyn::Get(lenses, Plan::LensName(lens.file));
|
||||
if (!lens.empirical || !runs(entry)) continue;
|
||||
|
|
|
|||
|
|
@ -842,7 +842,7 @@ inventory unit, against a frozen commit range.)";
|
|||
} else {
|
||||
fs::create_directories(config.parent_path());
|
||||
std::ofstream(config, std::ios::binary) << Platform::ReadFile(Home() / "process" / "templates" / "config.json").value_or("{}\n");
|
||||
std::println(" wrote .review-gates/config.json (the template: set base, then what the lenses' environments need)");
|
||||
std::println(" wrote .review-gates/config.json (the template: every lens off - turn on the ones this repository runs, set base, then what their environments need)");
|
||||
}
|
||||
// The artifacts and the worktrees stay out of git.
|
||||
const fs::path ignore = cwd / ".gitignore";
|
||||
|
|
@ -887,6 +887,7 @@ inventory unit, against a frozen commit range.)";
|
|||
if (!std::ranges::contains(off, it.key()) && environment && !environment->mcp.empty()) browser = true;
|
||||
}
|
||||
std::println("\nnext:\n {} config - until it reports no problem", Invocation());
|
||||
if (off.size() == Plan::Lenses.size()) std::println(" turn lenses on in .review-gates/config.json (lenses.<name>.run = true) - every lens is off until the repository says which run");
|
||||
if (browser) std::println(" {} browser install - a lens drives the application in Chromium", Invocation());
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1720,7 +1720,9 @@ namespace Crafter::Review::Run {
|
|||
const std::vector<Plan::Gate> gates = Plan::GatesFor(only, without, off);
|
||||
if (gates.empty()) {
|
||||
std::vector<std::string> why;
|
||||
if (!off.empty()) {
|
||||
if (off.size() == Plan::Lenses.size()) {
|
||||
why.emplace_back("the config turns on no lens (every lens is off until lenses.<name>.run = true turns it on)");
|
||||
} else if (!off.empty()) {
|
||||
std::vector<std::string> names;
|
||||
for (const std::string& lf : off) names.push_back(Plan::LensName(lf));
|
||||
why.push_back(std::format("the config turns off {}", Dyn::Join(names, ", ")));
|
||||
|
|
|
|||
Loading…
Reference in a new issue