summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/main/main.cpp50
-rw-r--r--src/buildtool/storage/TARGETS1
-rw-r--r--src/buildtool/storage/config.hpp107
-rw-r--r--src/buildtool/storage/fs_utils.cpp8
-rw-r--r--src/buildtool/storage/garbage_collector.cpp4
-rw-r--r--src/buildtool/storage/uplinker.cpp4
-rw-r--r--src/other_tools/just_mr/main.cpp32
7 files changed, 127 insertions, 79 deletions
diff --git a/src/buildtool/main/main.cpp b/src/buildtool/main/main.cpp
index d0c36d93..e1f10904 100644
--- a/src/buildtool/main/main.cpp
+++ b/src/buildtool/main/main.cpp
@@ -102,17 +102,29 @@ void SetupLogging(LogArguments const& clargs) {
}
}
+[[nodiscard]] auto CreateStorageConfig(EndpointArguments const& eargs) noexcept
+ -> std::optional<StorageConfig> {
+ StorageConfig::Builder builder;
+ if (eargs.local_root.has_value()) {
+ builder.SetBuildRoot(*eargs.local_root);
+ }
+
+ auto config = builder.Build();
+ if (config) {
+ return *std::move(config);
+ }
+ Logger::Log(LogLevel::Error, config.error());
+ return std::nullopt;
+}
+
#ifndef BOOTSTRAP_BUILD_TOOL
void SetupExecutionConfig(EndpointArguments const& eargs,
BuildArguments const& bargs,
RebuildArguments const& rargs) {
- using StorageConfig = StorageConfig;
using LocalConfig = LocalExecutionConfig;
using RemoteConfig = RemoteExecutionConfig;
- if (not(not eargs.local_root or
- (StorageConfig::Instance().SetBuildRoot(*eargs.local_root))) or
- not(not bargs.local_launcher or
- LocalConfig::SetLauncher(*bargs.local_launcher))) {
+ if (bargs.local_launcher and
+ not LocalConfig::SetLauncher(*bargs.local_launcher)) {
Logger::Log(LogLevel::Error, "Failed to configure local execution.");
std::exit(kExitFailure);
}
@@ -783,12 +795,17 @@ auto main(int argc, char* argv[]) -> int {
if (not auth_config) {
return kExitFailure;
}
+#endif
+ auto const storage_config = CreateStorageConfig(arguments.endpoint);
+ if (not storage_config) {
+ return kExitFailure;
+ }
+ auto const storage = Storage::Create(&*storage_config);
- auto const storage = Storage::Create(&StorageConfig::Instance());
-
+#ifndef BOOTSTRAP_BUILD_TOOL
if (arguments.cmd == SubCommand::kGc) {
if (GarbageCollector::TriggerGarbageCollection(
- StorageConfig::Instance(), arguments.gc.no_rotate)) {
+ *storage_config, arguments.gc.no_rotate)) {
return kExitSuccess;
}
return kExitFailure;
@@ -796,13 +813,13 @@ auto main(int argc, char* argv[]) -> int {
if (arguments.cmd == SubCommand::kExecute) {
SetupExecutionServiceConfig(arguments.service);
- ApiBundle const exec_apis{&StorageConfig::Instance(),
+ ApiBundle const exec_apis{&*storage_config,
&storage,
/*repo_config=*/nullptr,
&*auth_config,
RemoteExecutionConfig::RemoteAddress()};
if (not ServerImpl::Instance().Run(
- StorageConfig::Instance(), storage, exec_apis)) {
+ *storage_config, storage, exec_apis)) {
return kExitFailure;
}
return kExitSuccess;
@@ -816,7 +833,7 @@ auto main(int argc, char* argv[]) -> int {
arguments.service.pid_file);
if (serve_server) {
ApiBundle const serve_apis{
- &StorageConfig::Instance(),
+ &*storage_config,
&storage,
/*repo_config=*/nullptr,
&*auth_config,
@@ -825,7 +842,7 @@ auto main(int argc, char* argv[]) -> int {
ServeApi::Create(*serve_config, &storage, &serve_apis);
bool with_execute = not RemoteExecutionConfig::RemoteAddress();
return serve_server->Run(*serve_config,
- StorageConfig::Instance(),
+ *storage_config,
storage,
serve,
serve_apis,
@@ -876,7 +893,7 @@ auto main(int argc, char* argv[]) -> int {
if (not SetupRetryConfig(arguments.retry)) {
std::exit(kExitFailure);
}
- ApiBundle const main_apis{&StorageConfig::Instance(),
+ ApiBundle const main_apis{&*storage_config,
&storage,
&repo_config,
&*auth_config,
@@ -895,11 +912,10 @@ auto main(int argc, char* argv[]) -> int {
ProgressReporter::Reporter(&stats, &progress)};
if (arguments.cmd == SubCommand::kInstallCas) {
- if (not repo_config.SetGitCAS(
- StorageConfig::Instance().GitRoot())) {
+ if (not repo_config.SetGitCAS(storage_config->GitRoot())) {
Logger::Log(LogLevel::Debug,
"Failed set Git CAS {}.",
- StorageConfig::Instance().GitRoot().string());
+ storage_config->GitRoot().string());
}
return FetchAndInstallArtifacts(main_apis, arguments.fetch)
? kExitSuccess
@@ -923,7 +939,7 @@ auto main(int argc, char* argv[]) -> int {
#endif // BOOTSTRAP_BUILD_TOOL
#ifndef BOOTSTRAP_BUILD_TOOL
- auto lock = GarbageCollector::SharedLock(StorageConfig::Instance());
+ auto lock = GarbageCollector::SharedLock(*storage_config);
if (not lock) {
return kExitFailure;
}
diff --git a/src/buildtool/storage/TARGETS b/src/buildtool/storage/TARGETS
index 00a5f2d2..2d624afb 100644
--- a/src/buildtool/storage/TARGETS
+++ b/src/buildtool/storage/TARGETS
@@ -11,6 +11,7 @@
, ["src/buildtool/logging", "log_level"]
, ["src/utils/cpp", "gsl"]
, ["src/utils/cpp", "tmp_dir"]
+ , ["src/utils/cpp", "expected"]
]
, "stage": ["src", "buildtool", "storage"]
}
diff --git a/src/buildtool/storage/config.hpp b/src/buildtool/storage/config.hpp
index 417d3e88..7c4be29d 100644
--- a/src/buildtool/storage/config.hpp
+++ b/src/buildtool/storage/config.hpp
@@ -24,6 +24,7 @@
#include "src/buildtool/file_system/file_system_manager.hpp"
#include "src/buildtool/logging/log_level.hpp"
#include "src/buildtool/logging/logger.hpp"
+#include "src/utils/cpp/expected.hpp"
#include "src/utils/cpp/gsl.hpp"
#include "src/utils/cpp/tmp_dir.hpp"
@@ -40,59 +41,35 @@ struct GenerationConfig final {
std::filesystem::path const target_cache;
};
-/// \brief Global storage configuration.
-class StorageConfig {
- public:
+struct StorageConfig final {
+ class Builder;
+
static inline auto const kDefaultBuildRoot =
FileSystemManager::GetUserHome() / ".cache" / "just";
- [[nodiscard]] static auto Instance() noexcept -> StorageConfig& {
- static StorageConfig config;
- return config;
- }
-
- [[nodiscard]] auto SetBuildRoot(std::filesystem::path const& dir) noexcept
- -> bool {
- if (FileSystemManager::IsRelativePath(dir)) {
- Logger::Log(LogLevel::Error,
- "Build root must be absolute path but got '{}'.",
- dir.string());
- return false;
- }
- build_root_ = dir;
- return true;
- }
-
- /// \brief Specifies the number of storage generations.
- auto SetNumGenerations(std::size_t num_generations) noexcept -> void {
- num_generations_ = num_generations;
- }
-
- /// \brief Number of storage generations.
- [[nodiscard]] auto NumGenerations() const noexcept -> std::size_t {
- return num_generations_;
- }
+ // Build root directory. All the storage dirs are subdirs of build_root.
+ // By default, build_root is set to $HOME/.cache/just.
+ // If the user uses --local-build-root PATH,
+ // then build_root will be set to PATH.
+ std::filesystem::path const build_root = kDefaultBuildRoot;
- /// \brief Build directory, defaults to user directory if not set
- [[nodiscard]] auto BuildRoot() const noexcept
- -> std::filesystem::path const& {
- return build_root_;
- }
+ // Number of total storage generations (default: two generations).
+ std::size_t const num_generations = 2;
/// \brief Root directory of all storage generations.
[[nodiscard]] auto CacheRoot() const noexcept -> std::filesystem::path {
- return BuildRoot() / "protocol-dependent";
+ return build_root / "protocol-dependent";
}
/// \brief Directory for the git repository storing various roots
[[nodiscard]] auto GitRoot() const noexcept -> std::filesystem::path {
- return BuildRoot() / "git";
+ return build_root / "git";
}
/// \brief Root directory of specific storage generation
[[nodiscard]] auto GenerationCacheRoot(std::size_t index) const noexcept
-> std::filesystem::path {
- ExpectsAudit(index < num_generations_);
+ ExpectsAudit(index < num_generations);
auto generation = std::string{"generation-"} + std::to_string(index);
return CacheRoot() / generation;
}
@@ -138,21 +115,59 @@ class StorageConfig {
};
private:
- // Build root directory. All the storage dirs are subdirs of build_root.
- // By default, build_root is set to $HOME/.cache/just.
- // If the user uses --local-build-root PATH,
- // then build_root will be set to PATH.
- std::filesystem::path build_root_{kDefaultBuildRoot};
-
- // Number of total storage generations (default: two generations).
- std::size_t num_generations_{2};
-
// different folder for different caching protocol
[[nodiscard]] static auto UpdatePathForCompatibility(
std::filesystem::path const& dir,
bool is_compatible) -> std::filesystem::path {
return dir / (is_compatible ? "compatible-sha256" : "git-sha1");
+ };
+};
+
+class StorageConfig::Builder final {
+ public:
+ auto SetBuildRoot(std::filesystem::path value) noexcept -> Builder& {
+ build_root_ = std::move(value);
+ return *this;
}
+
+ /// \brief Specifies the number of storage generations.
+ auto SetNumGenerations(std::size_t value) noexcept -> Builder& {
+ num_generations_ = value;
+ return *this;
+ }
+
+ [[nodiscard]] auto Build() const noexcept
+ -> expected<StorageConfig, std::string> {
+ // To not duplicate default arguments of StorageConfig in builder,
+ // create a default config and copy default arguments from there.
+ StorageConfig const default_config;
+
+ auto build_root = default_config.build_root;
+ if (build_root_.has_value()) {
+ build_root = *build_root_;
+ if (FileSystemManager::IsRelativePath(build_root)) {
+ return unexpected(fmt::format(
+ "Build root must be absolute path but got '{}'.",
+ build_root.string()));
+ }
+ }
+
+ auto num_generations = default_config.num_generations;
+ if (num_generations_.has_value()) {
+ num_generations = *num_generations_;
+ if (num_generations == 0) {
+ return unexpected(std::string{
+ "The number of generations must be greater than 0."});
+ }
+ }
+
+ return StorageConfig{.build_root = std::move(build_root),
+ .num_generations = num_generations};
+ }
+
+ private:
+ std::optional<std::filesystem::path> build_root_;
+ std::optional<std::size_t> num_generations_;
};
#endif // INCLUDED_SRC_BUILDTOOL_STORAGE_CONFIG_HPP
diff --git a/src/buildtool/storage/fs_utils.cpp b/src/buildtool/storage/fs_utils.cpp
index e50e892e..3286c4ec 100644
--- a/src/buildtool/storage/fs_utils.cpp
+++ b/src/buildtool/storage/fs_utils.cpp
@@ -54,14 +54,14 @@ auto GetGitRoot(StorageConfig const& storage_config,
auto GetCommitTreeIDFile(StorageConfig const& storage_config,
std::string const& commit) noexcept
-> std::filesystem::path {
- return storage_config.BuildRoot() / "commit-tree-map" / commit;
+ return storage_config.build_root / "commit-tree-map" / commit;
}
auto GetArchiveTreeIDFile(StorageConfig const& storage_config,
std::string const& repo_type,
std::string const& content) noexcept
-> std::filesystem::path {
- return storage_config.BuildRoot() / "tree-map" / repo_type / content;
+ return storage_config.build_root / "tree-map" / repo_type / content;
}
auto GetForeignFileTreeIDFile(StorageConfig const& storage_config,
@@ -82,14 +82,14 @@ auto GetForeignFileTreeIDFile(StorageConfig const& storage_config,
auto GetDistdirTreeIDFile(StorageConfig const& storage_config,
std::string const& content) noexcept
-> std::filesystem::path {
- return storage_config.BuildRoot() / "distfiles-tree-map" / content;
+ return storage_config.build_root / "distfiles-tree-map" / content;
}
auto GetResolvedTreeIDFile(StorageConfig const& storage_config,
std::string const& tree_hash,
PragmaSpecial const& pragma_special) noexcept
-> std::filesystem::path {
- return storage_config.BuildRoot() / "special-tree-map" /
+ return storage_config.build_root / "special-tree-map" /
kPragmaSpecialInverseMap.at(pragma_special) / tree_hash;
}
diff --git a/src/buildtool/storage/garbage_collector.cpp b/src/buildtool/storage/garbage_collector.cpp
index 3b3e5d28..25a78ddb 100644
--- a/src/buildtool/storage/garbage_collector.cpp
+++ b/src/buildtool/storage/garbage_collector.cpp
@@ -175,11 +175,11 @@ auto GarbageCollector::TriggerGarbageCollection(
storage_config.CacheRoot() /
fmt::format("{}{}", remove_me_prefix, remove_me_counter++);
to_remove.emplace_back(remove_me_dir);
- for (std::size_t i = storage_config.NumGenerations(); i > 0; --i) {
+ for (std::size_t i = storage_config.num_generations; i > 0; --i) {
auto cache_root = storage_config.GenerationCacheRoot(i - 1);
if (FileSystemManager::IsDirectory(cache_root)) {
auto new_cache_root =
- (i == storage_config.NumGenerations())
+ (i == storage_config.num_generations)
? remove_me_dir
: storage_config.GenerationCacheRoot(i);
if (not FileSystemManager::Rename(cache_root,
diff --git a/src/buildtool/storage/uplinker.cpp b/src/buildtool/storage/uplinker.cpp
index de6cfb99..fee01af4 100644
--- a/src/buildtool/storage/uplinker.cpp
+++ b/src/buildtool/storage/uplinker.cpp
@@ -32,8 +32,8 @@ namespace {
gsl::not_null<StorageConfig const*> const& storage_config) noexcept
-> std::vector<Generation> {
std::vector<Generation> generations;
- generations.reserve(storage_config->NumGenerations());
- for (std::size_t i = 0; i < storage_config->NumGenerations(); ++i) {
+ generations.reserve(storage_config->num_generations);
+ for (std::size_t i = 0; i < storage_config->num_generations; ++i) {
generations.emplace_back(Generation::Create(storage_config,
/*generation=*/i));
}
diff --git a/src/other_tools/just_mr/main.cpp b/src/other_tools/just_mr/main.cpp
index 98e1de2c..92f07944 100644
--- a/src/other_tools/just_mr/main.cpp
+++ b/src/other_tools/just_mr/main.cpp
@@ -198,6 +198,22 @@ void SetupLogging(MultiRepoLogArguments const& clargs) {
}
}
+[[nodiscard]] auto CreateStorageConfig(
+ MultiRepoCommonArguments const& args) noexcept
+ -> std::optional<StorageConfig> {
+ StorageConfig::Builder builder;
+ if (args.just_mr_paths->root.has_value()) {
+ builder.SetBuildRoot(*args.just_mr_paths->root);
+ }
+
+ auto config = builder.Build();
+ if (config) {
+ return *std::move(config);
+ }
+ Logger::Log(LogLevel::Error, config.error());
+ return std::nullopt;
+}
+
} // namespace
auto main(int argc, char* argv[]) -> int {
@@ -289,14 +305,14 @@ auto main(int argc, char* argv[]) -> int {
// Setup LocalStorageConfig to store the local_build_root properly
// and make the cas and git cache roots available
- if (not StorageConfig::Instance().SetBuildRoot(
- *arguments.common.just_mr_paths->root)) {
+ auto storage_config = CreateStorageConfig(arguments.common);
+ if (not storage_config) {
Logger::Log(LogLevel::Error,
"Failed to configure local build root.");
return kExitGenericFailure;
}
- auto const storage = Storage::Create(&StorageConfig::Instance());
+ auto const storage = Storage::Create(&*storage_config);
// check for conflicts in main repo name
if ((not arguments.setup.sub_all) and arguments.common.main and
@@ -347,12 +363,12 @@ auto main(int argc, char* argv[]) -> int {
arguments.auth,
arguments.retry,
arguments.launch_fwd,
- StorageConfig::Instance(),
+ *storage_config,
storage,
forward_build_root,
my_name);
}
- auto lock = GarbageCollector::SharedLock(StorageConfig::Instance());
+ auto lock = GarbageCollector::SharedLock(*storage_config);
if (not lock) {
return kExitGenericFailure;
}
@@ -377,7 +393,7 @@ auto main(int argc, char* argv[]) -> int {
arguments.setup,
arguments.just_cmd,
arguments.auth,
- StorageConfig::Instance(),
+ *storage_config,
storage,
/*interactive=*/(arguments.cmd == SubCommand::kSetupEnv),
my_name);
@@ -397,7 +413,7 @@ auto main(int argc, char* argv[]) -> int {
return MultiRepoUpdate(config,
arguments.common,
arguments.update,
- StorageConfig::Instance(),
+ *storage_config,
my_name);
}
@@ -425,7 +441,7 @@ auto main(int argc, char* argv[]) -> int {
arguments.setup,
arguments.fetch,
arguments.auth,
- StorageConfig::Instance(),
+ *storage_config,
storage,
my_name);
}