diff options
| author | Alexander Karatarakis <alkarata@microsoft.com> | 2017-01-26 17:53:45 -0800 |
|---|---|---|
| committer | Alexander Karatarakis <alkarata@microsoft.com> | 2017-01-30 21:52:41 -0800 |
| commit | 33b46b1fee70996a23a7860f853e95ef80ff3978 (patch) | |
| tree | 985a5833c2c48cc9ccb9ec3e40139948e731ba03 /toolsrc/src | |
| parent | cc81c3de6c74837dc146d7d3de73e4388cfc14dc (diff) | |
| download | vcpkg-33b46b1fee70996a23a7860f853e95ef80ff3978.tar.gz vcpkg-33b46b1fee70996a23a7860f853e95ef80ff3978.zip | |
Create a remove plan. NOT used yet
Diffstat (limited to 'toolsrc/src')
| -rw-r--r-- | toolsrc/src/commands_remove.cpp | 8 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg_Dependencies.cpp | 58 |
2 files changed, 64 insertions, 2 deletions
diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/commands_remove.cpp index bf415d2c0..7b8286f9c 100644 --- a/toolsrc/src/commands_remove.cpp +++ b/toolsrc/src/commands_remove.cpp @@ -7,6 +7,7 @@ namespace vcpkg::Commands::Remove { + using Dependencies::package_spec_with_remove_plan; using Dependencies::remove_plan_type; static const std::string OPTION_PURGE = "--purge"; @@ -57,7 +58,7 @@ namespace vcpkg::Commands::Remove if (!dependencies_out.empty()) return remove_plan_type::DEPENDENCIES_NOT_SATISFIED; - return remove_plan_type::SHOULD_REMOVE; + return remove_plan_type::REMOVE; } static void deinstall_package(const vcpkg_paths& paths, const package_spec& spec, StatusParagraphs& status_db) @@ -85,7 +86,7 @@ namespace vcpkg::Commands::Remove System::println(" %s depends on %s", dep->package.displayname(), pkg.package.displayname()); } exit(EXIT_FAILURE); - case remove_plan_type::SHOULD_REMOVE: + case remove_plan_type::REMOVE: break; default: Checks::unreachable(); @@ -174,6 +175,9 @@ namespace vcpkg::Commands::Remove Input::check_triplets(specs, paths); bool alsoRemoveFolderFromPackages = options.find(OPTION_PURGE) != options.end(); + const std::vector<package_spec_with_remove_plan> remove_plan = Dependencies::create_remove_plan(paths, specs, status_db); + Checks::check_exit(!remove_plan.empty(), "Remove plan cannot be empty"); + for (const package_spec& spec : specs) { deinstall_package(paths, spec, status_db); diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 1daa6de02..4468930c4 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -5,6 +5,7 @@ #include "package_spec.h" #include "StatusParagraphs.h" #include <unordered_set> +#include <unordered_map> #include "vcpkg_Maps.h" #include "vcpkg_Files.h" #include "vcpkglib.h" @@ -72,4 +73,61 @@ namespace vcpkg::Dependencies } return ret; } + + std::vector<package_spec_with_remove_plan> create_remove_plan(const vcpkg_paths& paths, const std::vector<package_spec>& specs, const StatusParagraphs& status_db) + { + std::unordered_set<package_spec> specs_as_set(specs.cbegin(), specs.cend()); + + std::unordered_map<package_spec, remove_plan_action> was_examined; // Examine = we have checked its immediate (non-recursive) dependencies + Graphs::Graph<package_spec> graph; + graph.add_vertices(specs); + + std::vector<package_spec> examine_stack(specs); + while (!examine_stack.empty()) + { + const package_spec spec = examine_stack.back(); + examine_stack.pop_back(); + + if (was_examined.find(spec) != was_examined.end()) + { + continue; + } + + auto it = status_db.find(spec); + if (it == status_db.end() || (*it)->state == install_state_t::not_installed) + { + was_examined.emplace(spec, remove_plan_action{ remove_plan_type::NOT_INSTALLED, nullptr}); + continue; + } + + for (const std::unique_ptr<StatusParagraph>& an_installed_package : status_db) + { + if (an_installed_package->want != want_t::install) + continue; + if (an_installed_package->package.spec.target_triplet() != spec.target_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; + } + + graph.add_edge(spec, an_installed_package.get()->package.spec); + examine_stack.push_back(an_installed_package.get()->package.spec); + } + + const remove_plan_type type = specs_as_set.find(spec) != specs_as_set.end() ? remove_plan_type::REMOVE_USER_REQUESTED: remove_plan_type::REMOVE; + was_examined.emplace(spec, remove_plan_action{ type, std::make_unique<BinaryParagraph>(std::move((*it)->package))}); + } + + std::vector<package_spec_with_remove_plan> ret; + + const std::vector<package_spec> pkgs = graph.find_topological_sort(); + for (const package_spec& pkg : pkgs) + { + ret.push_back({ pkg, std::move(was_examined[pkg]) }); + } + return ret; + } } |
