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
|
#include "src/buildtool/build_engine/target_map/export.hpp"
#include <unordered_set>
#include "src/buildtool/build_engine/base_maps/field_reader.hpp"
#include "src/buildtool/build_engine/expression/configuration.hpp"
namespace {
auto expectedFields = std::unordered_set<std::string>{"config_doc",
"doc",
"fixed_config",
"flexible_config",
"target",
"type"};
void FinalizeExport(
const std::vector<AnalysedTargetPtr const*>& exported,
const BuildMaps::Base::EntityName& target,
const std::vector<std::string>& vars,
const Configuration& effective_config,
const BuildMaps::Target::TargetMap::LoggerPtr& logger,
const BuildMaps::Target::TargetMap::SetterPtr& setter,
const gsl::not_null<BuildMaps::Target::ResultTargetMap*>& result_map) {
const auto* value = exported[0];
if (not(*value)->Tainted().empty()) {
(*logger)("Only untainted targets can be exported.", true);
return;
}
auto provides = (*value)->Provides();
if (not provides->IsCacheable()) {
(*logger)(fmt::format("Only cacheable values can be exported; but "
"target provides {}",
provides->ToString()),
true);
return;
}
std::unordered_set<std::string> vars_set{};
vars_set.insert(vars.begin(), vars.end());
// TODO(aehlig): wrap all artifacts into "save to target-cache" special
// action
auto analysis_result = std::make_shared<AnalysedTarget>(
TargetResult{(*value)->Artifacts(), provides, (*value)->RunFiles()},
std::vector<ActionDescription>{},
std::vector<std::string>{},
std::vector<Tree>{},
std::move(vars_set),
std::set<std::string>{});
analysis_result =
result_map->Add(target, effective_config, std::move(analysis_result));
(*setter)(std::move(analysis_result));
}
} // namespace
void ExportRule(
const nlohmann::json& desc_json,
const BuildMaps::Target::ConfiguredTarget& key,
const BuildMaps::Target::TargetMap::SubCallerPtr& subcaller,
const BuildMaps::Target::TargetMap::SetterPtr& setter,
const BuildMaps::Target::TargetMap::LoggerPtr& logger,
const gsl::not_null<BuildMaps::Target::ResultTargetMap*> result_map) {
auto desc = BuildMaps::Base::FieldReader::CreatePtr(
desc_json, key.target, "export target", logger);
desc->ExpectFields(expectedFields);
auto exported_target_name = desc->ReadExpression("target");
if (not exported_target_name) {
return;
}
auto exported_target = BuildMaps::Base::ParseEntityNameFromExpression(
exported_target_name,
key.target,
[&logger, &exported_target_name](std::string const& parse_err) {
(*logger)(fmt::format("Parsing target name {} failed with:\n{}",
exported_target_name->ToString(),
parse_err),
true);
});
if (not exported_target) {
return;
}
auto flexible_vars = desc->ReadStringList("flexible_config");
if (not flexible_vars) {
return;
}
auto effective_config = key.config.Prune(*flexible_vars);
// TODO(aehlig): if the respository is content-fixed, look up in target
// cache with key consistig of repository-description, target, and effective
// config.
auto fixed_config =
desc->ReadOptionalExpression("fixed_config", Expression::kEmptyMap);
if (not fixed_config->IsMap()) {
(*logger)(fmt::format("fixed_config has to be a map, but found {}",
fixed_config->ToString()),
true);
return;
}
for (auto const& var : fixed_config->Map().Keys()) {
if (effective_config.VariableFixed(var)) {
(*logger)(
fmt::format("Variable {} is both fixed and flexible.", var),
true);
return;
}
}
auto target_config = effective_config.Update(fixed_config);
(*subcaller)(
{BuildMaps::Target::ConfiguredTarget{std::move(*exported_target),
std::move(target_config)}},
[setter,
logger,
vars = std::move(*flexible_vars),
result_map,
effective_config = std::move(effective_config),
target = key.target](auto const& values) {
FinalizeExport(values,
target,
vars,
effective_config,
logger,
setter,
result_map);
},
logger);
}
|