From 7f80c0e2d311c7ff2453bdd558e4e7fd91cea872 Mon Sep 17 00:00:00 2001 From: gnaggnoyil Date: Wed, 10 Jul 2019 04:02:48 +0800 Subject: [PATCH] Make handle features (#6797) --- toolsrc/include/vcpkg/base/util.h | 9 ++++ toolsrc/src/vcpkg/commands.dependinfo.cpp | 61 +++++++++++++++++++++-- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index 213adb67c..e629ef0b2 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -6,9 +6,18 @@ #include #include #include +#include namespace vcpkg::Util { + template + constexpr std::add_const_t& as_const(T& t) noexcept + { + return t; + } + template + void as_const(const T&&) = delete; + template using ElementT = std::remove_reference_t::iterator>())>; diff --git a/toolsrc/src/vcpkg/commands.dependinfo.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp index c0800a4b5..8394e0166 100644 --- a/toolsrc/src/vcpkg/commands.dependinfo.cpp +++ b/toolsrc/src/vcpkg/commands.dependinfo.cpp @@ -6,6 +6,10 @@ #include #include #include +#include + +#include +#include #include using vcpkg::Dependencies::PathsPortFileProvider; @@ -130,14 +134,29 @@ namespace vcpkg::Commands::DependInfo const std::vector& source_control_files, const std::unordered_set& switches) { + auto maybe_requested_spec = ParsedSpecifier::from_string(requested_package); + // TODO: move this check to the top-level invocation of this function since + // argument `requested_package` shall always be valid in inner-level invocation. + if (!maybe_requested_spec.has_value()) + { + System::print2(System::Color::warning, + "'", + requested_package, + "' is not a valid package specifier: ", + vcpkg::to_string(maybe_requested_spec.error()), + "\n"); + return; + } + auto requested_spec = maybe_requested_spec.get(); + const auto source_control_file = - Util::find_if(source_control_files, [&requested_package](const auto& source_control_file) { - return source_control_file->core_paragraph->name == requested_package; + Util::find_if(source_control_files, [&requested_spec](const auto& source_control_file) { + return source_control_file->core_paragraph->name == requested_spec->name; }); if (source_control_file != source_control_files.end()) { - const auto new_package = packages_to_keep.insert(requested_package).second; + const auto new_package = packages_to_keep.insert(requested_spec->name).second; if (new_package && !Util::Sets::contains(switches, OPTION_NO_RECURSE)) { @@ -145,6 +164,42 @@ namespace vcpkg::Commands::DependInfo { build_dependencies_list(packages_to_keep, dependency.depend.name, source_control_files, switches); } + + // Collect features with `*` considered + std::set collected_features; + for (const auto& requested_feature_name : requested_spec->features) + { + if (requested_feature_name == "*") + { + for (auto &&feature_paragraph : (*source_control_file)->feature_paragraphs) + { + collected_features.insert(std::addressof(Util::as_const(*feature_paragraph))); + } + continue; + } + auto maybe_feature = (*source_control_file)->find_feature(requested_feature_name); + if (auto &&feature_paragraph = maybe_feature.get()) + { + collected_features.insert(std::addressof(Util::as_const(*feature_paragraph))); + } + else + { + System::print2(System::Color::warning, + "dependency '", + requested_feature_name, + "' of package '", + requested_spec->name, + "' does not exist\n"); + continue; + } + } + for (auto feature_paragraph : collected_features) + { + for (const auto& dependency : feature_paragraph->depends) + { + build_dependencies_list(packages_to_keep, dependency.depend.name, source_control_files, switches); + } + } } } else