aboutsummaryrefslogtreecommitdiff
path: root/toolsrc
diff options
context:
space:
mode:
authorgnaggnoyil <gnaggnoyil@gmail.com>2019-07-10 04:02:48 +0800
committerCurtis J Bezault <curtbezault@gmail.com>2019-07-09 16:02:48 -0400
commit7f80c0e2d311c7ff2453bdd558e4e7fd91cea872 (patch)
tree2ab8cd4514926f64e4e210696c151bc31d90ab45 /toolsrc
parenta15e2446faadd558171cd08f352bf51cb659d13a (diff)
downloadvcpkg-7f80c0e2d311c7ff2453bdd558e4e7fd91cea872.tar.gz
vcpkg-7f80c0e2d311c7ff2453bdd558e4e7fd91cea872.zip
Make handle features (#6797)
Diffstat (limited to 'toolsrc')
-rw-r--r--toolsrc/include/vcpkg/base/util.h9
-rw-r--r--toolsrc/src/vcpkg/commands.dependinfo.cpp61
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 <unordered_map>
#include <utility>
#include <vector>
+#include <type_traits>
namespace vcpkg::Util
{
+ template <class T>
+ constexpr std::add_const_t<T>& as_const(T& t) noexcept
+ {
+ return t;
+ }
+ template <class T>
+ void as_const(const T&&) = delete;
+
template<class Container>
using ElementT =
std::remove_reference_t<decltype(*std::declval<typename std::remove_reference_t<Container>::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 <vcpkg/commands.h>
#include <vcpkg/help.h>
#include <vcpkg/paragraphs.h>
+#include <vcpkg/packagespec.h>
+
+#include <vector>
+#include <memory>
#include <vcpkg/dependencies.h>
using vcpkg::Dependencies::PathsPortFileProvider;
@@ -130,14 +134,29 @@ namespace vcpkg::Commands::DependInfo
const std::vector<const SourceControlFile*>& source_control_files,
const std::unordered_set<std::string>& 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<const FeatureParagraph*> 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