summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
5 files changed, 93 insertions, 9 deletions
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.