Crafter.Build/tests/Script/fixture/project.cpp
Jorijn van der Graaf 8d031a1dba
test(script): names, arguments and exit codes, in process and by CLI
RunScript on hand-built configurations: the named script alone runs,
with the project, the project directory and the arguments exactly as
given; its return value comes back whole from 0 to 255 and as 1 outside
that; a script that throws exits 1. A project without scripts, a
duplicate, an untypeable name, a missing callback and an unknown name
all fail without running anything. ctx.Run returns the command's exit
code and 128+signal for a killed one, and ShellQuote carries quotes,
spaces and expansions through sh intact.

Then the same through Run() with a fixture project, because the parsing
is where this goes wrong. `run record a --help -v clean --debug
--version run` must hand all seven words to the script, leave the one
project arg that stood before `run` alone, and not delete the staged
bin/ and build/. `run clean` and `run help` look for scripts of those
names. Moving the two capture branches below the verbs in the parse
loop fails this test.

The command-line half needs the installed module sources and is skipped
without them, but only when the in-process half reported no failure.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-20 19:08:26 +02:00

30 lines
1.3 KiB
C++

// SPDX-License-Identifier: LGPL-3.0-only
// SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
import std;
import Crafter.Build;
using namespace Crafter;
// Scripts that report what they were handed. The test that loads this file
// drives the real command line and can only observe a script through its
// exit code and through what it leaves in the project directory.
extern "C" Configuration CrafterBuildProject(std::span<const std::string_view> args) {
Configuration cfg;
cfg.path = "./";
cfg.name = "script-fixture";
cfg.outputName = "script-fixture";
// Applied so that a script argument which leaked into the project's
// args would be visible: in cfg.projectArgs, or as cfg.debug.
ApplyStandardArgs(cfg, args);
cfg.scripts.push_back({"record", [](ScriptContext& ctx) {
std::ofstream out(ctx.projectDir / "record.txt");
for (const std::string& arg : ctx.args) std::println(out, "arg:{}", arg);
for (const std::string& arg : ctx.project.projectArgs) std::println(out, "projectArg:{}", arg);
std::println(out, "debug:{}", ctx.project.debug);
std::println(out, "project:{}", ctx.project.name);
return 42;
}});
cfg.scripts.push_back({"shell", [](ScriptContext& ctx) { return ctx.Run("exit 7"); }});
return cfg;
}