1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
// Copyright 2025 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/computed_roots/inquire_serve.hpp"
#include <filesystem>
#include <memory>
#include <utility>
#include <variant>
#include <vector>
#include "nlohmann/json.hpp"
#include "src/buildtool/build_engine/base_maps/entity_name_data.hpp"
#include "src/buildtool/build_engine/base_maps/module_name.hpp"
#include "src/buildtool/build_engine/expression/configuration.hpp"
#include "src/buildtool/build_engine/expression/expression.hpp"
#include "src/buildtool/build_engine/expression/expression_ptr.hpp"
#include "src/buildtool/build_engine/expression/target_result.hpp"
#include "src/buildtool/common/artifact_digest.hpp"
#include "src/buildtool/common/repository_config.hpp"
#include "src/buildtool/computed_roots/artifacts_root.hpp"
#include "src/buildtool/execution_api/utils/rehash_utils.hpp"
#include "src/buildtool/file_system/file_root.hpp"
#include "src/buildtool/logging/log_level.hpp"
#include "src/buildtool/multithreading/async_map_consumer.hpp"
#include "src/buildtool/serve_api/remote/serve_api.hpp"
#include "src/buildtool/storage/storage.hpp"
#include "src/buildtool/storage/target_cache_entry.hpp"
#include "src/buildtool/storage/target_cache_key.hpp"
[[nodiscard]] auto InquireServe(
gsl::not_null<AnalyseContext*> const& analyse_context,
BuildMaps::Target::ConfiguredTarget const& id,
gsl::not_null<Logger const*> const& logger) -> std::optional<std::string> {
auto const& repo_name = id.target.ToModule().repository;
if (not analyse_context->repo_config->TargetRoot(repo_name)->IsAbsent()) {
logger->Emit(LogLevel::Info,
"Base root is concrete, will manage build locally.");
return std::nullopt;
}
if (analyse_context->serve == nullptr) {
logger->Emit(LogLevel::Warning,
"Cannot treat a root absent without serve");
return std::nullopt;
}
auto target = id.target.GetNamedTarget();
auto target_root_id =
analyse_context->repo_config->TargetRoot(repo_name)->GetAbsentTreeId();
if (not target_root_id) {
logger->Emit(LogLevel::Warning,
"Failed to get the target root id for repository {}",
nlohmann::json(repo_name).dump());
return std::nullopt;
}
std::filesystem::path module{id.target.ToModule().module};
auto vars = analyse_context->serve->ServeTargetVariables(
*target_root_id,
(module / *(analyse_context->repo_config->TargetFileName(repo_name)))
.string(),
target.name);
if (not vars) {
logger->Emit(LogLevel::Warning,
"Failed to obtain variables for {}",
id.target.ToString());
return std::nullopt;
}
auto effective_config = id.config.Prune(*vars);
logger->Emit(LogLevel::Info,
"Effective configuration {}",
effective_config.ToString());
auto repo_key = analyse_context->repo_config->RepositoryKey(
*analyse_context->storage, target.repository);
if (not repo_key) {
logger->Emit(LogLevel::Warning, "Cannot obtain repository key");
return std::nullopt;
}
auto target_cache_key = analyse_context->storage->TargetCache().ComputeKey(
*repo_key, target, effective_config);
if (not target_cache_key) {
logger->Emit(LogLevel::Warning, "Failed to obtain target-cache key");
return std::nullopt;
}
logger->Emit(LogLevel::Info,
"Target cache key {}",
target_cache_key->Id().ToString());
auto res = analyse_context->serve->ServeTarget(
*target_cache_key, *repo_key, /*keep_artifacts_root=*/true);
if (not res) {
logger->Emit(LogLevel::Warning, "Could not obtain target from serve");
return std::nullopt;
}
if (res->index() != 3) {
logger->Emit(LogLevel::Warning, "Failed to obtain root from serve");
return std::nullopt;
}
auto target_cache_value = std::get<3>(*res);
auto const& [entry, info] = target_cache_value;
auto result = entry.ToResult();
if (not result) {
logger->Emit(LogLevel::Warning, "Reading entry cache entry failed.");
return std::nullopt;
}
auto wrapped_logger = std::make_shared<AsyncMapConsumerLogger>(
[&logger](auto const& msg, bool fatal) {
logger->Emit(fatal ? LogLevel::Warning : LogLevel::Info,
"While computing root from stage:{}",
msg);
});
auto git_tree = ArtifactsRoot(
result->artifact_stage, wrapped_logger, /*rehash=*/std::nullopt);
if (not git_tree) {
logger->Emit(
LogLevel::Warning,
"Failed to compute git tree from obtained artifact stage {}",
result->artifact_stage->ToString());
return std::nullopt;
}
logger->Emit(LogLevel::Info, "Tree identifier for root is {}.", *git_tree);
return git_tree;
}
|