diff options
author | Klaus Aehlig <klaus.aehlig@huawei.com> | 2023-08-10 11:56:15 +0200 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2023-08-11 14:32:05 +0200 |
commit | 24124411aecdeebb4182ad857756265df0764363 (patch) | |
tree | 957f7928dfaf0b82910672ff344c4f401af6f832 /src | |
parent | dd576b8730b1aa9ea90fba20367471b4a09da5d3 (diff) | |
download | justbuild-24124411aecdeebb4182ad857756265df0764363.tar.gz |
Move downstepping to subobjects to a library
... in order to make that functionality reusable
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/execution_api/utils/TARGETS | 18 | ||||
-rw-r--r-- | src/buildtool/execution_api/utils/subobject.cpp | 120 | ||||
-rw-r--r-- | src/buildtool/execution_api/utils/subobject.hpp | 34 | ||||
-rw-r--r-- | src/buildtool/main/TARGETS | 2 | ||||
-rw-r--r-- | src/buildtool/main/install_cas.cpp | 99 |
5 files changed, 181 insertions, 92 deletions
diff --git a/src/buildtool/execution_api/utils/TARGETS b/src/buildtool/execution_api/utils/TARGETS new file mode 100644 index 00000000..20b65c18 --- /dev/null +++ b/src/buildtool/execution_api/utils/TARGETS @@ -0,0 +1,18 @@ +{ "subobject": + { "type": ["@", "rules", "CC", "library"] + , "name": ["subobject"] + , "hdrs": ["subobject.hpp"] + , "srcs": ["subobject.cpp"] + , "deps": + [ ["src/buildtool/common", "common"] + , ["src/buildtool/execution_api/common", "common"] + , ["@", "gsl", "", "gsl"] + ] + , "private-deps": + [ ["src/buildtool/compatibility", "compatibility"] + , ["src/buildtool/execution_api/bazel_msg", "bazel_msg_factory"] + , ["src/buildtool/logging", "logging"] + ] + , "stage": ["src", "buildtool", "execution_api", "utils"] + } +} diff --git a/src/buildtool/execution_api/utils/subobject.cpp b/src/buildtool/execution_api/utils/subobject.cpp new file mode 100644 index 00000000..46ec58a7 --- /dev/null +++ b/src/buildtool/execution_api/utils/subobject.cpp @@ -0,0 +1,120 @@ +// Copyright 2023 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/execution_api/utils/subobject.hpp" +#ifndef BOOTSTRAP_BUILD_TOOL + +#include "src/buildtool/compatibility/compatibility.hpp" +#include "src/buildtool/execution_api/bazel_msg/bazel_msg_factory.hpp" +#include "src/buildtool/logging/log_level.hpp" +#include "src/buildtool/logging/logger.hpp" + +auto RetrieveSubPathId(Artifact::ObjectInfo object_info, + gsl::not_null<IExecutionApi*> const& api, + const std::filesystem::path& sub_path) + -> std::optional<Artifact::ObjectInfo> { + + std::filesystem::path sofar{}; + for (auto const& segment : sub_path) { + if (object_info.type != ObjectType::Tree) { + Logger::Log(LogLevel::Warning, + "Non-tree found at path '{}', cannot follow to '{}'", + sofar.string(), + segment.string()); + break; + } + auto data = api->RetrieveToMemory(object_info); + if (not data) { + Logger::Log(LogLevel::Error, + "Failed to retrieve artifact {} at path '{}'", + object_info.ToString(), + sofar.string()); + return std::nullopt; + } + if (Compatibility::IsCompatible()) { + auto directory = + BazelMsgFactory::MessageFromString<bazel_re::Directory>(*data); + if (not directory) { + Logger::Log(LogLevel::Warning, + "Failed to parse directory message at path '{}'", + sofar.string()); + break; + } + std::optional<Artifact::ObjectInfo> new_object_info{}; + if (not BazelMsgFactory::ReadObjectInfosFromDirectory( + *directory, + [&new_object_info, &segment](auto path, auto info) { + if (path == segment) { + new_object_info = info; + } + return true; + })) { + Logger::Log(LogLevel::Warning, + "Failed to process directory message at path '{}'", + sofar.string()); + break; + } + if (not new_object_info) { + Logger::Log(LogLevel::Warning, + "Entry {} not found at path '{}'", + segment.string(), + sofar.string()); + break; + } + object_info = *new_object_info; + } + else { + auto entries = GitRepo::ReadTreeData( + *data, + HashFunction::ComputeTreeHash(*data).Bytes(), + [](auto const& /*unused*/) { return true; }, + /*is_hex_id=*/false); + if (not entries) { + Logger::Log(LogLevel::Warning, + "Failed to parse tree {} at path '{}'", + object_info.ToString(), + sofar.string()); + break; + } + std::optional<Artifact::ObjectInfo> new_object_info{}; + if (not BazelMsgFactory::ReadObjectInfosFromGitTree( + *entries, + [&new_object_info, &segment](auto path, auto info) { + if (path == segment) { + new_object_info = info; + } + return true; + })) { + Logger::Log(LogLevel::Warning, + "Failed to process tree entries at path '{}'", + sofar.string()); + break; + } + + if (not new_object_info) { + Logger::Log(LogLevel::Warning, + "Entry {} not found at path '{}'", + segment.string(), + sofar.string()); + break; + } + object_info = *new_object_info; + } + sofar /= segment; + } + + return object_info; +} + +#endif diff --git a/src/buildtool/execution_api/utils/subobject.hpp b/src/buildtool/execution_api/utils/subobject.hpp new file mode 100644 index 00000000..85fc7bdb --- /dev/null +++ b/src/buildtool/execution_api/utils/subobject.hpp @@ -0,0 +1,34 @@ +// Copyright 2023 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. + +#ifndef INCLUDED_SRC_BUILDTOOL_EXECUTION_API_UTILS_SUBOBJECT_HPP +#define INCLUDED_SRC_BUILDTOOL_EXECUTION_API_UTILS_SUBOBJECT_HPP + +#ifndef BOOTSTRAP_BUILD_TOOL + +#include <filesystem> +#include <optional> + +#include "gsl/gsl" +#include "src/buildtool/common/artifact.hpp" +#include "src/buildtool/execution_api/common/execution_api.hpp" + +auto RetrieveSubPathId(Artifact::ObjectInfo object_info, + gsl::not_null<IExecutionApi*> const& api, + const std::filesystem::path& sub_path) + -> std::optional<Artifact::ObjectInfo>; + +#endif + +#endif diff --git a/src/buildtool/main/TARGETS b/src/buildtool/main/TARGETS index 8ff214d0..b74a5fe4 100644 --- a/src/buildtool/main/TARGETS +++ b/src/buildtool/main/TARGETS @@ -83,9 +83,9 @@ , "private-deps": [ ["src/buildtool/compatibility", "compatibility"] , ["src/buildtool/crypto", "hash_function"] - , ["src/buildtool/execution_api/bazel_msg", "bazel_msg_factory"] , ["src/buildtool/execution_api/remote", "config"] , ["src/buildtool/logging", "logging"] + , ["src/buildtool/execution_api/utils", "subobject"] ] } , "analyse": diff --git a/src/buildtool/main/install_cas.cpp b/src/buildtool/main/install_cas.cpp index 99867de8..622e7a1f 100644 --- a/src/buildtool/main/install_cas.cpp +++ b/src/buildtool/main/install_cas.cpp @@ -17,7 +17,7 @@ #include "src/buildtool/compatibility/compatibility.hpp" #include "src/buildtool/crypto/hash_function.hpp" #ifndef BOOTSTRAP_BUILD_TOOL -#include "src/buildtool/execution_api/bazel_msg/bazel_msg_factory.hpp" +#include "src/buildtool/execution_api/utils/subobject.hpp" #endif #include "src/buildtool/execution_api/remote/config.hpp" @@ -81,96 +81,13 @@ auto FetchAndInstallArtifacts( if (clargs.sub_path) { std::filesystem::path sofar{}; - for (auto const& segment : *clargs.sub_path) { - if (object_info.type != ObjectType::Tree) { - Logger::Log( - LogLevel::Warning, - "Non-tree found at path '{}', cannot follow to '{}'", - sofar.string(), - segment.string()); - break; - } - auto data = api->RetrieveToMemory(object_info); - if (not data) { - Logger::Log(LogLevel::Error, - "Failed to retrieve artifact {} at path '{}'", - object_info.ToString(), - sofar.string()); - return false; - } - if (Compatibility::IsCompatible()) { - auto directory = - BazelMsgFactory::MessageFromString<bazel_re::Directory>( - *data); - if (not directory) { - Logger::Log( - LogLevel::Warning, - "Failed to parse directory message at path '{}'", - sofar.string()); - break; - } - std::optional<Artifact::ObjectInfo> new_object_info{}; - if (not BazelMsgFactory::ReadObjectInfosFromDirectory( - *directory, - [&new_object_info, &segment](auto path, auto info) { - if (path == segment) { - new_object_info = info; - } - return true; - })) { - Logger::Log( - LogLevel::Warning, - "Failed to process directory message at path '{}'", - sofar.string()); - break; - } - if (not new_object_info) { - Logger::Log(LogLevel::Warning, - "Entry {} not found at path '{}'", - segment.string(), - sofar.string()); - break; - } - object_info = *new_object_info; - } - else { - auto entries = GitRepo::ReadTreeData( - *data, - HashFunction::ComputeTreeHash(*data).Bytes(), - [](auto const& /*unused*/) { return true; }, - /*is_hex_id=*/false); - if (not entries) { - Logger::Log(LogLevel::Warning, - "Failed to parse tree {} at path '{}'", - object_info.ToString(), - sofar.string()); - break; - } - std::optional<Artifact::ObjectInfo> new_object_info{}; - if (not BazelMsgFactory::ReadObjectInfosFromGitTree( - *entries, - [&new_object_info, &segment](auto path, auto info) { - if (path == segment) { - new_object_info = info; - } - return true; - })) { - Logger::Log(LogLevel::Warning, - "Failed to process tree entries at path '{}'", - sofar.string()); - break; - } - - if (not new_object_info) { - Logger::Log(LogLevel::Warning, - "Entry {} not found at path '{}'", - segment.string(), - sofar.string()); - break; - } - object_info = *new_object_info; - } - sofar /= segment; + auto new_object_info = + RetrieveSubPathId(object_info, api, *clargs.sub_path); + if (new_object_info) { + object_info = *new_object_info; + } + else { + return false; } } |