summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Aehlig <klaus.aehlig@huawei.com>2023-09-20 10:49:03 +0200
committerKlaus Aehlig <klaus.aehlig@huawei.com>2023-09-20 18:43:39 +0200
commit5fbba3abfa6e725b47a170b0c4f7ce5f8c2671e7 (patch)
tree77d3afb331013f83769d7b3007f722af821acd3e
parent70aef852705090b48ded2842269daa7884fa54fd (diff)
downloadjustbuild-5fbba3abfa6e725b47a170b0c4f7ce5f8c2671e7.tar.gz
just-mr: add option to override the absent pragma
Using absent repositories depends on a just-serve endpoint. As such, it is not a datum of the project, but one of the available infrastructure. As the latter can change independently of the project, it is desriable to have the option to specify those pieces of information in separate files.
-rw-r--r--share/man/just-mr.1.md6
-rw-r--r--share/man/just-mrrc.5.md8
-rw-r--r--src/other_tools/just_mr/cli.hpp11
-rw-r--r--src/other_tools/just_mr/launch.cpp3
-rw-r--r--src/other_tools/just_mr/main.cpp18
-rw-r--r--src/other_tools/just_mr/setup_utils.cpp67
-rw-r--r--src/other_tools/just_mr/setup_utils.hpp3
7 files changed, 107 insertions, 9 deletions
diff --git a/share/man/just-mr.1.md b/share/man/just-mr.1.md
index e05828c6..12bd71a5 100644
--- a/share/man/just-mr.1.md
+++ b/share/man/just-mr.1.md
@@ -53,6 +53,12 @@ order:
The default configuration lookup order can be adjusted in the just-mrrc
file. See **`just-mrrc`**(5) for more details.
+**`--absent`** *`PATH`*
+Path to a file specifying which repositories are to be considered
+absent, overriding the values set by the *`"pragma"`* entries in the
+multi-repository configuration. The file has to contain a JSON array
+of those repository names to be considered absent.
+
**`-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
diff --git a/share/man/just-mrrc.5.md b/share/man/just-mrrc.5.md
index 5a7d0b82..b0a434e3 100644
--- a/share/man/just-mrrc.5.md
+++ b/share/man/just-mrrc.5.md
@@ -51,6 +51,10 @@ The just-mrrc is given by a JSON object.
detail). The lookup is performed in the same order the location
objects appear in the list.
+ - The value for the key *`"absent"`*, if provided, is a JSON list
+ of location objects to search for a file specifying the list of
+ absent repositories.
+
- The value for the key *`"local build root"`* is a single location
object, specifying the path to use as the local build root. For more
details, see **`just-mr`**(1).
@@ -124,6 +128,10 @@ An example just-mrrc file could look like the following:
, {"root": "home", "path": ".just-repos.json"}
, {"root": "system", "path": "etc/just-repos.json"}
]
+, "absent":
+ [ {"root": "workspace", "path": "etc/absent.json"}
+ , {"root": "home", "path": ".just-absent"}
+ ]
, "local build root": {"root": "home", "path": ".cache/just"}
, "checkout locations": {"root": "home", "path": ".just-local.json"}
, "local launcher": ["env", "--"]
diff --git a/src/other_tools/just_mr/cli.hpp b/src/other_tools/just_mr/cli.hpp
index 328ab666..4c0c6e34 100644
--- a/src/other_tools/just_mr/cli.hpp
+++ b/src/other_tools/just_mr/cli.hpp
@@ -33,6 +33,7 @@
/// \brief Arguments common to all just-mr subcommands
struct MultiRepoCommonArguments {
std::optional<std::filesystem::path> repository_config{std::nullopt};
+ std::optional<std::filesystem::path> absent_repository_file{std::nullopt};
std::optional<std::filesystem::path> checkout_locations_file{std::nullopt};
std::vector<std::string> explicit_distdirs{};
JustMR::PathsPtr just_mr_paths = std::make_shared<JustMR::Paths>();
@@ -98,6 +99,16 @@ static inline void SetupMultiRepoCommonArguments(
"Repository-description file to use.")
->type_name("FILE");
app->add_option_function<std::string>(
+ "--absent",
+ [clargs](auto const& file_raw) {
+ clargs->absent_repository_file =
+ std::filesystem::weakly_canonical(
+ std::filesystem::absolute(file_raw));
+ },
+ "File specifying the repositories to consider absent (overrides the "
+ "pragma in the config file).")
+ ->type_name("FILE");
+ app->add_option_function<std::string>(
"--local-build-root",
[clargs](auto const& local_build_root_raw) {
clargs->just_mr_paths->root = std::filesystem::weakly_canonical(
diff --git a/src/other_tools/just_mr/launch.cpp b/src/other_tools/just_mr/launch.cpp
index 26b87059..4e9403a8 100644
--- a/src/other_tools/just_mr/launch.cpp
+++ b/src/other_tools/just_mr/launch.cpp
@@ -60,7 +60,8 @@ auto CallJust(std::optional<std::filesystem::path> const& config_file,
if (not lock) {
return kExitGenericFailure;
}
- auto config = JustMR::Utils::ReadConfiguration(config_file);
+ auto config = JustMR::Utils::ReadConfiguration(
+ config_file, common_args.absent_repository_file);
use_config = true;
mr_config_path = MultiRepoSetup(config,
diff --git a/src/other_tools/just_mr/main.cpp b/src/other_tools/just_mr/main.cpp
index 85105e50..1e8905d6 100644
--- a/src/other_tools/just_mr/main.cpp
+++ b/src/other_tools/just_mr/main.cpp
@@ -590,6 +590,21 @@ void SetupLogging(MultiRepoLogArguments const& clargs) {
}
}
}
+ // read path to absent repository specification if not already provided by
+ // the user
+ if (not clargs->common.absent_repository_file) {
+ auto absent_order = rc_config["absent"];
+ if (absent_order.IsNotNull() and absent_order->IsList()) {
+ for (auto const& entry : absent_order->List()) {
+ auto path = ReadLocation(
+ entry, clargs->common.just_mr_paths->workspace_root);
+ if (path and FileSystemManager::IsFile(path->first)) {
+ clargs->common.absent_repository_file = path->first;
+ break;
+ }
+ }
+ }
+ }
// read config lookup order
auto config_lookup_order = rc_config["config lookup order"];
if (config_lookup_order.IsNotNull()) {
@@ -744,7 +759,8 @@ auto main(int argc, char* argv[]) -> int {
}
// The remaining options all need the config file
- auto config = JustMR::Utils::ReadConfiguration(config_file);
+ auto config = JustMR::Utils::ReadConfiguration(
+ config_file, arguments.common.absent_repository_file);
// Run subcommand `setup` or `setup-env`
if (arguments.cmd == SubCommand::kSetup or
diff --git a/src/other_tools/just_mr/setup_utils.cpp b/src/other_tools/just_mr/setup_utils.cpp
index b325a71d..332503ea 100644
--- a/src/other_tools/just_mr/setup_utils.cpp
+++ b/src/other_tools/just_mr/setup_utils.cpp
@@ -148,7 +148,8 @@ void DefaultReachableRepositories(
}
auto ReadConfiguration(
- std::optional<std::filesystem::path> const& config_file_opt) noexcept
+ std::optional<std::filesystem::path> const& config_file_opt,
+ std::optional<std::filesystem::path> const& absent_file_opt) noexcept
-> std::shared_ptr<Configuration> {
if (not config_file_opt) {
Logger::Log(LogLevel::Error, "Cannot find repository configuration.");
@@ -156,7 +157,7 @@ auto ReadConfiguration(
}
auto const& config_file = *config_file_opt;
- std::shared_ptr<Configuration> config{nullptr};
+ auto config = nlohmann::json::object();
if (not FileSystemManager::IsFile(config_file)) {
Logger::Log(LogLevel::Error,
"Cannot read config file {}.",
@@ -165,14 +166,13 @@ auto ReadConfiguration(
}
try {
std::ifstream fs(config_file);
- auto map = Expression::FromJson(nlohmann::json::parse(fs));
- if (not map->IsMap()) {
+ config = nlohmann::json::parse(fs);
+ if (not config.is_object()) {
Logger::Log(LogLevel::Error,
"Config file {} does not contain a JSON object.",
config_file.string());
std::exit(kExitConfigError);
}
- config = std::make_shared<Configuration>(map);
} catch (std::exception const& e) {
Logger::Log(LogLevel::Error,
"Parsing config file {} failed with error:\n{}",
@@ -180,7 +180,62 @@ auto ReadConfiguration(
e.what());
std::exit(kExitConfigError);
}
- return config;
+
+ if (absent_file_opt) {
+ if (not FileSystemManager::IsFile(*absent_file_opt)) {
+ Logger::Log(LogLevel::Error,
+ "Not file specifying the absent repositories: {}",
+ absent_file_opt->string());
+ std::exit(kExitConfigError);
+ }
+ try {
+ std::ifstream fs(*absent_file_opt);
+ auto absent = nlohmann::json::parse(fs);
+ if (not absent.is_array()) {
+ Logger::Log(LogLevel::Error,
+ "Expected {} to contain a list of repository "
+ "names, but found {}",
+ absent_file_opt->string(),
+ absent.dump());
+ std::exit(kExitConfigError);
+ }
+ std::unordered_set<std::string> absent_set{};
+ for (auto const& repo : absent) {
+ if (not repo.is_string()) {
+ Logger::Log(LogLevel::Error,
+ "Repositories names have to be strings, but "
+ "found entry {} in {}",
+ repo.dump(),
+ absent_file_opt->string());
+ std::exit(kExitConfigError);
+ }
+ absent_set.insert(repo);
+ }
+ auto new_repos = nlohmann::json::object();
+ auto repos = config.value("repositories", nlohmann::json::object());
+ for (auto const& [key, val] : repos.items()) {
+ new_repos[key] = val;
+ auto ws = val.value("repository", nlohmann::json::object());
+ auto pragma = ws.value("pragma", nlohmann::json::object());
+ pragma["absent"] = absent_set.contains(key);
+ ws["pragma"] = pragma;
+ new_repos[key]["repository"] = ws;
+ }
+ config["repositories"] = new_repos;
+ } catch (std::exception const& e) {
+ Logger::Log(LogLevel::Error,
+ "Parsing absent-repos file {} failed with error:\n{}",
+ absent_file_opt->string(),
+ e.what());
+ std::exit(kExitConfigError);
+ }
+ }
+
+ try {
+ return std::make_shared<Configuration>(Expression::FromJson(config));
+ } catch (...) {
+ return nullptr;
+ }
}
auto SetupRemoteApi(std::optional<std::string> const& remote_exec_addr,
diff --git a/src/other_tools/just_mr/setup_utils.hpp b/src/other_tools/just_mr/setup_utils.hpp
index 3294a7e5..9530cc95 100644
--- a/src/other_tools/just_mr/setup_utils.hpp
+++ b/src/other_tools/just_mr/setup_utils.hpp
@@ -55,7 +55,8 @@ void DefaultReachableRepositories(
/// \brief Read in a just-mr configuration file.
[[nodiscard]] auto ReadConfiguration(
- std::optional<std::filesystem::path> const& config_file_opt) noexcept
+ std::optional<std::filesystem::path> const& config_file_opt,
+ std::optional<std::filesystem::path> const& absent_file_opt) noexcept
-> std::shared_ptr<Configuration>;
/// \brief Setup of a remote API based on just-mr arguments.