diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/build_engine/base_maps/entity_name.hpp | 21 | ||||
-rw-r--r-- | src/buildtool/build_engine/base_maps/entity_name_data.hpp | 6 | ||||
-rw-r--r-- | src/buildtool/build_engine/target_map/target_map.cpp | 240 | ||||
-rw-r--r-- | src/buildtool/main/main.cpp | 3 |
4 files changed, 180 insertions, 90 deletions
diff --git a/src/buildtool/build_engine/base_maps/entity_name.hpp b/src/buildtool/build_engine/base_maps/entity_name.hpp index 49744ed4..2b5ddd57 100644 --- a/src/buildtool/build_engine/base_maps/entity_name.hpp +++ b/src/buildtool/build_engine/base_maps/entity_name.hpp @@ -98,25 +98,23 @@ template <typename T> std::nullopt) noexcept -> std::optional<EntityName> { try { bool const is_file = s0 == EntityName::kFileLocationMarker; + auto const ref_type = + s0 == EntityName::kFileLocationMarker + ? ReferenceType::kFile + : (s0 == EntityName::kGlobMarker ? ReferenceType::kGlob + : ReferenceType::kTree); if (list_size == 3) { if (IsString(list[2])) { auto const& name = GetString(list[2]); auto const& x = current.GetNamedTarget(); if (IsNone(list[1])) { - return EntityName{x.repository, - x.module, - name, - (is_file ? ReferenceType::kFile - : ReferenceType::kTree)}; + return EntityName{x.repository, x.module, name, ref_type}; } if (IsString(list[1])) { auto const& middle = GetString(list[1]); if (middle == "." or middle == x.module) { - return EntityName{x.repository, - x.module, - name, - (is_file ? ReferenceType::kFile - : ReferenceType::kTree)}; + return EntityName{ + x.repository, x.module, name, ref_type}; } } if (logger) { @@ -219,7 +217,8 @@ template <typename T> "obtained as FIELD value of anonymous fields")); } else if (s0 == EntityName::kFileLocationMarker or - s0 == EntityName::kTreeLocationMarker) { + s0 == EntityName::kTreeLocationMarker or + s0 == EntityName::kGlobMarker) { return ParseEntityNameFSReference( s0, list, list_size, current, logger); } 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 e3ecf607..902c9b38 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, kTree }; +enum class ReferenceType : std::int8_t { kTarget, kFile, kTree, kGlob }; struct NamedTarget { std::string repository{}; @@ -65,6 +65,7 @@ class EntityName { static constexpr auto kLocationMarker = "@"; static constexpr auto kFileLocationMarker = "FILE"; static constexpr auto kTreeLocationMarker = "TREE"; + static constexpr auto kGlobMarker = "GLOB"; static constexpr auto kRelativeLocationMarker = "./"; static constexpr auto kAnonymousMarker = "#"; @@ -119,6 +120,9 @@ class EntityName { else if (x.reference_t == ReferenceType::kTree) { j.push_back(kTreeLocationMarker); } + else if (x.reference_t == ReferenceType::kGlob) { + j.push_back(kGlobMarker); + } 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 087bcacb..66e1ec73 100644 --- a/src/buildtool/build_engine/target_map/target_map.cpp +++ b/src/buildtool/build_engine/target_map/target_map.cpp @@ -6,6 +6,8 @@ #include <string> #include <utility> +#include <fnmatch.h> + #include "fmt/format.h" #include "nlohmann/json.hpp" #include "src/buildtool/build_engine/base_maps/field_reader.hpp" @@ -1411,6 +1413,55 @@ void TreeTarget( }); } +void GlobResult(const std::vector<AnalysedTargetPtr const*>& values, + const BuildMaps::Target::TargetMap::SetterPtr& setter) { + auto result = Expression::map_t::underlying_map_t{}; + for (auto const& value : values) { + for (auto const& [k, v] : (*value)->Artifacts()->Map()) { + result[k] = v; + } + } + auto stage = ExpressionPtr{Expression::map_t{result}}; + auto target = std::make_shared<AnalysedTarget>( + TargetResult{stage, Expression::kEmptyMap, stage}, + std::vector<ActionDescription::Ptr>{}, + std::vector<std::string>{}, + std::vector<Tree::Ptr>{}, + std::unordered_set<std::string>{}, + std::set<std::string>{}); + (*setter)(std::move(target)); +} + +void GlobTargetWithDirEntry( + const BuildMaps::Base::EntityName& key, + const gsl::not_null<TaskSystem*>& ts, + const BuildMaps::Target::TargetMap::SetterPtr& setter, + const BuildMaps::Target::TargetMap::LoggerPtr& logger, + const gsl::not_null<BuildMaps::Base::SourceTargetMap*>& source_target_map, + const FileRoot::DirectoryEntries& dir) { + auto const& target = key.GetNamedTarget(); + auto const& pattern = target.name; + std::vector<BuildMaps::Base::EntityName> matches; + for (auto const& x : dir.FilesIterator()) { + if (fnmatch(pattern.c_str(), x.c_str(), 0) == 0) { + matches.emplace_back(BuildMaps::Base::EntityName{ + target.repository, + target.module, + x, + BuildMaps::Base::ReferenceType::kFile}); + } + } + source_target_map->ConsumeAfterKeysReady( + ts, + matches, + [setter](auto values) { GlobResult(values, setter); }, + [logger](auto const& msg, bool fatal) { + (*logger)( + fmt::format("While handling matching file targets:\n{}", msg), + fatal); + }); +} + } // namespace namespace BuildMaps::Target { @@ -1422,84 +1473,117 @@ auto CreateTargetMap( 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, - 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( - ts, - {key.target}, - [setter](auto values) { - (*setter)(AnalysedTargetPtr{*values[0]}); - }, - [logger, target = key.target](auto const& msg, auto fatal) { - (*logger)(fmt::format("While analysing target {} as " - "explicit source target:\n{}", - target.ToString(), - msg), - fatal); - }); - } - else { - targets_file_map->ConsumeAfterKeysReady( - ts, - {key.target.ToModule()}, - [key, - source_target_map, - rule_map, - ts, - subcaller = std::move(subcaller), - setter = std::move(setter), - logger, - result_map](auto values) { - withTargetsFile(key, - *values[0], - source_target_map, - rule_map, - ts, - subcaller, - setter, - logger, - result_map); - }, - [logger, target = key.target](auto const& msg, auto fatal) { - (*logger)(fmt::format("While searching targets " - "description for {}:\n{}", - target.ToString(), - msg), - fatal); - }); - } - }; + auto target_reader = [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( + ts, + {key.target}, + [setter](auto values) { + (*setter)(AnalysedTargetPtr{*values[0]}); + }, + [logger, target = key.target](auto const& msg, auto fatal) { + (*logger)(fmt::format("While analysing target {} as " + "explicit source target:\n{}", + target.ToString(), + msg), + fatal); + }); + } + else if (key.target.GetNamedTarget().reference_t == + BuildMaps::Base::ReferenceType::kGlob) { + auto wrapped_logger = std::make_shared<AsyncMapConsumerLogger>( + [logger, target = key.target](auto const& msg, bool fatal) { + (*logger)(fmt::format("While analysing {} as glob:\n{}", + target.ToString(), + msg), + fatal); + }); + auto const& target = key.target; + directory_entries_map->ConsumeAfterKeysReady( + ts, + {target.ToModule()}, + [target, ts, setter, wrapped_logger, source_target_map]( + auto values) { + GlobTargetWithDirEntry(target, + ts, + setter, + wrapped_logger, + source_target_map, + *values[0]); + }, + [target, logger](auto const& msg, bool fatal) { + (*logger)(fmt::format("While reading directory for {}:\n{}", + target.ToString(), + msg), + fatal); + } + + ); + } + else { + targets_file_map->ConsumeAfterKeysReady( + ts, + {key.target.ToModule()}, + [key, + source_target_map, + rule_map, + ts, + subcaller = std::move(subcaller), + setter = std::move(setter), + logger, + result_map](auto values) { + withTargetsFile(key, + *values[0], + source_target_map, + rule_map, + ts, + subcaller, + setter, + logger, + result_map); + }, + [logger, target = key.target](auto const& msg, auto fatal) { + (*logger)(fmt::format("While searching targets " + "description for {}:\n{}", + target.ToString(), + msg), + fatal); + }); + } + }; return AsyncMapConsumer<ConfiguredTarget, AnalysedTargetPtr>(target_reader, jobs); } diff --git a/src/buildtool/main/main.cpp b/src/buildtool/main/main.cpp index 30035819..c904f689 100644 --- a/src/buildtool/main/main.cpp +++ b/src/buildtool/main/main.cpp @@ -949,6 +949,9 @@ auto DetermineNonExplicitTarget( case Base::ReferenceType::kTree: std::cout << id.ToString() << " is a tree." << std::endl; return std::nullopt; + case Base::ReferenceType::kGlob: + std::cout << id.ToString() << " is a glob." << std::endl; + return std::nullopt; case Base::ReferenceType::kTarget: return id; } |