diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/build_engine/base_maps/entity_name.hpp | 54 | ||||
-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 | 117 | ||||
-rw-r--r-- | src/buildtool/build_engine/target_map/target_map.hpp | 12 | ||||
-rw-r--r-- | src/buildtool/main/main.cpp | 8 |
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()); |