test: -- reaches neither the project args nor the script

`run -- record -- a` has to run the record script with the args `--`
and `a`: the first `--` ends the options, the second comes after the
script's name and is the script's. The project args keep only what
stood before `run`. And `run -- -x` has to look for a script called
-x, since after `--` an option-like word is an operand. Before the fix
the first `--` showed up in the project args, and `-x` joined it there
while the bare `run` listed the scripts and succeeded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-10-31 05:10:38 +01:00
commit 70b68b98a5
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB

View file

@ -218,6 +218,29 @@ int main() {
Check(fs::exists(binSentinel) && fs::exists(buildSentinel), "`clean` as a script argument deleted nothing"); Check(fs::exists(binSentinel) && fs::exists(buildSentinel), "`clean` as a script argument deleted nothing");
} }
// `--` ends this tool's options and goes nowhere itself. In the
// project's args it gave the project a variant of its own, and every
// sibling that inherits the args one too. The word after it is an
// operand even when it looks like an option, here the script's name;
// after the name, a `--` is the script's like any other word.
{
fs::remove(scratch / "record.txt");
const std::int32_t code = RunWith({"crafter-build", project, "--flavour=x", "run", "--", "record", "--", "a"});
Check(code == 42, std::format("the script after `--` ran (got {})", code));
const std::vector<std::string> expected = {
"arg:--", "arg:a",
"projectArg:--flavour=x",
"debug:false",
"project:script-fixture",
};
const std::vector<std::string> record = ReadLines(scratch / "record.txt");
Check(record == expected, "`--` reached neither the project args nor the script");
if (record != expected) {
for (const std::string& line : record) std::println(std::cerr, " recorded: {}", line);
}
Check(RunWith({"crafter-build", project, "run", "--", "-x"}) == 1, "after `--` a word that looks like an option names the script");
}
// The first word after `run` is the name even when it is a verb. // The first word after `run` is the name even when it is a verb.
{ {
fs::remove(scratch / "record.txt"); fs::remove(scratch / "record.txt");