diff options
-rw-r--r-- | share/man/just-mr.1.org | 8 | ||||
-rw-r--r-- | src/other_tools/just_mr/cli.hpp | 9 | ||||
-rw-r--r-- | src/other_tools/just_mr/main.cpp | 27 | ||||
-rw-r--r-- | src/other_tools/just_mr/utils.hpp | 40 | ||||
-rw-r--r-- | test/end-to-end/just-mr/defaults.sh | 29 |
5 files changed, 105 insertions, 8 deletions
diff --git a/share/man/just-mr.1.org b/share/man/just-mr.1.org index e641285d..8b109f1b 100644 --- a/share/man/just-mr.1.org +++ b/share/man/just-mr.1.org @@ -42,6 +42,14 @@ See *just-mr-repository-config(5)* for more details on the input format. The default configuration lookup order can be adjusted in the just-mrrc file. See *just-mrrc(5)* for more details. + *-D*, *--defines* JSON\\ + Defines, via an in-line JSON object, an overlay configuration + for *just(1)*; if used as a launcher for a subcommand known + to support *--defines*, this defines value is forwarded, + otherwise it is ignored. If *-D* is given several times, + the *-D* options overlay (in the sense of ~map_union~) in + the order they are given on the command line. + *--local-build-root* PATH\\ Root for local CAS, cache, and build directories. The path will be created if it does not exist already. This option overwrites any values set diff --git a/src/other_tools/just_mr/cli.hpp b/src/other_tools/just_mr/cli.hpp index 4e363460..1d6580da 100644 --- a/src/other_tools/just_mr/cli.hpp +++ b/src/other_tools/just_mr/cli.hpp @@ -44,6 +44,7 @@ struct MultiRepoCommonArguments { std::optional<std::filesystem::path> git_path{std::nullopt}; bool norc{false}; std::size_t jobs{std::max(1U, std::thread::hardware_concurrency())}; + std::vector<std::string> defines{}; }; struct MultiRepoLogArguments { @@ -158,6 +159,14 @@ static inline void SetupMultiRepoCommonArguments( clargs->jobs, "Number of jobs to run (Default: Number of cores).") ->type_name("NUM"); + app->add_option_function<std::string>( + "-D,--defines", + [clargs](auto const& d) { clargs->defines.emplace_back(d); }, + "Define overlay configuration to be forwarded to the invocation of" + " just, in case the subcommand supports it; otherwise ignored.") + ->type_name("JSON") + ->trigger_on_parse(); // run callback on all instances while parsing, + // not after all parsing is done } static inline auto SetupMultiRepoLogArguments( diff --git a/src/other_tools/just_mr/main.cpp b/src/other_tools/just_mr/main.cpp index 72dd7b79..6c172e6a 100644 --- a/src/other_tools/just_mr/main.cpp +++ b/src/other_tools/just_mr/main.cpp @@ -1259,6 +1259,7 @@ void DefaultReachableRepositories( bool use_config{false}; bool use_build_root{false}; bool use_launcher{false}; + bool supports_defines{false}; std::optional<std::filesystem::path> mr_config_path{std::nullopt}; if (subcommand and kKnownJustSubcommands.contains(*subcommand)) { @@ -1275,6 +1276,7 @@ void DefaultReachableRepositories( } use_build_root = kKnownJustSubcommands.at(*subcommand).build_root; use_launcher = kKnownJustSubcommands.at(*subcommand).launch; + supports_defines = kKnownJustSubcommands.at(*subcommand).defines; } // build just command std::vector<std::string> cmd = {arguments.common.just_path->string()}; @@ -1313,6 +1315,31 @@ void DefaultReachableRepositories( if (arguments.log.plain_log) { cmd.emplace_back("--plain-log"); } + if (supports_defines) { + auto overlay_config = Configuration(); + for (auto const& s : arguments.common.defines) { + try { + auto map = Expression::FromJson(nlohmann::json::parse(s)); + if (not map->IsMap()) { + Logger::Log(LogLevel::Error, + "Defines entry {} does not contain a map.", + nlohmann::json(s).dump()); + std::exit(kExitClargsError); + } + overlay_config = overlay_config.Update(map); + } catch (std::exception const& e) { + Logger::Log(LogLevel::Error, + "Parsing defines entry {} failed with error:\n{}", + nlohmann::json(s).dump(), + e.what()); + std::exit(kExitClargsError); + } + } + if (not overlay_config.Expr()->Map().empty()) { + cmd.emplace_back("-D"); + cmd.emplace_back(overlay_config.ToString()); + } + } // add args read from just-mrrc if (subcommand and arguments.just_cmd.just_args.contains(*subcommand)) { for (auto const& subcmd_arg : diff --git a/src/other_tools/just_mr/utils.hpp b/src/other_tools/just_mr/utils.hpp index a7d43415..d992a895 100644 --- a/src/other_tools/just_mr/utils.hpp +++ b/src/other_tools/just_mr/utils.hpp @@ -49,18 +49,42 @@ struct JustSubCmdFlags { bool config; bool build_root; bool launch; + bool defines; }; // ordered, so that we have replicability std::map<std::string, JustSubCmdFlags> const kKnownJustSubcommands{ - {"version", {false /*config*/, false /*build_root*/, false /*launch*/}}, - {"describe", {true /*config*/, false /*build_root*/, false /*launch*/}}, - {"analyse", {true /*config*/, true /*build_root*/, false /*launch*/}}, - {"build", {true /*config*/, true /*build_root*/, true /*launch*/}}, - {"install", {true /*config*/, true /*build_root*/, true /*launch*/}}, - {"rebuild", {true /*config*/, true /*build_root*/, true /*launch*/}}, - {"install-cas", {false /*config*/, true /*build_root*/, false /*launch*/}}, - {"gc", {false /*config*/, true /*build_root*/, false /*launch*/}}}; + {"version", + {false /*config*/, + false /*build_root*/, + false /*launch*/, + false /*defines*/}}, + {"describe", + {true /*config*/, + false /*build_root*/, + false /*launch*/, + true /*defines*/}}, + {"analyse", + {true /*config*/, + true /*build_root*/, + false /*launch*/, + true /*defines*/}}, + {"build", + {true /*config*/, true /*build_root*/, true /*launch*/, true /*defines*/}}, + {"install", + {true /*config*/, true /*build_root*/, true /*launch*/, true /*defines*/}}, + {"rebuild", + {true /*config*/, true /*build_root*/, true /*launch*/, true /*defines*/}}, + {"install-cas", + {false /*config*/, + true /*build_root*/, + false /*launch*/, + false /*defines*/}}, + {"gc", + {false /*config*/, + true /*build_root*/, + false /*launch*/, + false /*defines*/}}}; nlohmann::json const kDefaultConfigLocations = nlohmann::json::array( {{{"root", "workspace"}, {"path", "repos.json"}}, diff --git a/test/end-to-end/just-mr/defaults.sh b/test/end-to-end/just-mr/defaults.sh index 77febef2..de641ab2 100644 --- a/test/end-to-end/just-mr/defaults.sh +++ b/test/end-to-end/just-mr/defaults.sh @@ -63,9 +63,13 @@ parser.add_argument("-f", "--log-file", dest="log_file", parser.add_argument("--log-limit", dest="log_limit") parser.add_argument("--log-append", dest="log_append", action="store_true", default=False) +parser.add_argument("-D", "--defines", dest="defines", + action="append", default=[]) (options, args) = parser.parse_known_args(sys.argv[2:]) target_dir=args[-1] +with open(os.path.join(target_dir, "defines"), "w") as f: + f.write(json.dumps([json.loads(x) for x in options.defines])) with open(os.path.join(target_dir, "log-limit"), "w") as f: f.write(json.dumps(options.log_limit)) with open(os.path.join(target_dir, "log-file"), "w") as f: @@ -141,4 +145,29 @@ test $(jq '. == ["cmd", "line", "launcher"] ' "${PARSE_DIR}/launcher") = "true" build "${PARSE_DIR}" 2>&1 test "$(cat "${PARSE_DIR}/launcher")" = 'null' +## Command-line -D + +# ignored on non-build commands +"${JUST_MR}" --local-build-root "${LBR}" --just "${PARSE}" \ + -D 'this is not json' version "${PARSE_DIR}" 2>&1 +test $(jq '. == [] ' "${PARSE_DIR}/defines") = "true" + +# not forwarded, if empty +"${JUST_MR}" --local-build-root "${LBR}" --just "${PARSE}" \ + -D '{}' build "${PARSE_DIR}" 2>&1 +test $(jq '. == [] ' "${PARSE_DIR}/defines") = "true" + +# combined on forwarding +"${JUST_MR}" --local-build-root "${LBR}" --just "${PARSE}" \ + -D '{"foo": "bar"}' -D '{"baz": "baz"}' -D '{"foo": "override"}' \ + build "${PARSE_DIR}" 2>&1 +test $(jq '. == [ {"foo": "override", "baz": "baz"}] ' "${PARSE_DIR}/defines") = true + +# but passed arguments are given separately + +"${JUST_MR}" --local-build-root "${LBR}" --just "${PARSE}" \ + -D '{"foo": "bar"}' -D '{"baz": "baz"}' \ + build -D '{"foo": "override"}' -D '{"x": "y"}' "${PARSE_DIR}" 2>&1 +test $(jq '. == [ {"foo": "bar", "baz": "baz"}, {"foo": "override"}, {"x": "y"}] ' "${PARSE_DIR}/defines") = true + echo OK |