Simplify Remove plan generation

This commit is contained in:
Alexander Karatarakis 2017-04-12 21:37:55 -07:00
parent 5131e955a8
commit 2fa87fbb0a
3 changed files with 47 additions and 70 deletions

View File

@ -7,15 +7,6 @@
namespace vcpkg::Dependencies
{
struct AnyParagraph
{
std::vector<PackageSpec> dependencies(const Triplet& triplet) const;
Optional<StatusParagraph> status_paragraph;
Optional<BinaryParagraph> binary_paragraph;
Optional<SourceParagraph> source_paragraph;
};
enum class RequestType
{
UNKNOWN,
@ -25,6 +16,15 @@ namespace vcpkg::Dependencies
std::string to_output_string(RequestType request_type, const CStringView s);
struct AnyParagraph
{
std::vector<PackageSpec> dependencies(const Triplet& triplet) const;
Optional<StatusParagraph> status_paragraph;
Optional<BinaryParagraph> binary_paragraph;
Optional<SourceParagraph> source_paragraph;
};
enum class InstallPlanType
{
UNKNOWN,
@ -57,36 +57,23 @@ namespace vcpkg::Dependencies
REMOVE
};
struct SpecAndRemovePlanType
{
PackageSpec spec;
RemovePlanType plan_type;
};
struct RemovePlanAction
{
static bool compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right);
RemovePlanAction();
RemovePlanAction(const RemovePlanType& plan_type, const RequestType& request_type);
RemovePlanAction(const PackageSpec& spec, const RemovePlanType& plan_type, const RequestType& request_type);
RemovePlanAction(const RemovePlanAction&) = delete;
RemovePlanAction(RemovePlanAction&&) = default;
RemovePlanAction& operator=(const RemovePlanAction&) = delete;
RemovePlanAction& operator=(RemovePlanAction&&) = default;
PackageSpec spec;
RemovePlanType plan_type;
RequestType request_type;
};
struct PackageSpecWithRemovePlan
{
static bool compare_by_name(const PackageSpecWithRemovePlan* left, const PackageSpecWithRemovePlan* right);
PackageSpecWithRemovePlan(const PackageSpec& spec, RemovePlanAction&& plan);
PackageSpec spec;
RemovePlanAction plan;
};
std::vector<InstallPlanAction> create_install_plan(const VcpkgPaths& paths, const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db);
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);
}

View File

@ -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);

View File

@ -93,19 +93,16 @@ namespace vcpkg::Dependencies
RemovePlanAction::RemovePlanAction() : plan_type(RemovePlanType::UNKNOWN)
, request_type(RequestType::UNKNOWN) { }
RemovePlanAction::RemovePlanAction(const RemovePlanType& plan_type, const RequestType& request_type)
: plan_type(plan_type)
RemovePlanAction::RemovePlanAction(const PackageSpec& spec, const RemovePlanType& plan_type, const RequestType& request_type)
: spec(spec)
, plan_type(plan_type)
, request_type(request_type) { }
bool PackageSpecWithRemovePlan::compare_by_name(const PackageSpecWithRemovePlan* left, const PackageSpecWithRemovePlan* right)
bool RemovePlanAction::compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right)
{
return left->spec.name() < right->spec.name();
}
PackageSpecWithRemovePlan::PackageSpecWithRemovePlan(const PackageSpec& spec, RemovePlanAction&& plan)
: spec(spec)
, plan(std::move(plan)) { }
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>
@ -134,13 +131,13 @@ namespace vcpkg::Dependencies
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 };
return InstallPlanAction{ spec, { nullopt, *bpgh, nullopt }, request_type };
Expected<SourceParagraph> maybe_spgh = Paragraphs::try_load_port(paths.port_dir(spec));
if (auto spgh = maybe_spgh.get())
return InstallPlanAction{ spec, {nullopt, nullopt, *spgh}, request_type };
return InstallPlanAction{ spec, { nullopt, nullopt, *spgh }, request_type };
return InstallPlanAction{ spec , {nullopt, nullopt, nullopt}, request_type };
return InstallPlanAction{ spec , { nullopt, nullopt, nullopt }, request_type };
}
};
@ -148,18 +145,20 @@ namespace vcpkg::Dependencies
return Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db, specs_as_set });
}
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)
{
struct RemoveAdjacencyProvider final : Graphs::AdjacencyProvider<PackageSpec, SpecAndRemovePlanType>
struct RemoveAdjacencyProvider final : Graphs::AdjacencyProvider<PackageSpec, RemovePlanAction>
{
const StatusParagraphs& status_db;
const std::vector<StatusParagraph*>& installed_ports;
const std::unordered_set<PackageSpec>& specs_as_set;
RemoveAdjacencyProvider(const StatusParagraphs& status_db, const std::vector<StatusParagraph*>& installed_ports)
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) { }
, installed_ports(installed_ports)
, specs_as_set(specs_as_set) { }
std::vector<PackageSpec> adjacency_list(const SpecAndRemovePlanType& p) const override
std::vector<PackageSpec> adjacency_list(const RemovePlanAction& p) const override
{
if (p.plan_type == RemovePlanType::NOT_INSTALLED)
{
@ -183,29 +182,20 @@ namespace vcpkg::Dependencies
return dependents;
}
SpecAndRemovePlanType load_vertex_data(const PackageSpec& spec) const override
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 { spec, RemovePlanType::NOT_INSTALLED };
return RemovePlanAction{ spec, RemovePlanType::NOT_INSTALLED, request_type };
}
return { spec, RemovePlanType::REMOVE };
return RemovePlanAction{ spec, 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;
for (const SpecAndRemovePlanType& pkg : toposort)
{
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;
return Graphs::topological_sort(specs, RemoveAdjacencyProvider{ status_db, installed_ports, specs_as_set });
}
}