From cde34211a506a2efc7483c41d937b31dc8e24666 Mon Sep 17 00:00:00 2001 From: Wim Leflere Date: Tue, 29 Jan 2019 22:40:47 +0100 Subject: Generate dependeny tree graph (#5185) * use dashed link for optional dependency * output full dependency tree * add warning if requested package does not exist * [vcpkg] Formatting * [vcpkg] Fix issue when parsing qualified dependencies Before this change, "harfbuzz[glib] (!x86)" would parse as "harfbuzz[glib]||!x86" instead of the desired "harfbuzz|glib|!x86" * [vcpkg] Improve depend-info handling of features and qualified dependencies. --- toolsrc/src/vcpkg/commands.dependinfo.cpp | 96 ++++++++++++++++++------------- toolsrc/src/vcpkg/sourceparagraph.cpp | 7 +-- 2 files changed, 59 insertions(+), 44 deletions(-) diff --git a/toolsrc/src/vcpkg/commands.dependinfo.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp index 5f72e965b..455f3b7c5 100644 --- a/toolsrc/src/vcpkg/commands.dependinfo.cpp +++ b/toolsrc/src/vcpkg/commands.dependinfo.cpp @@ -12,16 +12,16 @@ namespace vcpkg::Commands::DependInfo constexpr StringLiteral OPTION_DOT = "--dot"; constexpr StringLiteral OPTION_DGML = "--dgml"; - constexpr std::array DEPEND_SWITCHES = { { - { OPTION_DOT, "Creates graph on basis of dot" }, - { OPTION_DGML, "Creates graph on basis of dgml" }, - } }; + constexpr std::array DEPEND_SWITCHES = {{ + {OPTION_DOT, "Creates graph on basis of dot"}, + {OPTION_DGML, "Creates graph on basis of dgml"}, + }}; const CommandStructure COMMAND_STRUCTURE = { Help::create_example_string(R"###(depend-info [pat])###"), 0, - 1, - { DEPEND_SWITCHES,{} }, + SIZE_MAX, + {DEPEND_SWITCHES, {}}, nullptr, }; @@ -32,8 +32,7 @@ namespace vcpkg::Commands::DependInfo return output; } - std::string create_dot_as_string( - const std::vector>& source_control_files) + std::string create_dot_as_string(const std::vector>& source_control_files) { int empty_node_count = 0; @@ -53,7 +52,7 @@ namespace vcpkg::Commands::DependInfo s.append(Strings::format("%s;", name)); for (const Dependency& d : source_paragraph.depends) { - const std::string dependency_name = replace_dashes_with_underscore(d.name()); + const std::string dependency_name = replace_dashes_with_underscore(d.depend.name); s.append(Strings::format("%s -> %s;", name, dependency_name)); } } @@ -62,8 +61,7 @@ namespace vcpkg::Commands::DependInfo return s; } - std::string create_dgml_as_string( - const std::vector>& source_control_files) + std::string create_dgml_as_string(const std::vector>& source_control_files) { std::string s; s.append(""); @@ -79,16 +77,22 @@ namespace vcpkg::Commands::DependInfo // Iterate over dependencies. for (const Dependency& d : source_paragraph.depends) { - links.append(Strings::format("", name, d.name())); + if (d.qualifier.empty()) + links.append(Strings::format("", name, d.depend.name)); + else + links.append(Strings::format( + "", name, d.depend.name)); } // Iterate over feature dependencies. - const std::vector>& feature_paragraphs = source_control_file->feature_paragraphs; + const std::vector>& feature_paragraphs = + source_control_file->feature_paragraphs; for (const auto& feature_paragraph : feature_paragraphs) { for (const Dependency& d : feature_paragraph->depends) { - links.append(Strings::format("", name, d.name())); + links.append(Strings::format( + "", name, d.depend.name)); } } } @@ -101,9 +105,8 @@ namespace vcpkg::Commands::DependInfo return s; } - std::string create_graph_as_string( - const std::unordered_set& switches, - const std::vector>& source_control_files) + std::string create_graph_as_string(const std::unordered_set& switches, + const std::vector>& source_control_files) { if (Util::Sets::contains(switches, OPTION_DOT)) { @@ -116,35 +119,50 @@ namespace vcpkg::Commands::DependInfo return ""; } + void build_dependencies_list(std::set& packages_to_keep, + const std::string& requested_package, + const std::vector>& source_control_files) + { + 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; + }); + + if (source_control_file != source_control_files.end()) + { + const auto new_package = packages_to_keep.insert(requested_package).second; + + if (new_package) + { + for (const auto& dependency : (*source_control_file)->core_paragraph->depends) + { + build_dependencies_list(packages_to_keep, dependency.depend.name, source_control_files); + } + } + } + else + { + System::println(System::Color::warning, "package '%s' does not exist", requested_package); + } + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); auto source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - if (args.command_arguments.size() == 1) + if (args.command_arguments.size() >= 1) { - const std::string filter = args.command_arguments.at(0); - - Util::erase_remove_if(source_control_files, - [&](const std::unique_ptr& source_control_file) { - const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; - - if (Strings::case_insensitive_ascii_contains(source_paragraph.name, filter)) - { - return false; - } - - for (const Dependency& dependency : source_paragraph.depends) - { - if (Strings::case_insensitive_ascii_contains(dependency.name(), filter)) - { - return false; - } - } - - return true; - }); + std::set packages_to_keep; + for (const auto& requested_package : args.command_arguments) + { + build_dependencies_list(packages_to_keep, requested_package, source_control_files); + } + + Util::erase_remove_if(source_control_files, [&packages_to_keep](const auto& source_control_file) { + return !Util::Sets::contains(packages_to_keep, source_control_file->core_paragraph->name); + }); } if (!options.switches.empty()) diff --git a/toolsrc/src/vcpkg/sourceparagraph.cpp b/toolsrc/src/vcpkg/sourceparagraph.cpp index ed61cb42a..baa8b070b 100644 --- a/toolsrc/src/vcpkg/sourceparagraph.cpp +++ b/toolsrc/src/vcpkg/sourceparagraph.cpp @@ -194,16 +194,13 @@ namespace vcpkg auto pos = depend_string.find(' '); if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, ""); // expect of the form "\w+ \[\w+\]" - Dependency dep; - - dep.depend.name = depend_string.substr(0, pos); if (depend_string.c_str()[pos + 1] != '(' || depend_string[depend_string.size() - 1] != ')') { // Error, but for now just slurp the entire string. return Dependency::parse_dependency(depend_string, ""); } - dep.qualifier = depend_string.substr(pos + 2, depend_string.size() - pos - 3); - return dep; + return Dependency::parse_dependency(depend_string.substr(0, pos), + depend_string.substr(pos + 2, depend_string.size() - pos - 3)); }); } -- cgit v1.2.3