aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src
diff options
context:
space:
mode:
authorRobert Schumacher <roschuma@microsoft.com>2017-04-12 22:57:23 -0700
committerRobert Schumacher <roschuma@microsoft.com>2017-04-12 22:57:23 -0700
commitc3b54a2e7bd0a07068b6a12c29b00b8f57bdb3f1 (patch)
tree65f0fbf52220f8f5225da13a69afa415c0c0ff09 /toolsrc/src
parent7069fbbebc750a7c8a64adc8c30269527cbec9bd (diff)
parent3739e8e0b998b14c0f320c21618057e50698c51d (diff)
downloadvcpkg-c3b54a2e7bd0a07068b6a12c29b00b8f57bdb3f1.tar.gz
vcpkg-c3b54a2e7bd0a07068b6a12c29b00b8f57bdb3f1.zip
Merge from master
Diffstat (limited to 'toolsrc/src')
-rw-r--r--toolsrc/src/PackageSpec.cpp5
-rw-r--r--toolsrc/src/StatusParagraphs.cpp2
-rw-r--r--toolsrc/src/commands_build.cpp17
-rw-r--r--toolsrc/src/commands_ci.cpp12
-rw-r--r--toolsrc/src/commands_hash.cpp3
-rw-r--r--toolsrc/src/commands_install.cpp36
-rw-r--r--toolsrc/src/commands_integrate.cpp9
-rw-r--r--toolsrc/src/commands_remove.cpp28
-rw-r--r--toolsrc/src/vcpkg_Dependencies.cpp260
-rw-r--r--toolsrc/src/vcpkg_Strings.cpp9
-rw-r--r--toolsrc/src/vcpkglib.cpp11
11 files changed, 211 insertions, 181 deletions
diff --git a/toolsrc/src/PackageSpec.cpp b/toolsrc/src/PackageSpec.cpp
index bf1c7380c..2a7f4506c 100644
--- a/toolsrc/src/PackageSpec.cpp
+++ b/toolsrc/src/PackageSpec.cpp
@@ -64,4 +64,9 @@ namespace vcpkg
{
return left.name() == right.name() && left.triplet() == right.triplet();
}
+
+ bool operator!=(const PackageSpec& left, const PackageSpec& right)
+ {
+ return !(left == right);
+ }
}
diff --git a/toolsrc/src/StatusParagraphs.cpp b/toolsrc/src/StatusParagraphs.cpp
index 132b7d5d4..f41630132 100644
--- a/toolsrc/src/StatusParagraphs.cpp
+++ b/toolsrc/src/StatusParagraphs.cpp
@@ -2,8 +2,6 @@
#include "StatusParagraphs.h"
#include "vcpkg_Checks.h"
#include <algorithm>
-#include <algorithm>
-#include <algorithm>
namespace vcpkg
{
diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp
index 8d91ce813..9110e1fd0 100644
--- a/toolsrc/src/commands_build.cpp
+++ b/toolsrc/src/commands_build.cpp
@@ -10,10 +10,11 @@
#include "metrics.h"
#include "vcpkg_Enums.h"
#include "Paragraphs.h"
+#include "vcpkg_Util.h"
namespace vcpkg::Commands::Build
{
- using Dependencies::PackageSpecWithInstallPlan;
+ using Dependencies::InstallPlanAction;
using Dependencies::InstallPlanType;
static const std::string OPTION_CHECKS_ONLY = "--checks-only";
@@ -148,19 +149,17 @@ namespace vcpkg::Commands::Build
const BuildResult result = build_package(spgh, spec, paths, paths.port_dir(spec), status_db);
if (result == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES)
{
- std::vector<PackageSpecWithInstallPlan> unmet_dependencies = Dependencies::create_install_plan(paths, { spec }, status_db);
- unmet_dependencies.erase(
- std::remove_if(unmet_dependencies.begin(), unmet_dependencies.end(), [&spec](const PackageSpecWithInstallPlan& p)
- {
- return (p.spec == spec) || (p.plan.plan_type == InstallPlanType::ALREADY_INSTALLED);
- }),
- unmet_dependencies.end());
+ std::vector<InstallPlanAction> unmet_dependencies = Dependencies::create_install_plan(paths, { spec }, status_db);
+ Util::keep_if(unmet_dependencies, [&spec](const InstallPlanAction& p)
+ {
+ return (p.spec != spec) && (p.plan_type != InstallPlanType::ALREADY_INSTALLED);
+ });
Checks::check_exit(VCPKG_LINE_INFO, !unmet_dependencies.empty());
System::println(System::Color::error, "The build command requires all dependencies to be already installed.");
System::println("The following dependencies are missing:");
System::println("");
- for (const PackageSpecWithInstallPlan& p : unmet_dependencies)
+ for (const InstallPlanAction& p : unmet_dependencies)
{
System::println(" %s", p.spec);
}
diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp
index d4b2865a6..a40a7ed32 100644
--- a/toolsrc/src/commands_ci.cpp
+++ b/toolsrc/src/commands_ci.cpp
@@ -10,7 +10,7 @@
namespace vcpkg::Commands::CI
{
- using Dependencies::PackageSpecWithInstallPlan;
+ using Dependencies::InstallPlanAction;
using Dependencies::InstallPlanType;
using Build::BuildResult;
@@ -36,7 +36,7 @@ namespace vcpkg::Commands::CI
const std::vector<PackageSpec> specs = load_all_package_specs(paths.get_filesystem(), paths.ports, triplet);
StatusParagraphs status_db = database_load_check(paths);
- const std::vector<PackageSpecWithInstallPlan> install_plan = Dependencies::create_install_plan(paths, specs, status_db);
+ const std::vector<InstallPlanAction> install_plan = Dependencies::create_install_plan(paths, specs, status_db);
Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty");
std::vector<BuildResult> results;
@@ -44,7 +44,7 @@ namespace vcpkg::Commands::CI
const ElapsedTime timer = ElapsedTime::create_started();
size_t counter = 0;
const size_t package_count = install_plan.size();
- for (const PackageSpecWithInstallPlan& action : install_plan)
+ for (const InstallPlanAction& action : install_plan)
{
const ElapsedTime build_timer = ElapsedTime::create_started();
counter++;
@@ -56,7 +56,7 @@ namespace vcpkg::Commands::CI
try
{
- switch (action.plan.plan_type)
+ switch (action.plan_type)
{
case InstallPlanType::ALREADY_INSTALLED:
results.back() = BuildResult::SUCCEEDED;
@@ -65,7 +65,7 @@ namespace vcpkg::Commands::CI
case InstallPlanType::BUILD_AND_INSTALL:
{
System::println("Building package %s... ", display_name);
- const BuildResult result = Commands::Build::build_package(action.plan.source_pgh.value_or_exit(VCPKG_LINE_INFO),
+ const BuildResult result = Commands::Build::build_package(action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO),
action.spec,
paths,
paths.port_dir(action.spec),
@@ -88,7 +88,7 @@ namespace vcpkg::Commands::CI
case InstallPlanType::INSTALL:
results.back() = BuildResult::SUCCEEDED;
System::println("Installing package %s... ", display_name);
- Install::install_package(paths, action.plan.binary_pgh.value_or_exit(VCPKG_LINE_INFO), &status_db);
+ Install::install_package(paths, action.any_paragraph.binary_paragraph.value_or_exit(VCPKG_LINE_INFO), &status_db);
System::println(System::Color::success, "Installing package %s... done", display_name);
break;
default:
diff --git a/toolsrc/src/commands_hash.cpp b/toolsrc/src/commands_hash.cpp
index 2ffa3a9aa..a9024d9e7 100644
--- a/toolsrc/src/commands_hash.cpp
+++ b/toolsrc/src/commands_hash.cpp
@@ -1,6 +1,7 @@
#include "pch.h"
#include "vcpkg_Commands.h"
#include "vcpkg_System.h"
+#include "vcpkg_Util.h"
namespace vcpkg::Commands::Hash
{
@@ -20,7 +21,7 @@ namespace vcpkg::Commands::Hash
Checks::check_exit(VCPKG_LINE_INFO, end != std::string::npos, "Unexpected output format from command: %s", Strings::utf16_to_utf8(cmd_line));
auto hash = output.substr(start, end - start);
- hash.erase(std::remove_if(hash.begin(), hash.end(), isspace), hash.end());
+ Util::keep_if(hash, [](char c) {return !isspace(c); });
System::println(hash);
}
diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp
index 15aab4845..32460b807 100644
--- a/toolsrc/src/commands_install.cpp
+++ b/toolsrc/src/commands_install.cpp
@@ -11,7 +11,7 @@
namespace vcpkg::Commands::Install
{
- using Dependencies::PackageSpecWithInstallPlan;
+ using Dependencies::InstallPlanAction;
using Dependencies::RequestType;
using Dependencies::InstallPlanType;
@@ -140,15 +140,15 @@ namespace vcpkg::Commands::Install
return SortedVector<std::string>(std::move(installed_files));
}
- static void print_plan(const std::vector<PackageSpecWithInstallPlan>& plan)
+ static void print_plan(const std::vector<InstallPlanAction>& plan)
{
- std::vector<const PackageSpecWithInstallPlan*> already_installed;
- std::vector<const PackageSpecWithInstallPlan*> build_and_install;
- std::vector<const PackageSpecWithInstallPlan*> install;
+ std::vector<const InstallPlanAction*> already_installed;
+ std::vector<const InstallPlanAction*> build_and_install;
+ std::vector<const InstallPlanAction*> install;
- for (const PackageSpecWithInstallPlan& i : plan)
+ for (const InstallPlanAction& i : plan)
{
- switch (i.plan.plan_type)
+ switch (i.plan_type)
{
case InstallPlanType::ALREADY_INSTALLED:
already_installed.push_back(&i);
@@ -164,23 +164,23 @@ namespace vcpkg::Commands::Install
}
}
- auto print_lambda = [](const PackageSpecWithInstallPlan* p) { return to_output_string(p->plan.request_type, p->spec.to_string()); };
+ auto print_lambda = [](const InstallPlanAction* p) { return Dependencies::to_output_string(p->request_type, p->spec.to_string()); };
if (!already_installed.empty())
{
- std::sort(already_installed.begin(), already_installed.end(), &PackageSpecWithInstallPlan::compare_by_name);
+ std::sort(already_installed.begin(), already_installed.end(), &InstallPlanAction::compare_by_name);
System::println("The following packages are already installed:\n%s", Strings::join("\n", already_installed, print_lambda));
}
if (!build_and_install.empty())
{
- std::sort(build_and_install.begin(), build_and_install.end(), &PackageSpecWithInstallPlan::compare_by_name);
+ std::sort(build_and_install.begin(), build_and_install.end(), &InstallPlanAction::compare_by_name);
System::println("The following packages will be built and installed:\n%s", Strings::join("\n", build_and_install, print_lambda));
}
if (!install.empty())
{
- std::sort(install.begin(), install.end(), &PackageSpecWithInstallPlan::compare_by_name);
+ std::sort(install.begin(), install.end(), &InstallPlanAction::compare_by_name);
System::println("The following packages will be installed:\n%s", Strings::join("\n", install, print_lambda));
}
}
@@ -252,7 +252,7 @@ namespace vcpkg::Commands::Install
// create the plan
StatusParagraphs status_db = database_load_check(paths);
- std::vector<PackageSpecWithInstallPlan> install_plan = Dependencies::create_install_plan(paths, specs, status_db);
+ std::vector<InstallPlanAction> install_plan = Dependencies::create_install_plan(paths, specs, status_db);
Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty");
// log the plan
@@ -266,9 +266,9 @@ namespace vcpkg::Commands::Install
print_plan(install_plan);
- const bool has_non_user_requested_packages = std::find_if(install_plan.cbegin(), install_plan.cend(), [](const PackageSpecWithInstallPlan& package)-> bool
+ const bool has_non_user_requested_packages = std::find_if(install_plan.cbegin(), install_plan.cend(), [](const InstallPlanAction& package)-> bool
{
- return package.plan.request_type != RequestType::USER_REQUESTED;
+ return package.request_type != RequestType::USER_REQUESTED;
}) != install_plan.cend();
if (has_non_user_requested_packages)
@@ -282,13 +282,13 @@ namespace vcpkg::Commands::Install
}
// execute the plan
- for (const PackageSpecWithInstallPlan& action : install_plan)
+ for (const InstallPlanAction& action : install_plan)
{
const std::string display_name = action.spec.to_string();
try
{
- switch (action.plan.plan_type)
+ switch (action.plan_type)
{
case InstallPlanType::ALREADY_INSTALLED:
System::println(System::Color::success, "Package %s is already installed", display_name);
@@ -296,7 +296,7 @@ namespace vcpkg::Commands::Install
case InstallPlanType::BUILD_AND_INSTALL:
{
System::println("Building package %s... ", display_name);
- const Build::BuildResult result = Commands::Build::build_package(action.plan.source_pgh.value_or_exit(VCPKG_LINE_INFO),
+ const Build::BuildResult result = Commands::Build::build_package(action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO),
action.spec,
paths,
paths.port_dir(action.spec),
@@ -317,7 +317,7 @@ namespace vcpkg::Commands::Install
}
case InstallPlanType::INSTALL:
System::println("Installing package %s... ", display_name);
- install_package(paths, action.plan.binary_pgh.value_or_exit(VCPKG_LINE_INFO), &status_db);
+ install_package(paths, action.any_paragraph.binary_paragraph.value_or_exit(VCPKG_LINE_INFO), &status_db);
System::println(System::Color::success, "Installing package %s... done", display_name);
break;
case InstallPlanType::UNKNOWN:
diff --git a/toolsrc/src/commands_integrate.cpp b/toolsrc/src/commands_integrate.cpp
index 8569fdd79..819c29082 100644
--- a/toolsrc/src/commands_integrate.cpp
+++ b/toolsrc/src/commands_integrate.cpp
@@ -3,6 +3,7 @@
#include "vcpkg_Checks.h"
#include "vcpkg_System.h"
#include "vcpkg_Files.h"
+#include "vcpkg_Util.h"
namespace vcpkg::Commands::Integrate
{
@@ -66,10 +67,10 @@ namespace vcpkg::Commands::Integrate
dir_id.erase(1, 1); // Erasing the ":"
// NuGet id cannot have invalid characters. We will only use alphanumeric and dot.
- dir_id.erase(std::remove_if(dir_id.begin(), dir_id.end(), [](char c)
- {
- return !isalnum(c) && (c != '.');
- }), dir_id.end());
+ Util::keep_if(dir_id, [](char c)
+ {
+ return isalnum(c) || (c == '.');
+ });
const std::string nuget_id = "vcpkg." + dir_id;
return nuget_id;
diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/commands_remove.cpp
index 9ce4adb75..a61435b5d 100644
--- a/toolsrc/src/commands_remove.cpp
+++ b/toolsrc/src/commands_remove.cpp
@@ -8,7 +8,7 @@
namespace vcpkg::Commands::Remove
{
- using Dependencies::PackageSpecWithRemovePlan;
+ using Dependencies::RemovePlanAction;
using Dependencies::RemovePlanType;
using Dependencies::RequestType;
using Update::OutdatedPackage;
@@ -101,14 +101,14 @@ namespace vcpkg::Commands::Remove
write_update(paths, pkg);
}
- static void print_plan(const std::vector<PackageSpecWithRemovePlan>& plan)
+ static void print_plan(const std::vector<RemovePlanAction>& plan)
{
- std::vector<const PackageSpecWithRemovePlan*> not_installed;
- std::vector<const PackageSpecWithRemovePlan*> remove;
+ std::vector<const RemovePlanAction*> not_installed;
+ std::vector<const RemovePlanAction*> remove;
- for (const PackageSpecWithRemovePlan& i : plan)
+ for (const RemovePlanAction& i : plan)
{
- switch (i.plan.plan_type)
+ switch (i.plan_type)
{
case RemovePlanType::NOT_INSTALLED:
not_installed.push_back(&i);
@@ -121,17 +121,17 @@ namespace vcpkg::Commands::Remove
}
}
- auto print_lambda = [](const PackageSpecWithRemovePlan* p) { return to_output_string(p->plan.request_type, p->spec.to_string()); };
+ auto print_lambda = [](const RemovePlanAction* p) { return Dependencies::to_output_string(p->request_type, p->spec.to_string()); };
if (!not_installed.empty())
{
- std::sort(not_installed.begin(), not_installed.end(), &PackageSpecWithRemovePlan::compare_by_name);
+ std::sort(not_installed.begin(), not_installed.end(), &RemovePlanAction::compare_by_name);
System::println("The following packages are not installed, so not removed:\n%s", Strings::join("\n", not_installed, print_lambda));
}
if (!remove.empty())
{
- std::sort(remove.begin(), remove.end(), &PackageSpecWithRemovePlan::compare_by_name);
+ std::sort(remove.begin(), remove.end(), &RemovePlanAction::compare_by_name);
System::println("The following packages will be removed:\n%s", Strings::join("\n", remove, print_lambda));
}
}
@@ -172,14 +172,14 @@ namespace vcpkg::Commands::Remove
const bool isRecursive = options.find(OPTION_RECURSE) != options.cend();
const bool dryRun = options.find(OPTION_DRY_RUN) != options.cend();
- const std::vector<PackageSpecWithRemovePlan> remove_plan = Dependencies::create_remove_plan(specs, status_db);
+ const std::vector<RemovePlanAction> remove_plan = Dependencies::create_remove_plan(specs, status_db);
Checks::check_exit(VCPKG_LINE_INFO, !remove_plan.empty(), "Remove plan cannot be empty");
print_plan(remove_plan);
- const bool has_non_user_requested_packages = std::find_if(remove_plan.cbegin(), remove_plan.cend(), [](const PackageSpecWithRemovePlan& package)-> bool
+ const bool has_non_user_requested_packages = std::find_if(remove_plan.cbegin(), remove_plan.cend(), [](const RemovePlanAction& package)-> bool
{
- return package.plan.request_type != RequestType::USER_REQUESTED;
+ return package.request_type != RequestType::USER_REQUESTED;
}) != remove_plan.cend();
if (has_non_user_requested_packages)
@@ -198,11 +198,11 @@ namespace vcpkg::Commands::Remove
Checks::exit_success(VCPKG_LINE_INFO);
}
- for (const PackageSpecWithRemovePlan& action : remove_plan)
+ for (const RemovePlanAction& action : remove_plan)
{
const std::string display_name = action.spec.to_string();
- switch (action.plan.plan_type)
+ switch (action.plan_type)
{
case RemovePlanType::NOT_INSTALLED:
System::println(System::Color::success, "Package %s is not installed", display_name);
diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp
index 3e3f502b5..03e3c2aeb 100644
--- a/toolsrc/src/vcpkg_Dependencies.cpp
+++ b/toolsrc/src/vcpkg_Dependencies.cpp
@@ -5,10 +5,40 @@
#include "PackageSpec.h"
#include "StatusParagraphs.h"
#include "vcpkg_Files.h"
+#include "vcpkg_Util.h"
+#include "vcpkglib.h"
#include "Paragraphs.h"
namespace vcpkg::Dependencies
{
+ std::vector<PackageSpec> AnyParagraph::dependencies(const Triplet& triplet) const
+ {
+ auto to_package_specs = [&](const std::vector<std::string>& dependencies_as_string)
+ {
+ return Util::fmap(dependencies_as_string, [&](const std::string s)
+ {
+ return PackageSpec::from_name_and_triplet(s, triplet).value_or_exit(VCPKG_LINE_INFO);
+ });
+ };
+
+ if (auto p = this->status_paragraph.get())
+ {
+ return to_package_specs(p->package.depends);
+ }
+
+ if (auto p = this->binary_paragraph.get())
+ {
+ return to_package_specs(p->depends);
+ }
+
+ if (auto p = this->source_paragraph.get())
+ {
+ return to_package_specs(filter_dependencies(p->depends, triplet));
+ }
+
+ Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot get dependencies because there was none of: source/binary/status paragraphs");
+ }
+
std::string to_output_string(RequestType request_type, const CStringView s)
{
switch (request_type)
@@ -22,160 +52,156 @@ namespace vcpkg::Dependencies
}
}
- InstallPlanAction::InstallPlanAction() : plan_type(InstallPlanType::UNKNOWN), request_type(RequestType::UNKNOWN), binary_pgh(nullopt), source_pgh(nullopt) { }
-
- InstallPlanAction::InstallPlanAction(const InstallPlanType& plan_type, const RequestType& request_type, Optional<BinaryParagraph> binary_pgh, Optional<SourceParagraph> source_pgh)
- : plan_type(std::move(plan_type)), request_type(request_type), binary_pgh(std::move(binary_pgh)), source_pgh(std::move(source_pgh)) { }
+ InstallPlanAction::InstallPlanAction() : spec()
+ , any_paragraph()
+ , plan_type(InstallPlanType::UNKNOWN)
+ , request_type(RequestType::UNKNOWN) { }
- bool PackageSpecWithInstallPlan::compare_by_name(const PackageSpecWithInstallPlan* left, const PackageSpecWithInstallPlan* right)
+ InstallPlanAction::InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type) : InstallPlanAction()
{
- return left->spec.name() < right->spec.name();
- }
+ this->spec = spec;
+ this->request_type = request_type;
+ if (auto p = any_paragraph.status_paragraph.get())
+ {
+ this->plan_type = InstallPlanType::ALREADY_INSTALLED;
+ this->any_paragraph.status_paragraph = *p;
+ return;
+ }
- PackageSpecWithInstallPlan::PackageSpecWithInstallPlan(const PackageSpec& spec, InstallPlanAction&& plan) : spec(spec), plan(std::move(plan)) { }
+ if (auto p = any_paragraph.binary_paragraph.get())
+ {
+ this->plan_type = InstallPlanType::INSTALL;
+ this->any_paragraph.binary_paragraph = *p;
+ return;
+ }
- RemovePlanAction::RemovePlanAction() : plan_type(RemovePlanType::UNKNOWN), request_type(RequestType::UNKNOWN) { }
+ if (auto p = any_paragraph.source_paragraph.get())
+ {
+ this->plan_type = InstallPlanType::BUILD_AND_INSTALL;
+ this->any_paragraph.source_paragraph = *p;
+ return;
+ }
- RemovePlanAction::RemovePlanAction(const RemovePlanType& plan_type, const Dependencies::RequestType& request_type) : plan_type(plan_type), request_type(request_type) { }
+ this->plan_type = InstallPlanType::UNKNOWN;
+ }
- bool PackageSpecWithRemovePlan::compare_by_name(const PackageSpecWithRemovePlan* left, const PackageSpecWithRemovePlan* right)
+ bool InstallPlanAction::compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right)
{
return left->spec.name() < right->spec.name();
}
- PackageSpecWithRemovePlan::PackageSpecWithRemovePlan(const PackageSpec& spec, RemovePlanAction&& plan)
- : spec(spec), plan(std::move(plan)) { }
+ RemovePlanAction::RemovePlanAction() : plan_type(RemovePlanType::UNKNOWN)
+ , request_type(RequestType::UNKNOWN) { }
- std::vector<PackageSpecWithInstallPlan> create_install_plan(const VcpkgPaths& paths, const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db)
- {
- std::unordered_set<PackageSpec> specs_as_set(specs.cbegin(), specs.cend());
+ RemovePlanAction::RemovePlanAction(const PackageSpec& spec, const RemovePlanType& plan_type, const RequestType& request_type)
+ : spec(spec)
+ , plan_type(plan_type)
+ , request_type(request_type) { }
- std::unordered_map<PackageSpec, InstallPlanAction> was_examined; // Examine = we have checked its immediate (non-recursive) dependencies
- Graphs::Graph<PackageSpec> graph;
- graph.add_vertices(specs);
+ bool RemovePlanAction::compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right)
+ {
+ return left->spec.name() < right->spec.name();
+ }
- std::vector<PackageSpec> examine_stack(specs);
- while (!examine_stack.empty())
+ std::vector<InstallPlanAction> create_install_plan(const VcpkgPaths& paths, const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db)
+ {
+ struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider<PackageSpec, InstallPlanAction>
{
- const PackageSpec spec = examine_stack.back();
- examine_stack.pop_back();
+ const VcpkgPaths& paths;
+ const StatusParagraphs& status_db;
+ const std::unordered_set<PackageSpec>& specs_as_set;
- if (was_examined.find(spec) != was_examined.end())
- {
- continue;
- }
+ InstallAdjacencyProvider(const VcpkgPaths& p, const StatusParagraphs& s, const std::unordered_set<PackageSpec>& specs_as_set) : paths(p)
+ , status_db(s)
+ , specs_as_set(specs_as_set) {}
- auto process_dependencies = [&](const std::vector<std::string>& dependencies_as_string)
- {
- for (const std::string& dep_as_string : dependencies_as_string)
- {
- const PackageSpec current_dep = PackageSpec::from_name_and_triplet(dep_as_string, spec.triplet()).value_or_exit(VCPKG_LINE_INFO);
- auto it = status_db.find_installed(current_dep);
- if (it != status_db.end())
- {
- continue;
- }
-
- graph.add_edge(spec, current_dep);
- if (was_examined.find(current_dep) == was_examined.end())
- {
- examine_stack.push_back(std::move(current_dep));
- }
- }
- };
-
- 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())
+ std::vector<PackageSpec> adjacency_list(const InstallPlanAction& p) const override
{
- was_examined.emplace(spec, InstallPlanAction{ InstallPlanType::ALREADY_INSTALLED, request_type, nullopt, nullopt });
- continue;
+ if (p.any_paragraph.status_paragraph.get())
+ return std::vector<PackageSpec>{};
+ return p.any_paragraph.dependencies(p.spec.triplet());
}
- Expected<BinaryParagraph> maybe_bpgh = Paragraphs::try_load_cached_package(paths, spec);
- if (BinaryParagraph* bpgh = maybe_bpgh.get())
+ InstallPlanAction load_vertex_data(const PackageSpec& spec) const override
{
- process_dependencies(bpgh->depends);
- was_examined.emplace(spec, InstallPlanAction{ InstallPlanType::INSTALL, request_type, std::move(*bpgh), nullopt });
- continue;
- }
+ 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 };
- Expected<SourceParagraph> maybe_spgh = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec));
- if (auto spgh = maybe_spgh.get())
- {
- process_dependencies(filter_dependencies(spgh->depends, spec.triplet()));
- was_examined.emplace(spec, InstallPlanAction{ InstallPlanType::BUILD_AND_INSTALL, request_type, nullopt, std::move(*spgh) });
- }
- else
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot find package %s", spec.name());
+ Expected<BinaryParagraph> maybe_bpgh = Paragraphs::try_load_cached_package(paths, spec);
+ if (auto bpgh = maybe_bpgh.get())
+ return InstallPlanAction{ spec, { nullopt, *bpgh, nullopt }, request_type };
+
+ Expected<SourceParagraph> maybe_spgh = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec));
+ if (auto spgh = maybe_spgh.get())
+ return InstallPlanAction{ spec, { nullopt, nullopt, *spgh }, request_type };
+
+ return InstallPlanAction{ spec , { nullopt, nullopt, nullopt }, request_type };
}
- }
+ };
- std::vector<PackageSpecWithInstallPlan> ret;
+ const std::unordered_set<PackageSpec> specs_as_set(specs.cbegin(), specs.cend());
+ std::vector<InstallPlanAction> toposort = Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db, specs_as_set });
+ Util::keep_if(toposort, [](const InstallPlanAction& p)
+ {
+ return !(p.request_type == RequestType::AUTO_SELECTED && p.plan_type == InstallPlanType::ALREADY_INSTALLED);
+ });
- const std::vector<PackageSpec> pkgs = graph.find_topological_sort();
- for (const PackageSpec& pkg : pkgs)
- {
- ret.push_back(PackageSpecWithInstallPlan(pkg, std::move(was_examined[pkg])));
- }
- return ret;
+ return toposort;
}
- std::vector<PackageSpecWithRemovePlan> create_remove_plan(const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db)
+ std::vector<RemovePlanAction> create_remove_plan(const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db)
{
- std::unordered_set<PackageSpec> specs_as_set(specs.cbegin(), specs.cend());
-
- std::unordered_map<PackageSpec, RemovePlanAction> was_examined; // Examine = we have checked its immediate (non-recursive) dependencies
- Graphs::Graph<PackageSpec> graph;
- graph.add_vertices(specs);
-
- std::vector<PackageSpec> examine_stack(specs);
- while (!examine_stack.empty())
+ struct RemoveAdjacencyProvider final : Graphs::AdjacencyProvider<PackageSpec, RemovePlanAction>
{
- const PackageSpec spec = examine_stack.back();
- examine_stack.pop_back();
-
- if (was_examined.find(spec) != was_examined.end())
- {
- continue;
- }
+ const StatusParagraphs& status_db;
+ const std::vector<StatusParagraph*>& installed_ports;
+ const std::unordered_set<PackageSpec>& specs_as_set;
- const StatusParagraphs::const_iterator it = status_db.find(spec);
- if (it == status_db.end() || (*it)->state == InstallState::NOT_INSTALLED)
- {
- was_examined.emplace(spec, RemovePlanAction(RemovePlanType::NOT_INSTALLED, RequestType::USER_REQUESTED));
- continue;
- }
+ RemoveAdjacencyProvider(const StatusParagraphs& status_db, const std::vector<StatusParagraph*>& installed_ports, const std::unordered_set<PackageSpec>& specs_as_set)
+ : status_db(status_db)
+ , installed_ports(installed_ports)
+ , specs_as_set(specs_as_set) { }
- for (const std::unique_ptr<StatusParagraph>& an_installed_package : status_db)
+ std::vector<PackageSpec> adjacency_list(const RemovePlanAction& p) const override
{
- if (an_installed_package->want != Want::INSTALL)
- continue;
- if (an_installed_package->package.spec.triplet() != spec.triplet())
- continue;
+ if (p.plan_type == RemovePlanType::NOT_INSTALLED)
+ {
+ return {};
+ }
- const std::vector<std::string>& deps = an_installed_package->package.depends;
- if (std::find(deps.begin(), deps.end(), spec.name()) == deps.end())
+ const PackageSpec& spec = p.spec;
+ std::vector<PackageSpec> dependents;
+ for (const StatusParagraph* an_installed_package : installed_ports)
{
- continue;
+ if (an_installed_package->package.spec.triplet() != spec.triplet())
+ continue;
+
+ const std::vector<std::string>& deps = an_installed_package->package.depends;
+ if (std::find(deps.begin(), deps.end(), spec.name()) == deps.end())
+ continue;
+
+ dependents.push_back(an_installed_package->package.spec);
}
- graph.add_edge(spec, an_installed_package.get()->package.spec);
- examine_stack.push_back(an_installed_package.get()->package.spec);
+ return dependents;
}
- const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED;
- was_examined.emplace(spec, RemovePlanAction(RemovePlanType::REMOVE, request_type));
- }
-
- std::vector<PackageSpecWithRemovePlan> ret;
+ RemovePlanAction load_vertex_data(const PackageSpec& spec) const override
+ {
+ const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED;
+ const StatusParagraphs::const_iterator it = status_db.find_installed(spec);
+ if (it == status_db.end())
+ {
+ return RemovePlanAction{ spec, RemovePlanType::NOT_INSTALLED, request_type };
+ }
+ return RemovePlanAction{ spec, RemovePlanType::REMOVE, request_type };
+ }
+ };
- const std::vector<PackageSpec> pkgs = graph.find_topological_sort();
- for (const PackageSpec& pkg : pkgs)
- {
- ret.push_back(PackageSpecWithRemovePlan(pkg, std::move(was_examined[pkg])));
- }
- return ret;
+ const std::vector<StatusParagraph*>& installed_ports = get_installed_ports(status_db);
+ const std::unordered_set<PackageSpec> specs_as_set(specs.cbegin(), specs.cend());
+ return Graphs::topological_sort(specs, RemoveAdjacencyProvider{ status_db, installed_ports, specs_as_set });
}
}
diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp
index 26dc6388b..3d9895436 100644
--- a/toolsrc/src/vcpkg_Strings.cpp
+++ b/toolsrc/src/vcpkg_Strings.cpp
@@ -1,5 +1,6 @@
#include "pch.h"
#include "vcpkg_Strings.h"
+#include "vcpkg_Util.h"
namespace vcpkg::Strings::details
{
@@ -98,10 +99,10 @@ namespace vcpkg::Strings
trim(&s);
}
- strings->erase(std::remove_if(strings->begin(), strings->end(), [](const std::string& s)-> bool
- {
- return s == "";
- }), strings->end());
+ Util::keep_if(*strings, [](const std::string& s)-> bool
+ {
+ return s != "";
+ });
}
std::vector<std::string> split(const std::string& s, const std::string& delimiter)
diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp
index cc70b86b0..6cfc741e1 100644
--- a/toolsrc/src/vcpkglib.cpp
+++ b/toolsrc/src/vcpkglib.cpp
@@ -5,6 +5,7 @@
#include "metrics.h"
#include "vcpkg_Util.h"
#include "vcpkg_Strings.h"
+#include "vcpkg_Util.h"
namespace vcpkg
{
@@ -200,12 +201,10 @@ namespace vcpkg
upgrade_to_slash_terminated_sorted_format(fs, &installed_files_of_current_pgh, listfile_path);
// Remove the directories
- installed_files_of_current_pgh.erase(
- std::remove_if(installed_files_of_current_pgh.begin(), installed_files_of_current_pgh.end(), [](const std::string& file) -> bool
- {
- return file.back() == '/';
- }
- ), installed_files_of_current_pgh.end());
+ Util::keep_if(installed_files_of_current_pgh, [](const std::string& file) -> bool
+ {
+ return file.back() != '/';
+ });
StatusParagraphAndAssociatedFiles pgh_and_files = { *pgh, SortedVector<std::string>(std::move(installed_files_of_current_pgh)) };
installed_files.push_back(std::move(pgh_and_files));