summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/man/just-mr.1.org8
-rw-r--r--src/other_tools/just_mr/cli.hpp9
-rw-r--r--src/other_tools/just_mr/main.cpp27
-rw-r--r--src/other_tools/just_mr/utils.hpp40
-rw-r--r--test/end-to-end/just-mr/defaults.sh29
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