diff options
| author | Robert Schumacher <roschuma@microsoft.com> | 2017-12-13 04:48:13 -0800 |
|---|---|---|
| committer | Robert Schumacher <roschuma@microsoft.com> | 2017-12-13 04:48:13 -0800 |
| commit | 7a6ffdc75c6634e0df3c158e871426190511a096 (patch) | |
| tree | 5993bcddb76841caf16aa5c6160b5c8fe89e0b66 /toolsrc/src | |
| parent | e6b16165e7d69feab3f4841ab702e6072199b9d4 (diff) | |
| download | vcpkg-7a6ffdc75c6634e0df3c158e871426190511a096.tar.gz vcpkg-7a6ffdc75c6634e0df3c158e871426190511a096.zip | |
Revert "[vcpkg-upgrade] Initial commit of upgrade command."
This reverts commit 803347a0c545687f6e6b8b3594b52d11435491b3.
Diffstat (limited to 'toolsrc/src')
| -rw-r--r-- | toolsrc/src/commands.upgrade.cpp | 79 | ||||
| -rw-r--r-- | toolsrc/src/tests.plan.cpp | 150 | ||||
| -rw-r--r-- | toolsrc/src/tests.update.cpp | 34 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/commands.ci.cpp | 2 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/commands.cpp | 3 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/commands.portsdiff.cpp | 7 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/dependencies.cpp | 391 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/help.cpp | 1 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/install.cpp | 120 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/paragraphs.cpp | 12 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/remove.cpp | 9 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/update.cpp | 40 |
12 files changed, 316 insertions, 532 deletions
diff --git a/toolsrc/src/commands.upgrade.cpp b/toolsrc/src/commands.upgrade.cpp deleted file mode 100644 index 7a3210042..000000000 --- a/toolsrc/src/commands.upgrade.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "pch.h" - -#include <vcpkg/commands.h> -#include <vcpkg/dependencies.h> -#include <vcpkg/help.h> -#include <vcpkg/install.h> -#include <vcpkg/statusparagraphs.h> -#include <vcpkg/update.h> -#include <vcpkg/vcpkglib.h> - -namespace vcpkg::Commands::Upgrade -{ - using Install::KeepGoing; - using Install::to_keep_going; - - static const std::string OPTION_NO_DRY_RUN = "--no-dry-run"; - static const std::string OPTION_KEEP_GOING = "--keep-going"; - - static const std::array<CommandSwitch, 2> INSTALL_SWITCHES = {{ - {OPTION_NO_DRY_RUN, "Actually upgrade"}, - {OPTION_KEEP_GOING, "Continue installing packages on failure"}, - }}; - - const CommandStructure COMMAND_STRUCTURE = { - Help::create_example_string("upgrade --no-dry-run"), - 0, - 0, - {INSTALL_SWITCHES, {}}, - nullptr, - }; - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet&) - { - // input sanitization - const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); - - const bool no_dry_run = Util::Sets::contains(options.switches, OPTION_NO_DRY_RUN); - const KeepGoing keep_going = to_keep_going(Util::Sets::contains(options.switches, OPTION_KEEP_GOING)); - - // create the plan - StatusParagraphs status_db = database_load_check(paths); - - Dependencies::PathsPortFileProvider provider(paths); - Dependencies::PackageGraph graph(provider, status_db); - - auto outdated_packages = Update::find_outdated_packages(provider, status_db); - for (auto&& outdated_package : outdated_packages) - graph.upgrade(outdated_package.spec); - - auto plan = graph.serialize(); - - if (plan.empty()) - { - System::println("All packages are up-to-date."); - Checks::exit_success(VCPKG_LINE_INFO); - } - - Dependencies::print_plan(plan, true); - - if (!no_dry_run) - { - System::println(System::Color::warning, - "If you are sure you want to rebuild the above packages, run this command with the " - "--no-dry-run option."); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - const Install::InstallSummary summary = Install::perform(plan, keep_going, paths, status_db); - - System::println("\nTotal elapsed time: %s\n", summary.total_elapsed_time); - - if (keep_going == KeepGoing::YES) - { - summary.print(); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 781588c91..122a4ffef 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -36,7 +36,7 @@ namespace UnitTest1 std::vector<std::string> vec, const Triplet& triplet = Triplet::X86_WINDOWS) { - const auto& plan = install_action->install_action.value_or_exit(VCPKG_LINE_INFO); + const auto& plan = install_action->install_plan.value_or_exit(VCPKG_LINE_INFO); const auto& feature_list = plan.feature_list; Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); @@ -61,7 +61,7 @@ namespace UnitTest1 std::string pkg_name, const Triplet& triplet = Triplet::X86_WINDOWS) { - const auto& plan = remove_action->remove_action.value_or_exit(VCPKG_LINE_INFO); + const auto& plan = remove_action->remove_plan.value_or_exit(VCPKG_LINE_INFO); Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); Assert::AreEqual(pkg_name.c_str(), plan.spec.name().c_str()); } @@ -98,7 +98,7 @@ namespace UnitTest1 auto spec_b = spec_map.emplace("b", "c"); auto spec_c = spec_map.emplace("c"); - Dependencies::MapPortFileProvider map_port(spec_map.map); + Dependencies::MapPortFile map_port(spec_map.map); auto install_plan = Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); @@ -122,7 +122,7 @@ namespace UnitTest1 auto spec_g = spec_map.emplace("g"); auto spec_h = spec_map.emplace("h"); - Dependencies::MapPortFileProvider map_port(spec_map.map); + Dependencies::MapPortFile map_port(spec_map.map); auto install_plan = Dependencies::create_install_plan( map_port, {spec_a, spec_b, spec_c}, StatusParagraphs(std::move(status_paragraphs))); @@ -162,7 +162,7 @@ namespace UnitTest1 StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(1), install_plan.size()); - auto p = install_plan[0].install_action.get(); + auto p = install_plan[0].install_plan.get(); Assert::IsNotNull(p); Assert::AreEqual("a", p->spec.name().c_str()); Assert::AreEqual(Dependencies::InstallPlanType::ALREADY_INSTALLED, p->plan_type); @@ -183,13 +183,13 @@ namespace UnitTest1 StatusParagraphs(std::move(status_paragraphs))); Assert::AreEqual(size_t(2), install_plan.size()); - auto p = install_plan[0].install_action.get(); + auto p = install_plan[0].install_plan.get(); Assert::IsNotNull(p); Assert::AreEqual("b", p->spec.name().c_str()); Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p->plan_type); Assert::AreEqual(Dependencies::RequestType::AUTO_SELECTED, p->request_type); - auto p2 = install_plan[1].install_action.get(); + auto p2 = install_plan[1].install_plan.get(); Assert::IsNotNull(p2); Assert::AreEqual("a", p2->spec.name().c_str()); Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p2->plan_type); @@ -215,7 +215,7 @@ namespace UnitTest1 auto spec_j = spec_map.emplace("j", "k"); auto spec_k = spec_map.emplace("k"); - Dependencies::MapPortFileProvider map_port(spec_map.map); + Dependencies::MapPortFile map_port(spec_map.map); auto install_plan = Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); @@ -521,138 +521,4 @@ namespace UnitTest1 Assert::AreEqual("expat", remove_plan[2].spec.name().c_str()); } }; - - class UpgradePlanTests : public TestClass<UpgradePlanTests> - { - TEST_METHOD(basic_upgrade_scheme) - { - std::vector<std::unique_ptr<StatusParagraph>> pghs; - pghs.push_back(make_status_pgh("a")); - StatusParagraphs status_db(std::move(pghs)); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a"); - - Dependencies::MapPortFileProvider provider(spec_map.map); - Dependencies::PackageGraph graph(provider, status_db); - - graph.upgrade(spec_a); - - auto plan = graph.serialize(); - - Assert::AreEqual(size_t(2), plan.size()); - Assert::AreEqual("a", plan[0].spec().name().c_str()); - Assert::IsTrue(plan[0].remove_action.has_value()); - Assert::AreEqual("a", plan[1].spec().name().c_str()); - Assert::IsTrue(plan[1].install_action.has_value()); - } - - TEST_METHOD(basic_upgrade_scheme_with_recurse) - { - std::vector<std::unique_ptr<StatusParagraph>> pghs; - pghs.push_back(make_status_pgh("a")); - pghs.push_back(make_status_pgh("b", "a")); - StatusParagraphs status_db(std::move(pghs)); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a"); - spec_map.emplace("b", "a"); - - Dependencies::MapPortFileProvider provider(spec_map.map); - Dependencies::PackageGraph graph(provider, status_db); - - graph.upgrade(spec_a); - - auto plan = graph.serialize(); - - Assert::AreEqual(size_t(4), plan.size()); - Assert::AreEqual("b", plan[0].spec().name().c_str()); - Assert::IsTrue(plan[0].remove_action.has_value()); - - Assert::AreEqual("a", plan[1].spec().name().c_str()); - Assert::IsTrue(plan[1].remove_action.has_value()); - - Assert::AreEqual("a", plan[2].spec().name().c_str()); - Assert::IsTrue(plan[2].install_action.has_value()); - - Assert::AreEqual("b", plan[3].spec().name().c_str()); - Assert::IsTrue(plan[3].install_action.has_value()); - } - - TEST_METHOD(basic_upgrade_scheme_with_bystander) - { - std::vector<std::unique_ptr<StatusParagraph>> pghs; - pghs.push_back(make_status_pgh("a")); - pghs.push_back(make_status_pgh("b")); - StatusParagraphs status_db(std::move(pghs)); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a"); - spec_map.emplace("b", "a"); - - Dependencies::MapPortFileProvider provider(spec_map.map); - Dependencies::PackageGraph graph(provider, status_db); - - graph.upgrade(spec_a); - - auto plan = graph.serialize(); - - Assert::AreEqual(size_t(2), plan.size()); - Assert::AreEqual("a", plan[0].spec().name().c_str()); - Assert::IsTrue(plan[0].remove_action.has_value()); - Assert::AreEqual("a", plan[1].spec().name().c_str()); - Assert::IsTrue(plan[1].install_action.has_value()); - } - - TEST_METHOD(basic_upgrade_scheme_with_new_dep) - { - std::vector<std::unique_ptr<StatusParagraph>> pghs; - pghs.push_back(make_status_pgh("a")); - StatusParagraphs status_db(std::move(pghs)); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a", "b"); - spec_map.emplace("b"); - - Dependencies::MapPortFileProvider provider(spec_map.map); - Dependencies::PackageGraph graph(provider, status_db); - - graph.upgrade(spec_a); - - auto plan = graph.serialize(); - - Assert::AreEqual(size_t(3), plan.size()); - Assert::AreEqual("a", plan[0].spec().name().c_str()); - Assert::IsTrue(plan[0].remove_action.has_value()); - Assert::AreEqual("b", plan[1].spec().name().c_str()); - Assert::IsTrue(plan[1].install_action.has_value()); - Assert::AreEqual("a", plan[2].spec().name().c_str()); - Assert::IsTrue(plan[2].install_action.has_value()); - } - - TEST_METHOD(basic_upgrade_scheme_with_features) - { - std::vector<std::unique_ptr<StatusParagraph>> pghs; - pghs.push_back(make_status_pgh("a")); - pghs.push_back(make_status_feature_pgh("a", "a1")); - StatusParagraphs status_db(std::move(pghs)); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a", "", {{"a1", ""}}); - - Dependencies::MapPortFileProvider provider(spec_map.map); - Dependencies::PackageGraph graph(provider, status_db); - - graph.upgrade(spec_a); - - auto plan = graph.serialize(); - - Assert::AreEqual(size_t(2), plan.size()); - - Assert::AreEqual("a", plan[0].spec().name().c_str()); - Assert::IsTrue(plan[0].remove_action.has_value()); - - features_check(&plan[1], "a", {"core", "a1"}); - } - }; } diff --git a/toolsrc/src/tests.update.cpp b/toolsrc/src/tests.update.cpp index b6e487c17..06ae797f4 100644 --- a/toolsrc/src/tests.update.cpp +++ b/toolsrc/src/tests.update.cpp @@ -9,8 +9,6 @@ using namespace vcpkg::Update; namespace UnitTest1 { - using Pgh = std::vector<std::unordered_map<std::string, std::string>>; - class UpdateTests : public TestClass<UpdateTests> { TEST_METHOD(find_outdated_packages_basic) @@ -21,12 +19,10 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::unordered_map<std::string, SourceControlFile> map; - auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}})); - map.emplace("a", std::move(*scf)); - Dependencies::MapPortFileProvider provider(map); + std::map<std::string, VersionT> port_versions; + port_versions["a"] = VersionT("0"); - auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db), + auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(port_versions, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(1), pkgs.size()); @@ -45,12 +41,10 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::unordered_map<std::string, SourceControlFile> map; - auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}})); - map.emplace("a", std::move(*scf)); - Dependencies::MapPortFileProvider provider(map); + std::map<std::string, VersionT> port_versions; + port_versions["a"] = VersionT("0"); - auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db), + auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(port_versions, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(1), pkgs.size()); @@ -71,12 +65,10 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::unordered_map<std::string, SourceControlFile> map; - auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}})); - map.emplace("a", std::move(*scf)); - Dependencies::MapPortFileProvider provider(map); + std::map<std::string, VersionT> port_versions; + port_versions["a"] = VersionT("0"); - auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db), + auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(port_versions, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(1), pkgs.size()); @@ -92,12 +84,10 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::unordered_map<std::string, SourceControlFile> map; - auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "2"}}})); - map.emplace("a", std::move(*scf)); - Dependencies::MapPortFileProvider provider(map); + std::map<std::string, VersionT> port_versions; + port_versions["a"] = VersionT("2"); - auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db), + auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(port_versions, status_db), &OutdatedPackage::compare_by_name); Assert::AreEqual(size_t(0), pkgs.size()); diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 1a2f9b47f..f2e984bf8 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -27,7 +27,7 @@ namespace vcpkg::Commands::CI const std::vector<PackageSpec> specs = PackageSpec::to_package_specs(ports, triplet); StatusParagraphs status_db = database_load_check(paths); - const auto& paths_port_file = Dependencies::PathsPortFileProvider(paths); + const auto& paths_port_file = Dependencies::PathsPortFile(paths); std::vector<InstallPlanAction> install_plan = Dependencies::create_install_plan(paths_port_file, specs, status_db); diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index ccf6fa729..15b10c7ea 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -13,10 +13,9 @@ namespace vcpkg::Commands Span<const PackageNameAndFunction<CommandTypeA>> get_available_commands_type_a() { static std::vector<PackageNameAndFunction<CommandTypeA>> t = { - {"install", &Install::perform_and_exit}, + PackageNameAndFunction<CommandTypeA>{"install", &Install::perform_and_exit}, {"ci", &CI::perform_and_exit}, {"remove", &Remove::perform_and_exit}, - {"upgrade", &Upgrade::perform_and_exit}, {"build", &Build::Command::perform_and_exit}, {"env", &Env::perform_and_exit}, {"build-external", &BuildExternal::perform_and_exit}, diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp index dba04ce5b..6752715e4 100644 --- a/toolsrc/src/vcpkg/commands.portsdiff.cpp +++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp @@ -98,11 +98,8 @@ namespace vcpkg::Commands::PortsDiff ".vcpkg-root", git_exe.u8string()); System::cmd_execute_clean(cmd); - const auto all_ports = - Paragraphs::load_all_ports(paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); - std::map<std::string, VersionT> names_and_versions; - for (auto&& port : all_ports) - names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version); + const std::map<std::string, VersionT> names_and_versions = Paragraphs::load_all_port_names_and_versions( + paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); fs.remove_all(temp_checkout_path, ec); return names_and_versions; } diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 5148a10f5..0a1f79834 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -65,19 +65,26 @@ namespace vcpkg::Dependencies struct ClusterGraph : Util::MoveOnlyBase { - explicit ClusterGraph(const PortFileProvider& provider) : m_provider(provider) {} + explicit ClusterGraph(std::unordered_map<std::string, const SourceControlFile*>&& ports) + : m_ports(std::move(ports)) + { + } Cluster& get(const PackageSpec& spec) { auto it = m_graph.find(spec); if (it == m_graph.end()) { - // Load on-demand from m_provider - auto maybe_scf = m_provider.get_control_file(spec.name()); - auto& clust = m_graph[spec]; - clust.spec = spec; - if (auto p_scf = maybe_scf.get()) cluster_from_scf(*p_scf, clust); - return clust; + // Load on-demand from m_ports + auto it_ports = m_ports.find(spec.name()); + if (it_ports != m_ports.end()) + { + auto& clust = m_graph[spec]; + clust.spec = spec; + cluster_from_scf(*it_ports->second, clust); + return clust; + } + return m_graph[spec]; } return it->second; } @@ -100,7 +107,7 @@ namespace vcpkg::Dependencies } std::unordered_map<PackageSpec, Cluster> m_graph; - const PortFileProvider& m_provider; + std::unordered_map<std::string, const SourceControlFile*> m_ports; }; std::vector<PackageSpec> AnyParagraph::dependencies(const Triplet& triplet) const @@ -219,12 +226,12 @@ namespace vcpkg::Dependencies const PackageSpec& AnyAction::spec() const { - if (const auto p = install_action.get()) + if (const auto p = install_plan.get()) { return p->spec; } - if (const auto p = remove_action.get()) + if (const auto p = remove_plan.get()) { return p->spec; } @@ -262,20 +269,21 @@ namespace vcpkg::Dependencies return left->spec.name() < right->spec.name(); } - MapPortFileProvider::MapPortFileProvider(const std::unordered_map<std::string, SourceControlFile>& map) : ports(map) - { - } + MapPortFile::MapPortFile(const std::unordered_map<std::string, SourceControlFile>& map) : ports(map) {} - Optional<const SourceControlFile&> MapPortFileProvider::get_control_file(const std::string& spec) const + const SourceControlFile& MapPortFile::get_control_file(const std::string& spec) const { auto scf = ports.find(spec); - if (scf == ports.end()) return nullopt; + if (scf == ports.end()) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } return scf->second; } - PathsPortFileProvider::PathsPortFileProvider(const VcpkgPaths& paths) : ports(paths) {} + PathsPortFile::PathsPortFile(const VcpkgPaths& paths) : ports(paths) {} - Optional<const SourceControlFile&> PathsPortFileProvider::get_control_file(const std::string& spec) const + const SourceControlFile& PathsPortFile::get_control_file(const std::string& spec) const { auto cache_it = cache.find(spec); if (cache_it != cache.end()) @@ -290,34 +298,56 @@ namespace vcpkg::Dependencies auto it = cache.emplace(spec, std::move(*scf->get())); return it.first->second; } - return nullopt; + print_error_message(source_control_file.error()); + Checks::exit_fail(VCPKG_LINE_INFO); } std::vector<InstallPlanAction> create_install_plan(const PortFileProvider& port_file_provider, const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db) { - auto fspecs = Util::fmap(specs, [](const PackageSpec& spec) { return FeatureSpec(spec, ""); }); - auto plan = create_feature_install_plan(port_file_provider, fspecs, status_db); + struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider<PackageSpec, InstallPlanAction> + { + const PortFileProvider& port_file_provider; + const StatusParagraphs& status_db; + const std::unordered_set<PackageSpec>& specs_as_set; - std::vector<InstallPlanAction> ret; - ret.reserve(plan.size()); + InstallAdjacencyProvider(const PortFileProvider& port_file_provider, + const StatusParagraphs& s, + const std::unordered_set<PackageSpec>& specs_as_set) + : port_file_provider(port_file_provider), status_db(s), specs_as_set(specs_as_set) + { + } - for (auto&& action : plan) - { - if (auto p_install = action.install_action.get()) + std::vector<PackageSpec> adjacency_list(const InstallPlanAction& plan) const override { - ret.push_back(std::move(*p_install)); + if (plan.any_paragraph.status_paragraph.get()) return std::vector<PackageSpec>{}; + return plan.any_paragraph.dependencies(plan.spec.triplet()); } - else + + InstallPlanAction load_vertex_data(const PackageSpec& spec) const override { - Checks::exit_with_message(VCPKG_LINE_INFO, - "The installation plan requires feature packages support. Please re-run the " - "command with --featurepackages."); + const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() + ? RequestType::USER_REQUESTED + : RequestType::AUTO_SELECTED; + auto it = status_db.find_installed(spec); + if (it != status_db.end()) return InstallPlanAction{spec, {*it->get(), nullopt, nullopt}, request_type}; + return InstallPlanAction{ + spec, + {nullopt, nullopt, *port_file_provider.get_control_file(spec.name()).core_paragraph}, + request_type}; } - } + }; - return ret; + const std::unordered_set<PackageSpec> specs_as_set(specs.cbegin(), specs.cend()); + std::vector<InstallPlanAction> toposort = + Graphs::topological_sort(specs, InstallAdjacencyProvider{port_file_provider, status_db, specs_as_set}); + Util::erase_remove_if(toposort, [](const InstallPlanAction& plan) { + return plan.request_type == RequestType::AUTO_SELECTED && + plan.plan_type == InstallPlanType::ALREADY_INSTALLED; + }); + + return toposort; } std::vector<RemovePlanAction> create_remove_plan(const std::vector<PackageSpec>& specs, @@ -431,12 +461,11 @@ namespace vcpkg::Dependencies SUCCESS, }; - static MarkPlusResult mark_plus(const std::string& feature, - Cluster& cluster, - ClusterGraph& pkg_to_cluster, - GraphPlan& graph_plan); - - static void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); + MarkPlusResult mark_plus(const std::string& feature, + Cluster& cluster, + ClusterGraph& pkg_to_cluster, + GraphPlan& graph_plan); + void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); MarkPlusResult mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) { @@ -528,80 +557,110 @@ namespace vcpkg::Dependencies } } - std::vector<AnyAction> create_feature_install_plan(const PortFileProvider& provider, - const std::vector<FeatureSpec>& specs, - const StatusParagraphs& status_db) + static ClusterGraph create_feature_install_graph(const std::unordered_map<std::string, SourceControlFile>& map, + const StatusParagraphs& status_db) { - PackageGraph pgraph(provider, status_db); - for (auto&& spec : specs) - pgraph.install(spec); + std::unordered_map<std::string, const SourceControlFile*> ptr_map; + for (auto&& p : map) + ptr_map.emplace(p.first, &p.second); + ClusterGraph graph(std::move(ptr_map)); + + auto installed_ports = get_installed_ports(status_db); - return pgraph.serialize(); + for (auto&& status_paragraph : installed_ports) + { + Cluster& cluster = graph.get(status_paragraph->package.spec); + + cluster.transient_uninstalled = false; + + cluster.status_paragraphs.emplace_back(status_paragraph); + + auto& status_paragraph_feature = status_paragraph->package.feature; + // In this case, empty string indicates the "core" paragraph for a package. + if (status_paragraph_feature.empty()) + { + cluster.original_features.insert("core"); + } + else + { + cluster.original_features.insert(status_paragraph_feature); + } + } + + for (auto&& status_paragraph : installed_ports) + { + auto& spec = status_paragraph->package.spec; + auto& status_paragraph_feature = status_paragraph->package.feature; + auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, + status_paragraph->package.spec.triplet()); + + for (auto&& dependency : reverse_edges) + { + auto& dep_cluster = graph.get(dependency.spec()); + + auto depends_name = dependency.feature(); + if (depends_name.empty()) depends_name = "core"; + + auto& target_node = dep_cluster.edges[depends_name]; + target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); + } + } + return graph; } std::vector<AnyAction> create_feature_install_plan(const std::unordered_map<std::string, SourceControlFile>& map, const std::vector<FeatureSpec>& specs, const StatusParagraphs& status_db) { - MapPortFileProvider provider(map); - return create_feature_install_plan(provider, specs, status_db); - } + ClusterGraph graph = create_feature_install_graph(map, status_db); - void PackageGraph::install(const FeatureSpec& spec) - { - Cluster& spec_cluster = m_graph->get(spec.spec()); - spec_cluster.request_type = RequestType::USER_REQUESTED; - if (spec.feature() == "*") + GraphPlan graph_plan; + for (auto&& spec : specs) { - if (auto p_scf = spec_cluster.source_control_file.value_or(nullptr)) + Cluster& spec_cluster = graph.get(spec.spec()); + spec_cluster.request_type = RequestType::USER_REQUESTED; + if (spec.feature() == "*") { - for (auto&& feature : p_scf->feature_paragraphs) + if (auto p_scf = spec_cluster.source_control_file.value_or(nullptr)) { - auto res = mark_plus(feature->name, spec_cluster, *m_graph, *m_graph_plan); + for (auto&& feature : p_scf->feature_paragraphs) + { + auto res = mark_plus(feature->name, spec_cluster, graph, graph_plan); + + Checks::check_exit(VCPKG_LINE_INFO, + res == MarkPlusResult::SUCCESS, + "Error: Unable to locate feature %s", + spec); + } + + auto res = mark_plus("core", spec_cluster, graph, graph_plan); Checks::check_exit( VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); } - - auto res = mark_plus("core", spec_cluster, *m_graph, *m_graph_plan); - - Checks::check_exit( - VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); + else + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "Error: Unable to handle '*' because can't find CONTROL for %s", spec.spec()); + } } else { - Checks::exit_with_message( - VCPKG_LINE_INFO, "Error: Unable to handle '*' because can't find CONTROL for %s", spec.spec()); + auto res = mark_plus(spec.feature(), spec_cluster, graph, graph_plan); + + Checks::check_exit( + VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); } - } - else - { - auto res = mark_plus(spec.feature(), spec_cluster, *m_graph, *m_graph_plan); - Checks::check_exit( - VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); + graph_plan.install_graph.add_vertex(ClusterPtr{&spec_cluster}); } - m_graph_plan->install_graph.add_vertex(ClusterPtr{&spec_cluster}); - } - - void PackageGraph::upgrade(const PackageSpec& spec) - { - Cluster& spec_cluster = m_graph->get(spec); - spec_cluster.request_type = RequestType::USER_REQUESTED; - - mark_minus(spec_cluster, *m_graph, *m_graph_plan); - } - - std::vector<AnyAction> PackageGraph::serialize() const - { - Graphs::GraphAdjacencyProvider<ClusterPtr> adjacency_remove_graph(m_graph_plan->remove_graph.adjacency_list()); - auto remove_vertex_list = m_graph_plan->remove_graph.vertex_list(); + Graphs::GraphAdjacencyProvider<ClusterPtr> adjacency_remove_graph(graph_plan.remove_graph.adjacency_list()); + auto remove_vertex_list = graph_plan.remove_graph.vertex_list(); auto remove_toposort = Graphs::topological_sort(remove_vertex_list, adjacency_remove_graph); - Graphs::GraphAdjacencyProvider<ClusterPtr> adjacency_install_graph( - m_graph_plan->install_graph.adjacency_list()); - auto insert_vertex_list = m_graph_plan->install_graph.vertex_list(); + Graphs::GraphAdjacencyProvider<ClusterPtr> adjacency_install_graph(graph_plan.install_graph.adjacency_list()); + auto insert_vertex_list = graph_plan.install_graph.vertex_list(); auto insert_toposort = Graphs::topological_sort(insert_vertex_list, adjacency_install_graph); std::vector<AnyAction> plan; @@ -646,162 +705,4 @@ namespace vcpkg::Dependencies return plan; } - - static std::unique_ptr<ClusterGraph> create_feature_install_graph(const PortFileProvider& map, - const StatusParagraphs& status_db) - { - std::unique_ptr<ClusterGraph> graph = std::make_unique<ClusterGraph>(map); - - auto installed_ports = get_installed_ports(status_db); - - for (auto&& status_paragraph : installed_ports) - { - Cluster& cluster = graph->get(status_paragraph->package.spec); - - cluster.transient_uninstalled = false; - - cluster.status_paragraphs.emplace_back(status_paragraph); - - auto& status_paragraph_feature = status_paragraph->package.feature; - // In this case, empty string indicates the "core" paragraph for a package. - if (status_paragraph_feature.empty()) - { - cluster.original_features.insert("core"); - } - else - { - cluster.original_features.insert(status_paragraph_feature); - } - } - - // Populate the graph with "remove edges", which are the reverse of the Build-Depends edges. - for (auto&& status_paragraph : installed_ports) - { - auto& spec = status_paragraph->package.spec; - auto& status_paragraph_feature = status_paragraph->package.feature; - auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, - status_paragraph->package.spec.triplet()); - - for (auto&& dependency : reverse_edges) - { - auto& dep_cluster = graph->get(dependency.spec()); - - auto depends_name = dependency.feature(); - if (depends_name.empty()) depends_name = "core"; - - auto& target_node = dep_cluster.edges[depends_name]; - target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); - } - } - return graph; - } - - PackageGraph::PackageGraph(const PortFileProvider& provider, const StatusParagraphs& status_db) - : m_graph(create_feature_install_graph(provider, status_db)), m_graph_plan(std::make_unique<GraphPlan>()) - { - } - - PackageGraph::~PackageGraph() {} - - void print_plan(const std::vector<AnyAction>& action_plan, const bool is_recursive) - { - std::vector<const RemovePlanAction*> remove_plans; - std::vector<const InstallPlanAction*> rebuilt_plans; - std::vector<const InstallPlanAction*> only_install_plans; - std::vector<const InstallPlanAction*> new_plans; - std::vector<const InstallPlanAction*> already_installed_plans; - std::vector<const InstallPlanAction*> excluded; - - const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { - if (auto iplan = package.install_action.get()) - return iplan->request_type != RequestType::USER_REQUESTED; - else - return false; - }) != action_plan.cend(); - - for (auto&& action : action_plan) - { - if (auto install_action = action.install_action.get()) - { - // remove plans are guaranteed to come before install plans, so we know the plan will be contained if at - // all. - auto it = Util::find_if( - remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); - if (it != remove_plans.end()) - { - rebuilt_plans.emplace_back(install_action); - } - else - { - switch (install_action->plan_type) - { - case InstallPlanType::INSTALL: only_install_plans.emplace_back(install_action); break; - case InstallPlanType::ALREADY_INSTALLED: - if (install_action->request_type == RequestType::USER_REQUESTED) - already_installed_plans.emplace_back(install_action); - break; - case InstallPlanType::BUILD_AND_INSTALL: new_plans.emplace_back(install_action); break; - case InstallPlanType::EXCLUDED: excluded.emplace_back(install_action); break; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - } - else if (auto remove_action = action.remove_action.get()) - { - remove_plans.emplace_back(remove_action); - } - } - - std::sort(remove_plans.begin(), remove_plans.end(), &RemovePlanAction::compare_by_name); - std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(excluded.begin(), excluded.end(), &InstallPlanAction::compare_by_name); - - static auto actions_to_output_string = [](const std::vector<const InstallPlanAction*>& v) { - return Strings::join("\n", v, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname(), p->build_options); - }); - }; - - if (excluded.size() > 0) - { - System::println("The following packages are excluded:\n%s", actions_to_output_string(excluded)); - } - - if (already_installed_plans.size() > 0) - { - System::println("The following packages are already installed:\n%s", - actions_to_output_string(already_installed_plans)); - } - - if (rebuilt_plans.size() > 0) - { - System::println("The following packages will be rebuilt:\n%s", actions_to_output_string(rebuilt_plans)); - } - - if (new_plans.size() > 0) - { - System::println("The following packages will be built and installed:\n%s", - actions_to_output_string(new_plans)); - } - - if (only_install_plans.size() > 0) - { - System::println("The following packages will be directly installed:\n%s", - actions_to_output_string(only_install_plans)); - } - - if (has_non_user_requested_packages) - System::println("Additional packages (*) will be modified to complete this operation."); - - if (remove_plans.size() > 0 && !is_recursive) - { - System::println(System::Color::warning, - "If you are sure you want to rebuild the above packages, run the command with the " - "--recurse option"); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } } diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp index b7d355742..c83f0277b 100644 --- a/toolsrc/src/vcpkg/help.cpp +++ b/toolsrc/src/vcpkg/help.cpp @@ -85,7 +85,6 @@ namespace vcpkg::Help " vcpkg remove --outdated Uninstall all out-of-date packages\n" " vcpkg list List installed packages\n" " vcpkg update Display list of packages for updating\n" - " vcpkg upgrade Rebuild all outdated packages\n" " vcpkg hash <file> [alg] Hash a file by specific algorithm, default SHA512\n" " vcpkg help topics Display the list of help topics\n" " vcpkg help <topic> Display help for a specific topic\n" diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 08cfc2e73..76dc7a527 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -348,6 +348,108 @@ namespace vcpkg::Install Checks::unreachable(VCPKG_LINE_INFO); } + static void print_plan(const std::vector<AnyAction>& action_plan, const bool is_recursive) + { + std::vector<const RemovePlanAction*> remove_plans; + std::vector<const InstallPlanAction*> rebuilt_plans; + std::vector<const InstallPlanAction*> only_install_plans; + std::vector<const InstallPlanAction*> new_plans; + std::vector<const InstallPlanAction*> already_installed_plans; + std::vector<const InstallPlanAction*> excluded; + + const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { + if (auto iplan = package.install_plan.get()) + return iplan->request_type != RequestType::USER_REQUESTED; + else + return false; + }) != action_plan.cend(); + + for (auto&& action : action_plan) + { + if (auto install_action = action.install_plan.get()) + { + // remove plans are guaranteed to come before install plans, so we know the plan will be contained if at + // all. + auto it = Util::find_if( + remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); + if (it != remove_plans.end()) + { + rebuilt_plans.emplace_back(install_action); + } + else + { + switch (install_action->plan_type) + { + case InstallPlanType::INSTALL: only_install_plans.emplace_back(install_action); break; + case InstallPlanType::ALREADY_INSTALLED: + if (install_action->request_type == RequestType::USER_REQUESTED) + already_installed_plans.emplace_back(install_action); + break; + case InstallPlanType::BUILD_AND_INSTALL: new_plans.emplace_back(install_action); break; + case InstallPlanType::EXCLUDED: excluded.emplace_back(install_action); break; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + } + else if (auto remove_action = action.remove_plan.get()) + { + remove_plans.emplace_back(remove_action); + } + } + + std::sort(remove_plans.begin(), remove_plans.end(), &RemovePlanAction::compare_by_name); + std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(excluded.begin(), excluded.end(), &InstallPlanAction::compare_by_name); + + static auto actions_to_output_string = [](const std::vector<const InstallPlanAction*>& v) { + return Strings::join("\n", v, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname(), p->build_options); + }); + }; + + if (excluded.size() > 0) + { + System::println("The following packages are excluded:\n%s", actions_to_output_string(excluded)); + } + + if (already_installed_plans.size() > 0) + { + System::println("The following packages are already installed:\n%s", + actions_to_output_string(already_installed_plans)); + } + + if (rebuilt_plans.size() > 0) + { + System::println("The following packages will be rebuilt:\n%s", actions_to_output_string(rebuilt_plans)); + } + + if (new_plans.size() > 0) + { + System::println("The following packages will be built and installed:\n%s", + actions_to_output_string(new_plans)); + } + + if (only_install_plans.size() > 0) + { + System::println("The following packages will be directly installed:\n%s", + actions_to_output_string(only_install_plans)); + } + + if (has_non_user_requested_packages) + System::println("Additional packages (*) will be installed to complete this operation."); + + if (remove_plans.size() > 0 && !is_recursive) + { + System::println(System::Color::warning, + "If you are sure you want to rebuild the above packages, run the command with the " + "--recurse option"); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + void InstallSummary::print() const { System::println("RESULTS"); @@ -397,7 +499,7 @@ namespace vcpkg::Install results.emplace_back(spec, &action); - if (const auto install_action = action.install_action.get()) + if (const auto install_action = action.install_plan.get()) { auto result = perform_install_plan_action(paths, *install_action, status_db); @@ -409,7 +511,7 @@ namespace vcpkg::Install results.back().build_result = std::move(result); } - else if (const auto remove_action = action.remove_action.get()) + else if (const auto remove_action = action.remove_plan.get()) { Checks::check_exit(VCPKG_LINE_INFO, GlobalState::feature_packages); Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, status_db); @@ -588,7 +690,7 @@ namespace vcpkg::Install } else { - Dependencies::PathsPortFileProvider paths_port_file(paths); + Dependencies::PathsPortFile paths_port_file(paths); auto install_plan = Dependencies::create_install_plan( paths_port_file, Util::fmap(specs, [](auto&& spec) { return spec.package_spec; }), status_db); @@ -598,7 +700,7 @@ namespace vcpkg::Install for (auto&& action : action_plan) { - if (auto p_install = action.install_action.get()) + if (auto p_install = action.install_plan.get()) { p_install->build_options = install_plan_options; if (p_install->request_type != RequestType::USER_REQUESTED) @@ -611,16 +713,16 @@ namespace vcpkg::Install // log the plan const std::string specs_string = Strings::join(",", action_plan, [](const AnyAction& action) { - if (auto iaction = action.install_action.get()) + if (auto iaction = action.install_plan.get()) return iaction->spec.to_string(); - else if (auto raction = action.remove_action.get()) + else if (auto raction = action.remove_plan.get()) return "R$" + raction->spec.to_string(); Checks::unreachable(VCPKG_LINE_INFO); }); Metrics::g_metrics.lock()->track_property("installplan", specs_string); - Dependencies::print_plan(action_plan, is_recursive); + print_plan(action_plan, is_recursive); if (dry_run) { @@ -650,7 +752,7 @@ namespace vcpkg::Install for (auto&& result : summary.results) { if (!result.action) continue; - if (auto p_install_action = result.action->install_action.get()) + if (auto p_install_action = result.action->install_plan.get()) { if (p_install_action->request_type != RequestType::USER_REQUESTED) continue; auto bpgh = result.get_binary_paragraph(); @@ -671,7 +773,7 @@ namespace vcpkg::Install { if (build_result.binary_control_file) return &build_result.binary_control_file->core_paragraph; if (action) - if (auto p_install_plan = action->install_action.get()) + if (auto p_install_plan = action->install_plan.get()) { if (auto p_bcf = p_install_plan->any_paragraph.binary_control_file.get()) return &p_bcf->core_paragraph; diff --git a/toolsrc/src/vcpkg/paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp index b66d53994..b93de190c 100644 --- a/toolsrc/src/vcpkg/paragraphs.cpp +++ b/toolsrc/src/vcpkg/paragraphs.cpp @@ -289,4 +289,16 @@ namespace vcpkg::Paragraphs } return std::move(results.paragraphs); } + + std::map<std::string, VersionT> load_all_port_names_and_versions(const Files::Filesystem& fs, + const fs::path& ports_dir) + { + auto all_ports = load_all_ports(fs, ports_dir); + + std::map<std::string, VersionT> names_and_versions; + for (auto&& port : all_ports) + names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version); + + return names_and_versions; + } } diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 4079d60c1..8ae0bc881 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -207,11 +207,10 @@ namespace vcpkg::Remove System::println(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'"); Checks::exit_fail(VCPKG_LINE_INFO); } - - Dependencies::PathsPortFileProvider provider(paths); - - specs = Util::fmap(Update::find_outdated_packages(provider, status_db), - [](auto&& outdated) { return outdated.spec; }); + specs = Util::fmap( + Update::find_outdated_packages( + Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports), status_db), + [](auto&& outdated) { return outdated.spec; }); if (specs.empty()) { diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp index d6c5614ed..29baef91e 100644 --- a/toolsrc/src/vcpkg/update.cpp +++ b/toolsrc/src/vcpkg/update.cpp @@ -14,7 +14,7 @@ namespace vcpkg::Update return left.spec.name() < right.spec.name(); } - std::vector<OutdatedPackage> find_outdated_packages(const Dependencies::PortFileProvider& provider, + std::vector<OutdatedPackage> find_outdated_packages(const std::map<std::string, VersionT>& src_names_to_versions, const StatusParagraphs& status_db) { const std::vector<StatusParagraph*> installed_packages = get_installed_ports(status_db); @@ -24,23 +24,19 @@ namespace vcpkg::Update { if (!pgh->package.feature.empty()) { - // Skip feature paragraphs; only consider master paragraphs for needing updates. + // Skip feature packages; only consider master packages for needing updates. continue; } - auto maybe_scf = provider.get_control_file(pgh->package.spec.name()); - if (auto p_scf = maybe_scf.get()) + const auto it = src_names_to_versions.find(pgh->package.spec.name()); + if (it == src_names_to_versions.end()) { - auto&& port_version = p_scf->core_paragraph->version; - auto&& installed_version = pgh->package.version; - if (installed_version != port_version) - { - output.push_back({pgh->package.spec, VersionDiff(installed_version, port_version)}); - } + // Package was not installed from portfile + continue; } - else + if (it->second != pgh->package.version) { - // No portfile available + output.push_back({pgh->package.spec, VersionDiff(pgh->package.version, it->second)}); } } @@ -62,10 +58,10 @@ namespace vcpkg::Update const StatusParagraphs status_db = database_load_check(paths); - Dependencies::PathsPortFileProvider provider(paths); - - const auto outdated_packages = SortedVector<OutdatedPackage>(find_outdated_packages(provider, status_db), - &OutdatedPackage::compare_by_name); + const auto outdated_packages = SortedVector<OutdatedPackage>( + find_outdated_packages(Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports), + status_db), + &OutdatedPackage::compare_by_name); if (outdated_packages.empty()) { @@ -73,17 +69,19 @@ namespace vcpkg::Update } else { + std::string install_line; System::println("The following packages differ from their port versions:"); for (auto&& package : outdated_packages) { + install_line += package.spec.to_string(); + install_line += " "; System::println(" %-32s %s", package.spec, package.version_diff.to_string()); } System::println("\n" - "To update these packages and all dependencies, run\n" - " .\\vcpkg upgrade\n" - "\n" - "To only remove outdated packages, run\n" - " .\\vcpkg remove --outdated\n"); + "To update these packages, run\n" + " .\\vcpkg remove --outdated\n" + " .\\vcpkg install " + + install_line); } Checks::exit_success(VCPKG_LINE_INFO); |
