aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src
diff options
context:
space:
mode:
authorRobert Schumacher <roschuma@microsoft.com>2017-12-13 04:48:13 -0800
committerRobert Schumacher <roschuma@microsoft.com>2017-12-13 04:48:13 -0800
commit7a6ffdc75c6634e0df3c158e871426190511a096 (patch)
tree5993bcddb76841caf16aa5c6160b5c8fe89e0b66 /toolsrc/src
parente6b16165e7d69feab3f4841ab702e6072199b9d4 (diff)
downloadvcpkg-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.cpp79
-rw-r--r--toolsrc/src/tests.plan.cpp150
-rw-r--r--toolsrc/src/tests.update.cpp34
-rw-r--r--toolsrc/src/vcpkg/commands.ci.cpp2
-rw-r--r--toolsrc/src/vcpkg/commands.cpp3
-rw-r--r--toolsrc/src/vcpkg/commands.portsdiff.cpp7
-rw-r--r--toolsrc/src/vcpkg/dependencies.cpp391
-rw-r--r--toolsrc/src/vcpkg/help.cpp1
-rw-r--r--toolsrc/src/vcpkg/install.cpp120
-rw-r--r--toolsrc/src/vcpkg/paragraphs.cpp12
-rw-r--r--toolsrc/src/vcpkg/remove.cpp9
-rw-r--r--toolsrc/src/vcpkg/update.cpp40
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);