aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src/commands_remove.cpp
diff options
context:
space:
mode:
authorThomas Fussell <thomas.fussell@gmail.com>2017-03-12 17:44:06 -0400
committerThomas Fussell <thomas.fussell@gmail.com>2017-03-12 17:44:06 -0400
commit2f42035ab43dd50cd863b51944aa099a99ae60f0 (patch)
tree4b6cfd43955e946721c58028fd8564c861d5c331 /toolsrc/src/commands_remove.cpp
parente02e85626f3206feda86a6f5757009005e0cfe3e (diff)
parent1c9873a0daf625f67474aaf3e163c592c27ecb65 (diff)
downloadvcpkg-2f42035ab43dd50cd863b51944aa099a99ae60f0.tar.gz
vcpkg-2f42035ab43dd50cd863b51944aa099a99ae60f0.zip
Merge branch 'master' of git://github.com/Microsoft/vcpkg
Diffstat (limited to 'toolsrc/src/commands_remove.cpp')
-rw-r--r--toolsrc/src/commands_remove.cpp201
1 files changed, 116 insertions, 85 deletions
diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/commands_remove.cpp
index 445213fc2..1b7b7923a 100644
--- a/toolsrc/src/commands_remove.cpp
+++ b/toolsrc/src/commands_remove.cpp
@@ -1,12 +1,18 @@
+#include "pch.h"
#include "vcpkg_Commands.h"
-#include "vcpkg.h"
+#include "vcpkglib.h"
#include "vcpkg_System.h"
#include "vcpkg_Input.h"
-#include <fstream>
+#include "vcpkg_Dependencies.h"
-namespace vcpkg
+namespace vcpkg::Commands::Remove
{
+ using Dependencies::package_spec_with_remove_plan;
+ using Dependencies::remove_plan_type;
+ using Dependencies::request_type;
+
static const std::string OPTION_PURGE = "--purge";
+ static const std::string OPTION_RECURSE = "--recurse";
static void delete_directory(const fs::path& directory)
{
@@ -22,78 +28,9 @@ namespace vcpkg
}
}
- enum class deinstall_plan
- {
- not_installed,
- dependencies_not_satisfied,
- should_deinstall
- };
-
- static deinstall_plan deinstall_package_plan(
- const StatusParagraphs::iterator package_it,
- const StatusParagraphs& status_db,
- std::vector<const StatusParagraph*>& dependencies_out)
- {
- dependencies_out.clear();
-
- if (package_it == status_db.end() || (*package_it)->state == install_state_t::not_installed)
- {
- return deinstall_plan::not_installed;
- }
-
- auto& pkg = (*package_it)->package;
-
- for (auto&& inst_pkg : status_db)
- {
- if (inst_pkg->want != want_t::install)
- continue;
- if (inst_pkg->package.spec.target_triplet() != pkg.spec.target_triplet())
- continue;
-
- const auto& deps = inst_pkg->package.depends;
-
- if (std::find(deps.begin(), deps.end(), pkg.spec.name()) != deps.end())
- {
- dependencies_out.push_back(inst_pkg.get());
- }
- }
-
- if (!dependencies_out.empty())
- return deinstall_plan::dependencies_not_satisfied;
-
- return deinstall_plan::should_deinstall;
- }
-
- static void deinstall_package(const vcpkg_paths& paths, const package_spec& spec, StatusParagraphs& status_db)
+ static void remove_package(const vcpkg_paths& paths, const package_spec& spec, StatusParagraphs* status_db)
{
- auto package_it = status_db.find(spec.name(), spec.target_triplet());
- if (package_it == status_db.end())
- {
- System::println(System::color::success, "Package %s is not installed", spec);
- return;
- }
-
- auto& pkg = **package_it;
-
- std::vector<const StatusParagraph*> deps;
- auto plan = deinstall_package_plan(package_it, status_db, deps);
- switch (plan)
- {
- case deinstall_plan::not_installed:
- System::println(System::color::success, "Package %s is not installed", spec);
- return;
- case deinstall_plan::dependencies_not_satisfied:
- System::println(System::color::error, "Error: Cannot remove package %s:", spec);
- for (auto&& dep : deps)
- {
- System::println(" %s depends on %s", dep->package.displayname(), pkg.package.displayname());
- }
- exit(EXIT_FAILURE);
- case deinstall_plan::should_deinstall:
- break;
- default:
- Checks::unreachable();
- }
+ StatusParagraph& pkg = **status_db->find(spec.name(), spec.target_triplet());
pkg.want = want_t::purge;
pkg.state = install_state_t::half_installed;
@@ -163,31 +100,125 @@ namespace vcpkg
pkg.state = install_state_t::not_installed;
write_update(paths, pkg);
- System::println(System::color::success, "Package %s was successfully removed", pkg.package.displayname());
}
- void remove_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths, const triplet& default_target_triplet)
+ static void sort_packages_by_name(std::vector<const package_spec_with_remove_plan*>* packages)
{
- static const std::string example = create_example_string("remove zlib zlib:x64-windows curl boost");
- args.check_min_arg_count(1, example);
+ std::sort(packages->begin(), packages->end(), [](const package_spec_with_remove_plan* left, const package_spec_with_remove_plan* right) -> bool
+ {
+ return left->spec.name() < right->spec.name();
+ });
+ }
- const std::unordered_set<std::string> options = args.check_and_get_optional_command_arguments({OPTION_PURGE});
- auto status_db = database_load_check(paths);
+ static void print_plan(const std::vector<package_spec_with_remove_plan>& plan)
+ {
+ std::vector<const package_spec_with_remove_plan*> not_installed;
+ std::vector<const package_spec_with_remove_plan*> remove;
+ for (const package_spec_with_remove_plan& i : plan)
+ {
+ if (i.plan.plan_type == remove_plan_type::NOT_INSTALLED)
+ {
+ not_installed.push_back(&i);
+ continue;
+ }
+
+ if (i.plan.plan_type == remove_plan_type::REMOVE)
+ {
+ remove.push_back(&i);
+ continue;
+ }
+
+ Checks::unreachable();
+ }
+
+ if (!not_installed.empty())
+ {
+ sort_packages_by_name(&not_installed);
+ System::println("The following packages are not installed, so not removed:\n%s",
+ Strings::join("\n ", not_installed, [](const package_spec_with_remove_plan* p)
+ {
+ return " " + p->spec.toString();
+ }));
+ }
+
+ if (!remove.empty())
+ {
+ sort_packages_by_name(&remove);
+ System::println("The following packages will be removed:\n%s",
+ Strings::join("\n", remove, [](const package_spec_with_remove_plan* p)
+ {
+ if (p->plan.request_type == Dependencies::request_type::AUTO_SELECTED)
+ {
+ return " * " + p->spec.toString();
+ }
+
+ if (p->plan.request_type == Dependencies::request_type::USER_REQUESTED)
+ {
+ return " " + p->spec.toString();
+ }
+
+ Checks::unreachable();
+ }));
+ }
+ }
+
+ void perform_and_exit(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths, const triplet& default_target_triplet)
+ {
+ static const std::string example = Commands::Help::create_example_string("remove zlib zlib:x64-windows curl boost");
+ args.check_min_arg_count(1, example);
std::vector<package_spec> specs = Input::check_and_get_package_specs(args.command_arguments, default_target_triplet, example);
Input::check_triplets(specs, paths);
- bool alsoRemoveFolderFromPackages = options.find(OPTION_PURGE) != options.end();
+ const std::unordered_set<std::string> options = args.check_and_get_optional_command_arguments({ OPTION_PURGE, OPTION_RECURSE });
+ const bool alsoRemoveFolderFromPackages = options.find(OPTION_PURGE) != options.end();
+ const bool isRecursive = options.find(OPTION_RECURSE) != options.end();
+
+ auto status_db = database_load_check(paths);
+ const std::vector<package_spec_with_remove_plan> remove_plan = Dependencies::create_remove_plan(specs, status_db);
+ Checks::check_exit(!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 package_spec_with_remove_plan& package)-> bool
+ {
+ return package.plan.request_type != request_type::USER_REQUESTED;
+ }) != remove_plan.cend();
- for (const package_spec& spec : specs)
+ if (has_non_user_requested_packages && !isRecursive)
{
- deinstall_package(paths, spec, status_db);
+ System::println(System::color::warning,
+ "Additional packages (*) need to be removed to complete this operation.\n"
+ "If you are sure you want to remove them, run the command with the --recurse option");
+ exit(EXIT_FAILURE);
+ }
+
+ for (const package_spec_with_remove_plan& action : remove_plan)
+ {
+ const std::string display_name = action.spec.display_name();
+
+ switch (action.plan.plan_type)
+ {
+ case remove_plan_type::NOT_INSTALLED:
+ System::println(System::color::success, "Package %s is not installed", display_name);
+ break;
+ case remove_plan_type::REMOVE:
+ System::println("Removing package %s... ", display_name);
+ remove_package(paths, action.spec, &status_db);
+ System::println(System::color::success, "Removing package %s... done", display_name);
+ break;
+ case remove_plan_type::UNKNOWN:
+ default:
+ Checks::unreachable();
+ }
if (alsoRemoveFolderFromPackages)
{
- const fs::path spec_package_dir = paths.packages / spec.dir();
- delete_directory(spec_package_dir);
+ System::println("Purging package %s... ", display_name);
+ delete_directory(paths.packages / action.spec.dir());
+ System::println(System::color::success, "Purging package %s... done", display_name);
}
}
+
exit(EXIT_SUCCESS);
}
}