diff options
Diffstat (limited to 'src/buildtool/main/add_to_cas.cpp')
-rw-r--r-- | src/buildtool/main/add_to_cas.cpp | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/src/buildtool/main/add_to_cas.cpp b/src/buildtool/main/add_to_cas.cpp new file mode 100644 index 00000000..0d13f881 --- /dev/null +++ b/src/buildtool/main/add_to_cas.cpp @@ -0,0 +1,113 @@ +// Copyright 2024 Huawei Cloud Computing Technology Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/buildtool/main/add_to_cas.hpp" + +#ifndef BOOTSTRAP_BUILD_TOOL + +#include <iostream> + +#include "src/buildtool/compatibility/native_support.hpp" +#include "src/buildtool/execution_api/bazel_msg/bazel_msg_factory.hpp" +#include "src/buildtool/execution_api/local/local_api.hpp" +#include "src/buildtool/file_system/file_system_manager.hpp" +#include "src/buildtool/logging/log_level.hpp" +#include "src/buildtool/logging/logger.hpp" +#include "src/buildtool/storage/storage.hpp" + +auto AddArtifactsToCas(ToAddArguments const& clargs, + gsl::not_null<IExecutionApi*> const& remote_api) + -> bool { + + auto const& cas = Storage::Instance().CAS(); + std::optional<bazel_re::Digest> digest{}; + auto object_location = clargs.location; + + if (clargs.follow_symlinks) { + if (not FileSystemManager::ResolveSymlinks(&object_location)) { + Logger::Log(LogLevel::Error, + "Failed resolving {}", + clargs.location.string()); + return false; + } + } + + auto object_type = + FileSystemManager::Type(object_location, /*allow_upwards=*/true); + if (not object_type) { + Logger::Log(LogLevel::Error, + "Non existent or unsupported file-system entry at {}", + object_location.string()); + return false; + } + + switch (*object_type) { + case ObjectType::File: + digest = cas.StoreBlob(object_location, /*is_executable=*/false); + break; + case ObjectType::Executable: + digest = cas.StoreBlob(object_location, /*is_executable=*/true); + break; + case ObjectType::Symlink: { + auto content = FileSystemManager::ReadSymlink(object_location); + if (not content) { + Logger::Log(LogLevel::Error, + "Failed to read symlink at {}", + object_location.string()); + return false; + } + digest = cas.StoreBlob(*content, /*is_executable=*/false); + } break; + case ObjectType::Tree: { + if (Compatibility::IsCompatible()) { + Logger::Log(LogLevel::Error, + "Storing of trees only supported in native mode"); + return false; + } + auto store_blob = [&cas](auto path, auto is_exec) { + return cas.StoreBlob(path, is_exec); + }; + auto store_tree = [&cas](auto bytes, auto /*dir*/) { + return cas.StoreTree(bytes); + }; + auto store_symlink = [&cas](auto content) { + return cas.StoreBlob(content); + }; + digest = BazelMsgFactory::CreateGitTreeDigestFromLocalTree( + clargs.location, store_blob, store_tree, store_symlink); + } break; + } + + if (not digest) { + Logger::Log(LogLevel::Error, + "Failed to store {} in local CAS", + clargs.location.string()); + return false; + } + + std::cout << NativeSupport::Unprefix(digest->hash()) << std::endl; + + auto object = std::vector<Artifact::ObjectInfo>{ + Artifact::ObjectInfo{ArtifactDigest(*digest), *object_type, false}}; + + if (not LocalApi().RetrieveToCas(object, remote_api)) { + Logger::Log(LogLevel::Error, + "Failed to upload artifact to remote endpoint"); + return false; + } + + return true; +} + +#endif |