summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/build_engine/base_maps/entity_name.hpp54
-rw-r--r--src/buildtool/build_engine/base_maps/entity_name_data.hpp6
-rw-r--r--src/buildtool/build_engine/target_map/target_map.cpp117
-rw-r--r--src/buildtool/build_engine/target_map/target_map.hpp12
-rw-r--r--src/buildtool/main/main.cpp8
5 files changed, 166 insertions, 31 deletions
diff --git a/src/buildtool/build_engine/base_maps/entity_name.hpp b/src/buildtool/build_engine/base_maps/entity_name.hpp
index e198b97f..f20ca71e 100644
--- a/src/buildtool/build_engine/base_maps/entity_name.hpp
+++ b/src/buildtool/build_engine/base_maps/entity_name.hpp
@@ -89,31 +89,40 @@ template <typename T>
template <typename T>
// IsList(list) == true and Size(list) >= 3
-// list[0] == kFileLocationMarker
-[[nodiscard]] inline auto ParseEntityNameFile(
+[[nodiscard]] inline auto ParseEntityNameFSReference(
+ std::string const& s0, // list[0]
T const& list,
EntityName const& current,
std::optional<std::function<void(std::string const&)>> logger =
std::nullopt) noexcept -> std::optional<EntityName> {
try {
- if (IsString(list[2])) {
- const auto& name = GetString(list[2]);
- const auto& x = current.GetNamedTarget();
- if (IsNone(list[1])) {
- return EntityName{
- x.repository, x.module, name, ReferenceType::kFile};
- }
- if (IsString(list[1])) {
- const auto& middle = GetString(list[1]);
- if (middle == "." or middle == x.module) {
- return EntityName{
- x.repository, x.module, name, ReferenceType::kFile};
+ const bool is_file = s0 == EntityName::kFileLocationMarker;
+ if (is_file or s0 == EntityName::kTreeLocationMarker) {
+ if (IsString(list[2])) {
+ const auto& name = GetString(list[2]);
+ const auto& x = current.GetNamedTarget();
+ if (IsNone(list[1])) {
+ return EntityName{x.repository,
+ x.module,
+ name,
+ (is_file ? ReferenceType::kFile
+ : ReferenceType::kTree)};
+ }
+ if (IsString(list[1])) {
+ const auto& middle = GetString(list[1]);
+ if (middle == "." or middle == x.module) {
+ return EntityName{x.repository,
+ x.module,
+ name,
+ (is_file ? ReferenceType::kFile
+ : ReferenceType::kTree)};
+ }
+ }
+ if (logger) {
+ (*logger)(
+ fmt::format("Invalid module name {} for file reference",
+ ToString(list[1])));
}
- }
- if (logger) {
- (*logger)(
- fmt::format("Invalid module name {} for file reference",
- ToString(list[1])));
}
}
} catch (...) {
@@ -190,9 +199,6 @@ template <typename T>
// the first entry of the list must be a string
if (IsString(list[0])) {
const auto& s0 = GetString(list[0]);
- if (s0 == EntityName::kFileLocationMarker) {
- return ParseEntityNameFile(list, current, logger);
- }
if (s0 == EntityName::kRelativeLocationMarker) {
return ParseEntityNameRelative(list, current, logger);
}
@@ -205,6 +211,10 @@ template <typename T>
"supported. Identifiers of anonymous targets should be "
"obtained as FIELD value of anonymous fields"));
}
+ else if (s0 == EntityName::kFileLocationMarker or
+ s0 == EntityName::kTreeLocationMarker) {
+ return ParseEntityNameFSReference(s0, list, current, logger);
+ }
}
} catch (...) {
}
diff --git a/src/buildtool/build_engine/base_maps/entity_name_data.hpp b/src/buildtool/build_engine/base_maps/entity_name_data.hpp
index 7aa17db1..e3ecf607 100644
--- a/src/buildtool/build_engine/base_maps/entity_name_data.hpp
+++ b/src/buildtool/build_engine/base_maps/entity_name_data.hpp
@@ -24,7 +24,7 @@ struct AnonymousTarget {
}
};
-enum class ReferenceType : std::int8_t { kTarget, kFile };
+enum class ReferenceType : std::int8_t { kTarget, kFile, kTree };
struct NamedTarget {
std::string repository{};
@@ -64,6 +64,7 @@ class EntityName {
using variant_t = std::variant<NamedTarget, AnonymousTarget>;
static constexpr auto kLocationMarker = "@";
static constexpr auto kFileLocationMarker = "FILE";
+ static constexpr auto kTreeLocationMarker = "TREE";
static constexpr auto kRelativeLocationMarker = "./";
static constexpr auto kAnonymousMarker = "#";
@@ -115,6 +116,9 @@ class EntityName {
if (x.reference_t == ReferenceType::kFile) {
j.push_back(kFileLocationMarker);
}
+ else if (x.reference_t == ReferenceType::kTree) {
+ j.push_back(kTreeLocationMarker);
+ }
j.push_back(x.module);
j.push_back(x.name);
}
diff --git a/src/buildtool/build_engine/target_map/target_map.cpp b/src/buildtool/build_engine/target_map/target_map.cpp
index 2e4663da..ed8573ff 100644
--- a/src/buildtool/build_engine/target_map/target_map.cpp
+++ b/src/buildtool/build_engine/target_map/target_map.cpp
@@ -1274,6 +1274,96 @@ void withTargetNode(
}
}
+void TreeTarget(
+ const BuildMaps::Target::ConfiguredTarget& key,
+ const gsl::not_null<TaskSystem*>& ts,
+ 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,
+ const gsl::not_null<BuildMaps::Base::DirectoryEntriesMap*>&
+ directory_entries) {
+ const auto& target = key.target.GetNamedTarget();
+ const auto dir_name = std::filesystem::path{target.module} / target.name;
+ auto module_ = BuildMaps::Base::ModuleName{target.repository, dir_name};
+
+ directory_entries->ConsumeAfterKeysReady(
+ ts,
+ {module_},
+ [setter, subcaller, target, key, result_map, logger, dir_name](
+ auto values) {
+ // expected values.size() == 1
+ const auto& dir_entries = *values[0];
+ using BuildMaps::Target::ConfiguredTarget;
+
+ std::vector<ConfiguredTarget> v;
+
+ for (const auto& x : dir_entries.FilesIterator()) {
+ v.emplace_back(
+ ConfiguredTarget{BuildMaps::Base::EntityName{
+ target.repository,
+ dir_name,
+ x,
+ BuildMaps::Base::ReferenceType::kFile},
+ Configuration{}});
+ }
+
+ for (const auto& x : dir_entries.DirectoriesIterator()) {
+ v.emplace_back(
+ ConfiguredTarget{BuildMaps::Base::EntityName{
+ target.repository,
+ dir_name,
+ x,
+ BuildMaps::Base::ReferenceType::kTree},
+ Configuration{}});
+ }
+ (*subcaller)(
+ std::move(v),
+ [setter, key, result_map, name = target.name](
+ const auto& values) mutable {
+ std::unordered_map<std::string, ArtifactDescription>
+ artifacts;
+
+ artifacts.reserve(values.size());
+
+ for (const auto& x : values) {
+ auto val = x->get()->RunFiles();
+
+ auto const& [input_path, artifact] =
+ *(val->Map().begin());
+ auto norm_path = std::filesystem::path{input_path}
+ .lexically_normal()
+ .string();
+
+ artifacts.emplace(std::move(norm_path),
+ artifact->Artifact());
+ }
+
+ auto tree = std::make_shared<Tree>(std::move(artifacts));
+ auto tree_id = tree->Id();
+ auto tree_map = ExpressionPtr{Expression::map_t{
+ name, ExpressionPtr{ArtifactDescription{tree_id}}}};
+ auto analysis_result = std::make_shared<AnalysedTarget>(
+ TargetResult{tree_map, {}, tree_map},
+ std::vector<ActionDescription::Ptr>{},
+ std::vector<std::string>{},
+ std::vector<Tree::Ptr>{tree},
+ std::unordered_set<std::string>{},
+ std::set<std::string>{});
+ analysis_result = result_map->Add(
+ key.target, {}, std::move(analysis_result));
+ (*setter)(std::move(analysis_result));
+ },
+ logger);
+ },
+ [logger, target = key.target](auto const& msg, bool fatal) {
+ (*logger)(fmt::format("While analysing entries of {}: {}",
+ target.ToString(),
+ msg),
+ fatal);
+ });
+}
+
} // namespace
namespace BuildMaps::Target {
@@ -1281,16 +1371,41 @@ auto CreateTargetMap(
const gsl::not_null<BuildMaps::Base::SourceTargetMap*>& source_target_map,
const gsl::not_null<BuildMaps::Base::TargetsFileMap*>& targets_file_map,
const gsl::not_null<BuildMaps::Base::UserRuleMap*>& rule_map,
+ const gsl::not_null<BuildMaps::Base::DirectoryEntriesMap*>&
+ directory_entries_map,
const gsl::not_null<ResultTargetMap*>& result_map,
std::size_t jobs) -> TargetMap {
auto target_reader =
- [source_target_map, targets_file_map, rule_map, result_map](
+ [source_target_map,
+ targets_file_map,
+ rule_map,
+ result_map,
+ directory_entries_map](
auto ts, auto setter, auto logger, auto subcaller, auto key) {
if (key.target.IsAnonymousTarget()) {
withTargetNode(
key, rule_map, ts, subcaller, setter, logger, result_map);
}
else if (key.target.GetNamedTarget().reference_t ==
+ BuildMaps::Base::ReferenceType::kTree) {
+
+ auto wrapped_logger = std::make_shared<AsyncMapConsumerLogger>(
+ [logger, target = key.target](auto const& msg, bool fatal) {
+ (*logger)(fmt::format("While analysing {} as explicit "
+ "tree reference:\n{}",
+ target.ToString(),
+ msg),
+ fatal);
+ });
+ TreeTarget(key,
+ ts,
+ subcaller,
+ setter,
+ wrapped_logger,
+ result_map,
+ directory_entries_map);
+ }
+ else if (key.target.GetNamedTarget().reference_t ==
BuildMaps::Base::ReferenceType::kFile) {
// Not a defined target, treat as source target
source_target_map->ConsumeAfterKeysReady(
diff --git a/src/buildtool/build_engine/target_map/target_map.hpp b/src/buildtool/build_engine/target_map/target_map.hpp
index 4befc842..54e98626 100644
--- a/src/buildtool/build_engine/target_map/target_map.hpp
+++ b/src/buildtool/build_engine/target_map/target_map.hpp
@@ -14,11 +14,13 @@ namespace BuildMaps::Target {
using TargetMap = AsyncMapConsumer<ConfiguredTarget, AnalysedTargetPtr>;
-auto CreateTargetMap(const gsl::not_null<BuildMaps::Base::SourceTargetMap*>&,
- const gsl::not_null<BuildMaps::Base::TargetsFileMap*>&,
- const gsl::not_null<BuildMaps::Base::UserRuleMap*>&,
- const gsl::not_null<ResultTargetMap*>&,
- std::size_t jobs = 0) -> TargetMap;
+auto CreateTargetMap(
+ const gsl::not_null<BuildMaps::Base::SourceTargetMap*>&,
+ const gsl::not_null<BuildMaps::Base::TargetsFileMap*>&,
+ const gsl::not_null<BuildMaps::Base::UserRuleMap*>&,
+ const gsl::not_null<BuildMaps::Base::DirectoryEntriesMap*>&,
+ const gsl::not_null<ResultTargetMap*>&,
+ std::size_t jobs = 0) -> TargetMap;
auto IsBuiltInRule(nlohmann::json const& rule_type) -> bool;
diff --git a/src/buildtool/main/main.cpp b/src/buildtool/main/main.cpp
index 4f626a4d..bb96c3d3 100644
--- a/src/buildtool/main/main.cpp
+++ b/src/buildtool/main/main.cpp
@@ -619,8 +619,12 @@ struct AnalysisResult {
auto expr_map = Base::CreateExpressionMap(&expressions_file_map, jobs);
auto rule_map = Base::CreateRuleMap(&rule_file_map, &expr_map, jobs);
auto source_targets = Base::CreateSourceTargetMap(&directory_entries, jobs);
- auto target_map = Target::CreateTargetMap(
- &source_targets, &targets_file_map, &rule_map, result_map, jobs);
+ auto target_map = Target::CreateTargetMap(&source_targets,
+ &targets_file_map,
+ &rule_map,
+ &directory_entries,
+ result_map,
+ jobs);
auto id = ReadConfiguredTarget(clargs, main_repo, main_ws_root);
Logger::Log(LogLevel::Info, "Requested target is {}", id.ToString());