diff options
| author | Alexander Karatarakis <alkarata@microsoft.com> | 2017-04-12 18:55:37 -0700 |
|---|---|---|
| committer | Alexander Karatarakis <alkarata@microsoft.com> | 2017-04-12 22:05:03 -0700 |
| commit | 7f79f44b0c7084a80af541db04c54f3d1e95316c (patch) | |
| tree | 69151760ce0711dad55f090b851bbe027bdfc30c | |
| parent | 4749d7d67d43ac3c7c1c743eb838962c418f0d14 (diff) | |
| download | vcpkg-7f79f44b0c7084a80af541db04c54f3d1e95316c.tar.gz vcpkg-7f79f44b0c7084a80af541db04c54f3d1e95316c.zip | |
Rework create_install_plan()
| -rw-r--r-- | toolsrc/src/vcpkg_Dependencies.cpp | 90 |
1 files changed, 51 insertions, 39 deletions
diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 4c0254ae4..a2d7dcc7f 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -6,6 +6,7 @@ #include "StatusParagraphs.h" #include "vcpkg_Files.h" #include "vcpkg_Util.h" +#include "vcpkglib.h" namespace vcpkg::Dependencies { @@ -119,7 +120,7 @@ namespace vcpkg::Dependencies const VcpkgPaths& paths; const StatusParagraphs& status_db; - InstallAdjacencyProvider(const VcpkgPaths& p, const StatusParagraphs & s) : paths(p) + InstallAdjacencyProvider(const VcpkgPaths& p, const StatusParagraphs& s) : paths(p) , status_db(s) {} std::vector<PackageSpec> adjacency_list(const AnyParagraph& p) const override @@ -147,9 +148,9 @@ namespace vcpkg::Dependencies } }; - auto toposort = Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db }); + const std::vector<AnyParagraph> toposort = Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db }); - std::unordered_set<PackageSpec> specs_as_set(specs.cbegin(), specs.cend()); + const std::unordered_set<PackageSpec> specs_as_set(specs.cbegin(), specs.cend()); std::vector<PackageSpecWithInstallPlan> ret; for (const AnyParagraph& pkg : toposort) { @@ -163,58 +164,69 @@ namespace vcpkg::Dependencies return ret; } - std::vector<PackageSpecWithRemovePlan> create_remove_plan(const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db) + struct SpecAndRemovePlanType { - 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); + PackageSpec spec; + RemovePlanType plan_type; + }; - std::vector<PackageSpec> examine_stack(specs); - while (!examine_stack.empty()) + std::vector<PackageSpecWithRemovePlan> create_remove_plan(const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db) + { + struct RemoveAdjacencyProvider final : Graphs::AdjacencyProvider<PackageSpec, SpecAndRemovePlanType> { - const PackageSpec spec = examine_stack.back(); - examine_stack.pop_back(); + const StatusParagraphs& status_db; + const std::vector<StatusParagraph*>& installed_ports; - if (was_examined.find(spec) != was_examined.end()) - { - continue; - } + RemoveAdjacencyProvider(const StatusParagraphs& status_db, const std::vector<StatusParagraph*>& installed_ports) + : status_db(status_db) + , installed_ports(installed_ports) { } - const StatusParagraphs::const_iterator it = status_db.find_installed(spec); - if (it == status_db.end()) + std::vector<PackageSpec> adjacency_list(const SpecAndRemovePlanType& p) const override { - was_examined.emplace(spec, RemovePlanAction(RemovePlanType::NOT_INSTALLED, RequestType::USER_REQUESTED)); - continue; + if (p.plan_type == RemovePlanType::NOT_INSTALLED) + { + return {}; + } + + const PackageSpec& spec = p.spec; + std::vector<PackageSpec> dependents; + for (const StatusParagraph* an_installed_package : installed_ports) + { + 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); + } + + return dependents; } - const std::vector<StatusParagraph*> installed_ports = get_installed_ports(status_db); - for (const StatusParagraph* an_installed_package : installed_ports) + SpecAndRemovePlanType load_vertex_data(const PackageSpec& spec) const override { - 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()) + const StatusParagraphs::const_iterator it = status_db.find_installed(spec); + if (it == status_db.end()) { - continue; + return {spec, RemovePlanType::NOT_INSTALLED}; } - - graph.add_edge(spec, an_installed_package->package.spec); - examine_stack.push_back(an_installed_package->package.spec); + return { spec, RemovePlanType::REMOVE }; } + }; - 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)); - } + const std::vector<StatusParagraph*>& installed_ports = get_installed_ports(status_db); + const std::vector<SpecAndRemovePlanType> toposort = Graphs::topological_sort(specs, RemoveAdjacencyProvider{ status_db, installed_ports }); + const std::unordered_set<PackageSpec> specs_as_set(specs.cbegin(), specs.cend()); std::vector<PackageSpecWithRemovePlan> ret; - - const std::vector<PackageSpec> pkgs = graph.topological_sort(); - for (const PackageSpec& pkg : pkgs) + for (const SpecAndRemovePlanType& pkg : toposort) { - ret.push_back(PackageSpecWithRemovePlan(pkg, std::move(was_examined[pkg]))); + auto spec = pkg.spec; + const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED; + RemovePlanAction r(pkg.plan_type, request_type); + ret.push_back(PackageSpecWithRemovePlan(spec, std::move(r))); } return ret; } |
