From 1e9434ee6e3106c85ca65fca4d3ed609caf38c24 Mon Sep 17 00:00:00 2001 From: JackBoosY Date: Thu, 6 May 2021 23:57:24 -0700 Subject: [PATCH 01/10] [command:depend-info] Add tree display --- include/vcpkg/commands.dependinfo.h | 11 ++++ src/vcpkg/commands.dependinfo.cpp | 91 +++++++++++++++++++++-------- 2 files changed, 78 insertions(+), 24 deletions(-) diff --git a/include/vcpkg/commands.dependinfo.h b/include/vcpkg/commands.dependinfo.h index ef5d8a1080..f8476491ae 100644 --- a/include/vcpkg/commands.dependinfo.h +++ b/include/vcpkg/commands.dependinfo.h @@ -5,11 +5,22 @@ namespace vcpkg::Commands::DependInfo { extern const CommandStructure COMMAND_STRUCTURE; + + struct PackageDependInfo + { + std::string package; + int depth; + std::unordered_set features; + std::vector dependencies; + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet, Triplet host_triplet); + void RecurseFindDependencies(int level, std::string currDepend, std::vector allDepends); + struct DependInfoCommand : TripletCommand { virtual void perform_and_exit(const VcpkgCmdArguments& args, diff --git a/src/vcpkg/commands.dependinfo.cpp b/src/vcpkg/commands.dependinfo.cpp index bade947902..5666816cd9 100644 --- a/src/vcpkg/commands.dependinfo.cpp +++ b/src/vcpkg/commands.dependinfo.cpp @@ -42,19 +42,12 @@ namespace vcpkg::Commands::DependInfo "(default), " "reverse"}}}; - struct PackageDependInfo - { - std::string package; - int depth; - std::unordered_set features; - std::vector dependencies; - }; - enum SortMode { Lexicographical = 0, Topological, ReverseTopological, + Treelogical, Default = Topological }; @@ -82,10 +75,12 @@ namespace vcpkg::Commands::DependInfo constexpr StringLiteral OPTION_SORT_LEXICOGRAPHICAL = "lexicographical"; constexpr StringLiteral OPTION_SORT_TOPOLOGICAL = "topological"; constexpr StringLiteral OPTION_SORT_REVERSE = "reverse"; + constexpr StringLiteral OPTION_SORT_TREE = "tree"; static const std::map sortModesMap{{OPTION_SORT_LEXICOGRAPHICAL, Lexicographical}, {OPTION_SORT_TOPOLOGICAL, Topological}, - {OPTION_SORT_REVERSE, ReverseTopological}}; + {OPTION_SORT_REVERSE, ReverseTopological}, + {OPTION_SORT_TREE, Treelogical}}; auto iter = options.settings.find(OPTION_SORT); if (iter != options.settings.end()) @@ -304,36 +299,84 @@ namespace vcpkg::Commands::DependInfo { case SortMode::Lexicographical: std::sort(std::begin(depend_info), std::end(depend_info), lex); break; case SortMode::ReverseTopological: + case SortMode::Treelogical: std::sort(std::begin(depend_info), std::end(depend_info), reverse); break; case SortMode::Topological: std::sort(std::begin(depend_info), std::end(depend_info), topo); break; default: Checks::unreachable(VCPKG_LINE_INFO); } - for (auto&& info : depend_info) + if (sort_mode == SortMode::Treelogical) { - if (info.depth >= 0) - { - std::string features = Strings::join(", ", info.features); - const std::string dependencies = Strings::join(", ", info.dependencies); + auto first = depend_info.begin(); + std::string features = Strings::join(", ", first->features); + const std::string dependencies = Strings::join(", ", first->dependencies); - if (show_depth) - { - System::print2(System::Color::error, "(", info.depth, ") "); - } - System::print2(System::Color::success, info.package); - if (!features.empty()) + if (show_depth) + { + System::print2(System::Color::error, "(", first->depth, ") "); + } + System::print2(System::Color::success, first->package); + if (!features.empty()) + { + System::print2("["); + System::print2(System::Color::warning, features); + System::print2("]"); + } + System::print2("\n"); + RecurseFindDependencies(0, first->package, depend_info); + } + else + { + for (auto&& info : depend_info) + { + if (info.depth >= 0) { - System::print2("["); - System::print2(System::Color::warning, features); - System::print2("]"); + std::string features = Strings::join(", ", info.features); + const std::string dependencies = Strings::join(", ", info.dependencies); + + if (show_depth) + { + System::print2(System::Color::error, "(", info.depth, ") "); + } + System::print2(System::Color::success, info.package); + if (!features.empty()) + { + System::print2("["); + System::print2(System::Color::warning, features); + System::print2("]"); + } + System::print2(": ", dependencies, "\n"); } - System::print2(": ", dependencies, "\n"); } } Checks::exit_success(VCPKG_LINE_INFO); } + void RecurseFindDependencies(int level, std::string currDepend, std::vector allDepends) + { + auto currPos = allDepends.begin(); + for (currPos = allDepends.begin(); currPos != allDepends.end(); currPos++) + { + if (currPos->package == currDepend) + { + break; + } + } + + for (auto i = currPos->dependencies.begin(); i != currPos->dependencies.end(); i++) + { + if (level) + System::print2("|"); + for (size_t j = 0; j < level * 4; j++) + { + System::print2(" "); + } + System::print2("+-- ", i->c_str(), "\n"); + RecurseFindDependencies(level + 1, i->c_str(), allDepends); + } + } + void DependInfoCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet, From a6a99e0843051fc18433c223fe199418935d19d9 Mon Sep 17 00:00:00 2001 From: JackBoosY Date: Fri, 7 May 2021 01:21:17 -0700 Subject: [PATCH 02/10] change size_t to auto --- src/vcpkg/commands.dependinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vcpkg/commands.dependinfo.cpp b/src/vcpkg/commands.dependinfo.cpp index 5666816cd9..43819f0cff 100644 --- a/src/vcpkg/commands.dependinfo.cpp +++ b/src/vcpkg/commands.dependinfo.cpp @@ -368,7 +368,7 @@ namespace vcpkg::Commands::DependInfo { if (level) System::print2("|"); - for (size_t j = 0; j < level * 4; j++) + for (auto j = 0; j < level * 4; j++) { System::print2(" "); } From beeaa8d79d36acc3710f379dbc8ee7cb97d65837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jack=C2=B7Boos=C2=B7Yu?= <47264268+JackBoosY@users.noreply.github.com> Date: Tue, 18 May 2021 10:37:56 +0800 Subject: [PATCH 03/10] Update src/vcpkg/commands.dependinfo.cpp Co-authored-by: ras0219 <533828+ras0219@users.noreply.github.com> --- src/vcpkg/commands.dependinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vcpkg/commands.dependinfo.cpp b/src/vcpkg/commands.dependinfo.cpp index 43819f0cff..0eb6e5fe35 100644 --- a/src/vcpkg/commands.dependinfo.cpp +++ b/src/vcpkg/commands.dependinfo.cpp @@ -75,7 +75,7 @@ namespace vcpkg::Commands::DependInfo constexpr StringLiteral OPTION_SORT_LEXICOGRAPHICAL = "lexicographical"; constexpr StringLiteral OPTION_SORT_TOPOLOGICAL = "topological"; constexpr StringLiteral OPTION_SORT_REVERSE = "reverse"; - constexpr StringLiteral OPTION_SORT_TREE = "tree"; + constexpr StringLiteral OPTION_SORT_TREE = "x-tree"; static const std::map sortModesMap{{OPTION_SORT_LEXICOGRAPHICAL, Lexicographical}, {OPTION_SORT_TOPOLOGICAL, Topological}, From 3384e5d3249ff86f3e376400fb0ece88eaa7c3bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jack=C2=B7Boos=C2=B7Yu?= <47264268+JackBoosY@users.noreply.github.com> Date: Tue, 18 May 2021 10:38:00 +0800 Subject: [PATCH 04/10] Update src/vcpkg/commands.dependinfo.cpp Co-authored-by: ras0219 <533828+ras0219@users.noreply.github.com> --- src/vcpkg/commands.dependinfo.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vcpkg/commands.dependinfo.cpp b/src/vcpkg/commands.dependinfo.cpp index 0eb6e5fe35..9695e406ac 100644 --- a/src/vcpkg/commands.dependinfo.cpp +++ b/src/vcpkg/commands.dependinfo.cpp @@ -310,7 +310,6 @@ namespace vcpkg::Commands::DependInfo { auto first = depend_info.begin(); std::string features = Strings::join(", ", first->features); - const std::string dependencies = Strings::join(", ", first->dependencies); if (show_depth) { From 166efaeb478475fe3a98550fb3a1472a72abec9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jack=C2=B7Boos=C2=B7Yu?= <47264268+JackBoosY@users.noreply.github.com> Date: Tue, 18 May 2021 10:38:05 +0800 Subject: [PATCH 05/10] Update src/vcpkg/commands.dependinfo.cpp Co-authored-by: ras0219 <533828+ras0219@users.noreply.github.com> --- src/vcpkg/commands.dependinfo.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vcpkg/commands.dependinfo.cpp b/src/vcpkg/commands.dependinfo.cpp index 9695e406ac..2992d86d7e 100644 --- a/src/vcpkg/commands.dependinfo.cpp +++ b/src/vcpkg/commands.dependinfo.cpp @@ -354,7 +354,10 @@ namespace vcpkg::Commands::DependInfo void RecurseFindDependencies(int level, std::string currDepend, std::vector allDepends) { - auto currPos = allDepends.begin(); + if (level == 100) + { + Checks::exit_with_message(VCPKG_LINE_INFO, "Recursion depth exceeded."); + } for (currPos = allDepends.begin(); currPos != allDepends.end(); currPos++) { if (currPos->package == currDepend) From 46afbe0489894c30824afc57155b10effcfd040f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jack=C2=B7Boos=C2=B7Yu?= <47264268+JackBoosY@users.noreply.github.com> Date: Tue, 18 May 2021 10:38:09 +0800 Subject: [PATCH 06/10] Update src/vcpkg/commands.dependinfo.cpp Co-authored-by: ras0219 <533828+ras0219@users.noreply.github.com> --- src/vcpkg/commands.dependinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vcpkg/commands.dependinfo.cpp b/src/vcpkg/commands.dependinfo.cpp index 2992d86d7e..70f152db34 100644 --- a/src/vcpkg/commands.dependinfo.cpp +++ b/src/vcpkg/commands.dependinfo.cpp @@ -352,7 +352,7 @@ namespace vcpkg::Commands::DependInfo Checks::exit_success(VCPKG_LINE_INFO); } - void RecurseFindDependencies(int level, std::string currDepend, std::vector allDepends) + void RecurseFindDependencies(int level, const std::string& currDepend, const std::vector& allDepends) { if (level == 100) { From 289cab91ba1bf178625cc0309f266a06acbde0b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jack=C2=B7Boos=C2=B7Yu?= <47264268+JackBoosY@users.noreply.github.com> Date: Tue, 18 May 2021 10:38:13 +0800 Subject: [PATCH 07/10] Update src/vcpkg/commands.dependinfo.cpp Co-authored-by: ras0219 <533828+ras0219@users.noreply.github.com> --- src/vcpkg/commands.dependinfo.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/vcpkg/commands.dependinfo.cpp b/src/vcpkg/commands.dependinfo.cpp index 70f152db34..2ed47c1200 100644 --- a/src/vcpkg/commands.dependinfo.cpp +++ b/src/vcpkg/commands.dependinfo.cpp @@ -358,13 +358,8 @@ namespace vcpkg::Commands::DependInfo { Checks::exit_with_message(VCPKG_LINE_INFO, "Recursion depth exceeded."); } - for (currPos = allDepends.begin(); currPos != allDepends.end(); currPos++) - { - if (currPos->package == currDepend) - { - break; - } - } + auto currPos = std::find_if(allDepends.begin(), allDepends.end(), [&currDepend](const auto& p) { return p.package == currDepend; }); + Checks::check_exit(VCPKG_LINE_INFO, currPos != allDepends.end(), "internal vcpkg error"); for (auto i = currPos->dependencies.begin(); i != currPos->dependencies.end(); i++) { From 7d5d0ee10038fbb63ff00df0bbea29cb7d636f2e Mon Sep 17 00:00:00 2001 From: JackBoosY Date: Thu, 20 May 2021 01:16:43 -0700 Subject: [PATCH 08/10] Improve output, fix the connecting lines and spaces in front --- include/vcpkg/commands.dependinfo.h | 2 +- src/vcpkg/commands.dependinfo.cpp | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/include/vcpkg/commands.dependinfo.h b/include/vcpkg/commands.dependinfo.h index f8476491ae..3a56b73dd2 100644 --- a/include/vcpkg/commands.dependinfo.h +++ b/include/vcpkg/commands.dependinfo.h @@ -19,7 +19,7 @@ namespace vcpkg::Commands::DependInfo Triplet default_triplet, Triplet host_triplet); - void RecurseFindDependencies(int level, std::string currDepend, std::vector allDepends); + void RecurseFindDependencies(int levelFrom, const std::string& currDepend, const std::vector& allDepends); struct DependInfoCommand : TripletCommand { diff --git a/src/vcpkg/commands.dependinfo.cpp b/src/vcpkg/commands.dependinfo.cpp index 2ed47c1200..f8f0c3f6af 100644 --- a/src/vcpkg/commands.dependinfo.cpp +++ b/src/vcpkg/commands.dependinfo.cpp @@ -352,25 +352,26 @@ namespace vcpkg::Commands::DependInfo Checks::exit_success(VCPKG_LINE_INFO); } - void RecurseFindDependencies(int level, const std::string& currDepend, const std::vector& allDepends) + void RecurseFindDependencies(int levelFrom, const std::string& currDepend, const std::vector& allDepends) { - if (level == 100) + if (levelFrom == 100) { Checks::exit_with_message(VCPKG_LINE_INFO, "Recursion depth exceeded."); } auto currPos = std::find_if(allDepends.begin(), allDepends.end(), [&currDepend](const auto& p) { return p.package == currDepend; }); Checks::check_exit(VCPKG_LINE_INFO, currPos != allDepends.end(), "internal vcpkg error"); - + for (auto i = currPos->dependencies.begin(); i != currPos->dependencies.end(); i++) { - if (level) - System::print2("|"); - for (auto j = 0; j < level * 4; j++) + // Handle the connecting lines and spaces in front + for (auto j = 0; j < levelFrom; j++) { - System::print2(" "); + System::print2("| "); } + + // Handle the current level System::print2("+-- ", i->c_str(), "\n"); - RecurseFindDependencies(level + 1, i->c_str(), allDepends); + RecurseFindDependencies(levelFrom + 1, i->c_str(), allDepends); } } From bbe737fe1114970ce2af7fb86027a0eed983ecf5 Mon Sep 17 00:00:00 2001 From: JackBoosY Date: Thu, 20 May 2021 01:37:58 -0700 Subject: [PATCH 09/10] Delete the extra connecting line in front of the last element --- include/vcpkg/commands.dependinfo.h | 2 +- src/vcpkg/commands.dependinfo.cpp | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/include/vcpkg/commands.dependinfo.h b/include/vcpkg/commands.dependinfo.h index 3a56b73dd2..10f17e21d1 100644 --- a/include/vcpkg/commands.dependinfo.h +++ b/include/vcpkg/commands.dependinfo.h @@ -19,7 +19,7 @@ namespace vcpkg::Commands::DependInfo Triplet default_triplet, Triplet host_triplet); - void RecurseFindDependencies(int levelFrom, const std::string& currDepend, const std::vector& allDepends); + void RecurseFindDependencies(int levelFrom, const std::string& currDepend, bool isEnd, const std::vector& allDepends); struct DependInfoCommand : TripletCommand { diff --git a/src/vcpkg/commands.dependinfo.cpp b/src/vcpkg/commands.dependinfo.cpp index f8f0c3f6af..7c413b0d51 100644 --- a/src/vcpkg/commands.dependinfo.cpp +++ b/src/vcpkg/commands.dependinfo.cpp @@ -323,7 +323,7 @@ namespace vcpkg::Commands::DependInfo System::print2("]"); } System::print2("\n"); - RecurseFindDependencies(0, first->package, depend_info); + RecurseFindDependencies(0, first->package, false, depend_info); } else { @@ -352,7 +352,7 @@ namespace vcpkg::Commands::DependInfo Checks::exit_success(VCPKG_LINE_INFO); } - void RecurseFindDependencies(int levelFrom, const std::string& currDepend, const std::vector& allDepends) + void RecurseFindDependencies(int levelFrom, const std::string& currDepend, bool isEnd, const std::vector& allDepends) { if (levelFrom == 100) { @@ -364,14 +364,24 @@ namespace vcpkg::Commands::DependInfo for (auto i = currPos->dependencies.begin(); i != currPos->dependencies.end(); i++) { // Handle the connecting lines and spaces in front - for (auto j = 0; j < levelFrom; j++) + if (levelFrom) { - System::print2("| "); + for (auto j = 0; j < levelFrom - 1; j++) + { + System::print2("| "); + } + + if (!isEnd) + System::print2("| "); + else + System::print2(" "); } // Handle the current level System::print2("+-- ", i->c_str(), "\n"); - RecurseFindDependencies(levelFrom + 1, i->c_str(), allDepends); + // The last element doesn't need additional connecting lines + auto j = i; + RecurseFindDependencies(levelFrom + 1, i->c_str(), ++j == currPos->dependencies.end(), allDepends); } } From a54472e98fed8bf0f1eefc4dff26e0b86dfd31b5 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 13 Nov 2021 21:49:50 +0000 Subject: [PATCH 10/10] Fix multiple 'last' levels, reuse buffer, avoid combinatoricic explosion --- include/vcpkg/commands.dependinfo.h | 10 --- src/vcpkg/commands.dependinfo.cpp | 105 ++++++++++++++++++---------- 2 files changed, 67 insertions(+), 48 deletions(-) diff --git a/include/vcpkg/commands.dependinfo.h b/include/vcpkg/commands.dependinfo.h index 10f17e21d1..1b28b79fe9 100644 --- a/include/vcpkg/commands.dependinfo.h +++ b/include/vcpkg/commands.dependinfo.h @@ -6,21 +6,11 @@ namespace vcpkg::Commands::DependInfo { extern const CommandStructure COMMAND_STRUCTURE; - struct PackageDependInfo - { - std::string package; - int depth; - std::unordered_set features; - std::vector dependencies; - }; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet, Triplet host_triplet); - void RecurseFindDependencies(int levelFrom, const std::string& currDepend, bool isEnd, const std::vector& allDepends); - struct DependInfoCommand : TripletCommand { virtual void perform_and_exit(const VcpkgCmdArguments& args, diff --git a/src/vcpkg/commands.dependinfo.cpp b/src/vcpkg/commands.dependinfo.cpp index f04ed2c585..6ba1e74aae 100644 --- a/src/vcpkg/commands.dependinfo.cpp +++ b/src/vcpkg/commands.dependinfo.cpp @@ -22,6 +22,70 @@ namespace vcpkg::Commands::DependInfo { namespace { + struct PackageDependInfo + { + std::string package; + int depth; + std::unordered_set features; + std::vector dependencies; + }; + + // invariant: prefix_buf is equivalent on exitv (but may have been reallocated) + void print_dep_tree(std::string& prefix_buf, + const std::string& currDepend, + const std::vector& allDepends, + std::set& printed) + { + if (prefix_buf.size() > 400) + { + Checks::exit_with_message(VCPKG_LINE_INFO, "Recursion depth exceeded."); + } + auto currPos = std::find_if( + allDepends.begin(), allDepends.end(), [&currDepend](const auto& p) { return p.package == currDepend; }); + Checks::check_exit(VCPKG_LINE_INFO, currPos != allDepends.end(), "internal vcpkg error"); + if (currPos->dependencies.empty()) + { + return; + } + + const size_t original_size = prefix_buf.size(); + + if (Util::Sets::contains(printed, currDepend)) + { + // If we've already printed the set of dependencies, print an elipsis instead + Strings::append(prefix_buf, "+- ...\n"); + print2(prefix_buf); + prefix_buf.resize(original_size); + } + else + { + printed.insert(currDepend); + + for (auto i = currPos->dependencies.begin(); i != currPos->dependencies.end() - 1; ++i) + { + // Print the current level + Strings::append(prefix_buf, "+-- ", *i, "\n"); + print2(prefix_buf); + prefix_buf.resize(original_size); + + // Recurse + prefix_buf.append("| "); + print_dep_tree(prefix_buf, *i, allDepends, printed); + prefix_buf.resize(original_size); + } + + // Print the last of the current level + Strings::append(prefix_buf, "+-- ", currPos->dependencies.back(), "\n"); + print2(prefix_buf); + prefix_buf.resize(original_size); + + // Recurse + prefix_buf.append(" "); + print_dep_tree(prefix_buf, currPos->dependencies.back(), allDepends, printed); + prefix_buf.resize(original_size); + } + } + constexpr StringLiteral OPTION_DOT = "dot"; constexpr StringLiteral OPTION_DGML = "dgml"; constexpr StringLiteral OPTION_SHOW_DEPTH = "show-depth"; @@ -321,7 +385,9 @@ namespace vcpkg::Commands::DependInfo print2("]"); } print2("\n"); - RecurseFindDependencies(0, first->package, false, depend_info); + std::set printed; + std::string prefix_buf; + print_dep_tree(prefix_buf, first->package, depend_info, printed); } else { @@ -350,43 +416,6 @@ namespace vcpkg::Commands::DependInfo Checks::exit_success(VCPKG_LINE_INFO); } - void RecurseFindDependencies(int levelFrom, - const std::string& currDepend, - bool isEnd, - const std::vector& allDepends) - { - if (levelFrom == 100) - { - Checks::exit_with_message(VCPKG_LINE_INFO, "Recursion depth exceeded."); - } - auto currPos = std::find_if( - allDepends.begin(), allDepends.end(), [&currDepend](const auto& p) { return p.package == currDepend; }); - Checks::check_exit(VCPKG_LINE_INFO, currPos != allDepends.end(), "internal vcpkg error"); - - for (auto i = currPos->dependencies.begin(); i != currPos->dependencies.end(); i++) - { - // Handle the connecting lines and spaces in front - if (levelFrom) - { - for (auto j = 0; j < levelFrom - 1; j++) - { - print2("| "); - } - - if (!isEnd) - print2("| "); - else - print2(" "); - } - - // Handle the current level - print2("+-- ", i->c_str(), "\n"); - // The last element doesn't need additional connecting lines - auto j = i; - RecurseFindDependencies(levelFrom + 1, i->c_str(), ++j == currPos->dependencies.end(), allDepends); - } - } - void DependInfoCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet,