diff --git a/src/Cmd/Run.cc b/src/Cmd/Run.cc index 79c009f4c..0fb9f2ad5 100644 --- a/src/Cmd/Run.cc +++ b/src/Cmd/Run.cc @@ -30,8 +30,9 @@ const Subcmd RUN_CMD = .setDesc("Build and execute src/main.cc") .addOpt(OPT_RELEASE) .addOpt(OPT_JOBS) - .setArg(Arg{ "args" } - .setDesc("Arguments passed to the program") + .setArg(Arg{ "[-- args]" } + .setDesc("Arguments passed to the program (use -- to " + "separate cabin options from program arguments)") .setVariadic(true) .setRequired(false)) .setMainFn(runMain); @@ -61,6 +62,10 @@ static Result runMain(const CliArgsView args) { nextArg.data(), nextArg.data() + nextArg.size(), numThreads); Ensure(ec == std::errc(), "invalid number of threads: {}", nextArg); setParallelism(numThreads); + } else if (arg == "--") { + // End of cabin options, everything after is for the program + ++itr; + break; } else { // Unknown argument is the start of the program arguments. break; diff --git a/tests/06-run.sh b/tests/06-run.sh index 553f7f1d8..64efea005 100644 --- a/tests/06-run.sh +++ b/tests/06-run.sh @@ -34,4 +34,42 @@ EOF ) ' +test_expect_success 'cabin run -- passes arguments to program' ' + OUT=$(mktemp -d) && + test_when_finished "rm -rf $OUT" && + cd $OUT && + "$CABIN" new test_args && + cd test_args && + cp "$WHEREAMI/06-run/test_args.cc" src/main.cc && + "$CABIN" run -- --help --version foo 1>stdout && + ( + cat >stdout_exp <<-EOF && +argc=4 +arg[1]=--help +arg[2]=--version +arg[3]=foo +EOF + test_cmp stdout_exp stdout + ) +' + +test_expect_success 'cabin run without -- stops at first unknown arg' ' + OUT=$(mktemp -d) && + test_when_finished "rm -rf $OUT" && + cd $OUT && + "$CABIN" new test_args2 && + cd test_args2 && + cp "$WHEREAMI/06-run/test_args.cc" src/main.cc && + "$CABIN" run foo bar --release 1>stdout && + ( + cat >stdout_exp <<-EOF && +argc=4 +arg[1]=foo +arg[2]=bar +arg[3]=--release +EOF + test_cmp stdout_exp stdout + ) +' + test_done diff --git a/tests/06-run/test_args.cc b/tests/06-run/test_args.cc new file mode 100644 index 000000000..e03e9c2c5 --- /dev/null +++ b/tests/06-run/test_args.cc @@ -0,0 +1,7 @@ +#include +int main(int argc, char* argv[]) { + std::cout << "argc=" << argc << '\n'; + for (int i = 1; i < argc; ++i) { + std::cout << "arg[" << i << "]=" << argv[i] << '\n'; + } +} \ No newline at end of file