mirror of
https://github.com/microsoft/vcpkg.git
synced 2024-11-25 17:29:08 +08:00
Create a remove plan. NOT used yet
This commit is contained in:
parent
cc81c3de6c
commit
33b46b1fee
@ -30,9 +30,23 @@ namespace vcpkg::Dependencies
|
||||
{
|
||||
NOT_INSTALLED,
|
||||
DEPENDENCIES_NOT_SATISFIED,
|
||||
SHOULD_REMOVE
|
||||
REMOVE,
|
||||
REMOVE_USER_REQUESTED
|
||||
};
|
||||
|
||||
struct remove_plan_action
|
||||
{
|
||||
remove_plan_type type;
|
||||
std::unique_ptr<BinaryParagraph> bpgh;
|
||||
};
|
||||
|
||||
struct package_spec_with_remove_plan
|
||||
{
|
||||
package_spec spec;
|
||||
remove_plan_action plan;
|
||||
};
|
||||
|
||||
std::vector<package_spec_with_install_plan> create_install_plan(const vcpkg_paths& paths, const std::vector<package_spec>& specs, const StatusParagraphs& status_db);
|
||||
|
||||
std::vector<package_spec_with_remove_plan> create_remove_plan(const vcpkg_paths& paths, const std::vector<package_spec>& specs, const StatusParagraphs& status_db);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user