From 27be8b5c7489ea52156669f8e556ad3db1fd11d1 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 21 Aug 2017 17:16:14 -0700 Subject: [PATCH] [vcpkg] Fix feature packages for non-default triplets. Reduce duplication between normal installs and feature installs. --- toolsrc/include/VcpkgPaths.h | 1 + toolsrc/include/vcpkg_Dependencies.h | 17 +- toolsrc/include/vcpkg_Util.h | 6 +- toolsrc/src/VcpkgPaths.cpp | 1 + toolsrc/src/commands_install.cpp | 271 +++++++++++++-------------- toolsrc/src/test_install_plan.cpp | 4 +- toolsrc/src/vcpkg_Dependencies.cpp | 118 ++++++------ 7 files changed, 208 insertions(+), 210 deletions(-) diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index 95cd4bc28..e4e7ba83d 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -21,6 +21,7 @@ namespace vcpkg fs::path package_dir(const PackageSpec& spec) const; fs::path port_dir(const PackageSpec& spec) const; + fs::path port_dir(const std::string& name) const; fs::path build_info_file_path(const PackageSpec& spec) const; fs::path listfile_path(const BinaryParagraph& pgh) const; diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index 9ac52490e..e6c3c55c9 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -86,6 +86,9 @@ namespace vcpkg::Dependencies struct AnyAction { + AnyAction(InstallPlanAction&& iplan) : install_plan(std::move(iplan)) {} + AnyAction(RemovePlanAction&& rplan) : remove_plan(std::move(rplan)) {} + Optional install_plan; Optional remove_plan; }; @@ -114,21 +117,21 @@ namespace vcpkg::Dependencies RequestType request_type; }; - __interface PortFileProvider { virtual const SourceControlFile& get_control_file(const PackageSpec& spec) const; }; + __interface PortFileProvider { virtual const SourceControlFile& get_control_file(const std::string& spec) const; }; struct MapPortFile : PortFileProvider { - const std::unordered_map& ports; - explicit MapPortFile(const std::unordered_map& map); - const SourceControlFile& get_control_file(const PackageSpec& spec) const override; + const std::unordered_map& ports; + explicit MapPortFile(const std::unordered_map& map); + const SourceControlFile& get_control_file(const std::string& spec) const override; }; struct PathsPortFile : PortFileProvider { const VcpkgPaths& ports; - mutable std::unordered_map cache; + mutable std::unordered_map cache; explicit PathsPortFile(const VcpkgPaths& paths); - const SourceControlFile& get_control_file(const PackageSpec& spec) const override; + const SourceControlFile& get_control_file(const std::string& spec) const override; private: PathsPortFile(const PathsPortFile&) = delete; @@ -146,7 +149,7 @@ namespace vcpkg::Dependencies const std::vector& specs, const StatusParagraphs& status_db); - std::vector create_feature_install_plan(const std::unordered_map& map, + std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db); } diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index 671997e7e..a62b48d54 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -7,12 +7,12 @@ namespace vcpkg::Util { template - using FmapOut = decltype(std::declval()(std::declval()[0])); + using FmapOut = decltype(std::declval()(*begin(std::declval()))); template> - std::vector fmap(const Cont& xs, Func&& f) + std::vector fmap(Cont&& xs, Func&& f) { - using O = decltype(f(xs[0])); + using O = decltype(f(*begin(xs))); std::vector ret; ret.reserve(xs.size()); diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 60204bcdd..4be636650 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -214,6 +214,7 @@ namespace vcpkg fs::path VcpkgPaths::package_dir(const PackageSpec& spec) const { return this->packages / spec.dir(); } fs::path VcpkgPaths::port_dir(const PackageSpec& spec) const { return this->ports / spec.name(); } + fs::path VcpkgPaths::port_dir(const std::string& name) const { return this->ports / name; } fs::path VcpkgPaths::build_info_file_path(const PackageSpec& spec) const { diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index 3fc0e2563..9e37dc057 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -13,11 +13,7 @@ namespace vcpkg::Commands::Install { - using Dependencies::InstallPlanAction; - using Dependencies::InstallPlanType; - using Dependencies::RemovePlanAction; - using Dependencies::RemovePlanType; - using Dependencies::RequestType; + using namespace Dependencies; InstallDir InstallDir::from_destination_root(const fs::path& destination_root, const std::string& destination_subdirectory, @@ -176,41 +172,6 @@ namespace vcpkg::Commands::Install return SortedVector(std::move(installed_files)); } - static void print_plan(const std::map>& group_by_plan_type) - { - static constexpr std::array order = { - InstallPlanType::ALREADY_INSTALLED, InstallPlanType::BUILD_AND_INSTALL, InstallPlanType::INSTALL}; - - for (const InstallPlanType plan_type : order) - { - auto it = group_by_plan_type.find(plan_type); - if (it == group_by_plan_type.cend()) - { - continue; - } - - std::vector cont = it->second; - std::sort(cont.begin(), cont.end(), &InstallPlanAction::compare_by_name); - const std::string as_string = Strings::join("\n", cont, [](const InstallPlanAction* p) { - return Dependencies::to_output_string(p->request_type, p->spec.to_string()); - }); - - switch (plan_type) - { - case InstallPlanType::ALREADY_INSTALLED: - System::println("The following packages are already installed:\n%s", as_string); - continue; - case InstallPlanType::BUILD_AND_INSTALL: - System::println("The following packages will be built and installed:\n%s", as_string); - continue; - case InstallPlanType::INSTALL: - System::println("The following packages will be installed:\n%s", as_string); - continue; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - } - void install_package(const VcpkgPaths& paths, const BinaryControlFile& bcf, StatusParagraphs* status_db) { const fs::path package_dir = paths.package_dir(bcf.core_paragraph.spec); @@ -383,19 +344,78 @@ namespace vcpkg::Commands::Install Checks::unreachable(VCPKG_LINE_INFO); } - static void print_plan(const std::vector rebuilt_plans, - const std::vector new_plans) + static void print_plan(const std::vector& action_plan, bool is_recursive) { + std::vector remove_plans; + std::vector rebuilt_plans; + std::vector only_install_plans; + std::vector new_plans; + + const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { + if (auto iplan = package.install_plan.get()) + return iplan->request_type != RequestType::USER_REQUESTED; + else + return false; + }) != action_plan.cend(); + + for (auto&& action : action_plan) + { + if (auto install_action = action.install_plan.get()) + { + // remove plans are guaranteed to come before install plans, so we know the plan will be contained if at + // all. + auto it = Util::find_if( + remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); + if (it != remove_plans.end()) + { + rebuilt_plans.emplace_back(install_action); + } + else + { + if (install_action->plan_type == InstallPlanType::INSTALL) + only_install_plans.emplace_back(install_action); + else + new_plans.emplace_back(install_action); + } + } + else if (auto remove_action = action.remove_plan.get()) + { + remove_plans.emplace_back(remove_action); + } + } + + std::sort(remove_plans.begin(), remove_plans.end(), &RemovePlanAction::compare_by_name); + std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); + const std::string rebuilt_string = Strings::join("\n", rebuilt_plans, [](const InstallPlanAction* p) { - return Dependencies::to_output_string(p->request_type, p->displayname()); + return to_output_string(p->request_type, p->displayname()); }); + if (rebuilt_plans.size() > 0) System::println("The following packages will be rebuilt:\n%s", rebuilt_string); const std::string new_string = Strings::join("\n", new_plans, [](const InstallPlanAction* p) { - return Dependencies::to_output_string(p->request_type, p->displayname()); + return to_output_string(p->request_type, p->displayname()); }); + if (new_plans.size() > 0) + System::println("The following packages will be built and installed:\n%s", new_string); - if (rebuilt_plans.size() > 0) System::println("The following packages will be rebuilt:\n%s", rebuilt_string); - if (new_plans.size() > 0) System::println("The following packages will be installed:\n%s", new_string); + const std::string only_install_string = Strings::join("\n", only_install_plans, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname()); + }); + if (only_install_plans.size() > 0) + System::println("The following packages will be directly installed:\n%s", only_install_string); + + if (has_non_user_requested_packages) + System::println("Additional packages (*) will be installed to complete this operation."); + + if (remove_plans.size() > 0 && !is_recursive) + { + System::println(System::Color::warning, + "If you are sure you want to rebuild the above packages, run the command with the " + "--recurse option"); + Checks::exit_fail(VCPKG_LINE_INFO); + } } void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) @@ -410,86 +430,81 @@ namespace vcpkg::Commands::Install Commands::Help::create_example_string("install zlib zlib:x64-windows curl boost"); args.check_min_arg_count(1, example); - const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_package_spec(arg, default_triplet, example); + const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + return Input::check_and_get_full_package_spec(arg, default_triplet, example); }); + for (auto&& spec : specs) - Input::check_triplet(spec.triplet(), paths); + { + Input::check_triplet(spec.package_spec.triplet(), paths); + if (!spec.features.empty() && !g_feature_packages) + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "Feature packages are experimentally available under the --featurepackages flag."); + } + } const std::unordered_set options = args.check_and_get_optional_command_arguments( {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE}); const bool dryRun = options.find(OPTION_DRY_RUN) != options.cend(); const bool use_head_version = options.find(OPTION_USE_HEAD_VERSION) != options.cend(); const bool no_downloads = options.find(OPTION_NO_DOWNLOADS) != options.cend(); - const bool isRecursive = options.find(OPTION_RECURSE) != options.cend(); + const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); // create the plan StatusParagraphs status_db = database_load_check(paths); + const Build::BuildPackageOptions install_plan_options = {Build::to_use_head_version(use_head_version), + Build::to_allow_downloads(!no_downloads)}; + + std::vector action_plan; + if (g_feature_packages) { - const std::vector full_specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_full_package_spec(arg, default_triplet, example); - }); - - std::unordered_map scf_map; + std::unordered_map scf_map; auto all_ports = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); for (auto&& port : all_ports.paragraphs) { - auto pkg_spec = PackageSpec::from_name_and_triplet(port->core_paragraph->name, default_triplet) - .value_or_exit(VCPKG_LINE_INFO); - scf_map[pkg_spec] = std::move(*port); + scf_map[port->core_paragraph->name] = std::move(*port); } - std::vector action_plan = Dependencies::create_feature_install_plan( - scf_map, FullPackageSpec::to_feature_specs(full_specs), status_db); - // install plan will be empty if it is already installed - need to change this at status paragraph part - Checks::check_exit( - VCPKG_LINE_INFO, !action_plan.empty(), "Install plan cannot be empty for feature packages"); + action_plan = create_feature_install_plan(scf_map, FullPackageSpec::to_feature_specs(specs), status_db); + } + else + { + Dependencies::PathsPortFile paths_port_file(paths); + auto install_plan = Dependencies::create_install_plan( + paths_port_file, Util::fmap(specs, [](auto&& spec) { return spec.package_spec; }), status_db); - const Build::BuildPackageOptions install_plan_options = {Build::to_use_head_version(use_head_version), - Build::to_allow_downloads(!no_downloads)}; + action_plan = Util::fmap( + install_plan, [](InstallPlanAction& install_action) { return AnyAction(std::move(install_action)); }); + } - std::vector remove_plans; + // install plan will be empty if it is already installed - need to change this at status paragraph part + Checks::check_exit(VCPKG_LINE_INFO, !action_plan.empty(), "Install plan cannot be empty"); - std::vector rebuilt_plans; - std::vector new_plans; + // log the plan + const std::string specs_string = Strings::join(",", action_plan, [](const AnyAction& action) { + if (auto iaction = action.install_plan.get()) + return iaction->spec.to_string(); + else if (auto raction = action.remove_plan.get()) + return "R$" + raction->spec.to_string(); + Checks::unreachable(VCPKG_LINE_INFO); + }); + Metrics::track_property("installplan", specs_string); - // removal will happen before install - for (auto&& action : action_plan) + print_plan(action_plan, is_recursive); + + if (dryRun) + { + Checks::exit_success(VCPKG_LINE_INFO); + } + + // execute the plan + if (g_feature_packages) + { + for (const auto& action : action_plan) { if (auto install_action = action.install_plan.get()) - { - auto it = Util::find_if( - remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); - if (it != remove_plans.end()) - { - rebuilt_plans.emplace_back(install_action); - } - else - { - new_plans.emplace_back(install_action); - } - } - else if (auto remove_action = action.remove_plan.get()) - { - remove_plans.emplace_back(remove_action); - } - } - - print_plan(rebuilt_plans, new_plans); - - if (remove_plans.size() > 0 && !isRecursive) - { - System::println(System::Color::warning, - "If you are sure you want to rebuild the above packages, run the command with the " - "--recurse option"); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - // execute the plan - for (const Dependencies::AnyAction& any_action : action_plan) - { - if (auto install_action = any_action.install_plan.get()) { const BuildResult result = perform_install_plan_action(paths, *install_action, install_plan_options, status_db); @@ -499,7 +514,7 @@ namespace vcpkg::Commands::Install Checks::exit_fail(VCPKG_LINE_INFO); } } - else if (auto remove_action = any_action.remove_plan.get()) + else if (auto remove_action = action.remove_plan.get()) { static const std::string OPTION_PURGE = "--purge"; static const std::string OPTION_NO_PURGE = "--no-purge"; @@ -537,50 +552,18 @@ namespace vcpkg::Commands::Install } } } - - Checks::exit_success(VCPKG_LINE_INFO); } - - Dependencies::PathsPortFile paths_port_file(paths); - std::vector install_plan = - Dependencies::create_install_plan(paths_port_file, specs, status_db); - Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); - - // log the plan - const std::string specs_string = - Strings::join(",", install_plan, [](const InstallPlanAction& plan) { return plan.spec.to_string(); }); - Metrics::track_property("installplan", specs_string); - - std::map> group_by_plan_type; - Util::group_by(install_plan, &group_by_plan_type, [](const InstallPlanAction& p) { return p.plan_type; }); - print_plan(group_by_plan_type); - - const bool has_non_user_requested_packages = - Util::find_if(install_plan, [](const InstallPlanAction& package) -> bool { - return package.request_type != RequestType::USER_REQUESTED; - }) != install_plan.cend(); - - if (has_non_user_requested_packages) + else { - System::println("Additional packages (*) will be installed to complete this operation."); - } - - if (dryRun) - { - Checks::exit_success(VCPKG_LINE_INFO); - } - - const Build::BuildPackageOptions install_plan_options = {Build::to_use_head_version(use_head_version), - Build::to_allow_downloads(!no_downloads)}; - - // execute the plan - for (const InstallPlanAction& action : install_plan) - { - const BuildResult result = perform_install_plan_action(paths, action, install_plan_options, status_db); - if (result != BuildResult::SUCCEEDED) + for (const auto& action : action_plan) { - System::println(Build::create_user_troubleshooting_message(action.spec)); - Checks::exit_fail(VCPKG_LINE_INFO); + const auto& iaction = action.install_plan.value_or_exit(VCPKG_LINE_INFO); + const BuildResult result = perform_install_plan_action(paths, iaction, install_plan_options, status_db); + if (result != BuildResult::SUCCEEDED) + { + System::println(Build::create_user_troubleshooting_message(iaction.spec)); + Checks::exit_fail(VCPKG_LINE_INFO); + } } } diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp index f0884c063..939351872 100644 --- a/toolsrc/src/test_install_plan.cpp +++ b/toolsrc/src/test_install_plan.cpp @@ -12,7 +12,7 @@ namespace UnitTest1 { struct PackageSpecMap { - std::unordered_map map; + std::unordered_map map; Triplet triplet; PackageSpecMap(const Triplet& t) { triplet = t; } @@ -24,7 +24,7 @@ namespace UnitTest1 auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, triplet); Assert::IsTrue(spec.has_value()); - map.emplace(*spec.get(), std::move(*scf.get())); + map.emplace(scf->core_paragraph->name, std::move(*scf.get())); return PackageSpec{*spec.get()}; } PackageSpec set_package_map(std::string source, std::string version, std::string build_depends) diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 8f92179b5..abab359bb 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -63,24 +63,51 @@ namespace vcpkg::Dependencies struct ClusterGraph { - explicit ClusterGraph(std::unordered_map&& graph) : m_graph(std::move(graph)) {} + explicit ClusterGraph(std::unordered_map&& ports) + : m_ports(std::move(ports)) + { + } ClusterGraph(ClusterGraph&&) = default; Cluster& get(const PackageSpec& spec) - { - if (auto p = try_get(spec)) return *p; - Checks::exit_with_message(VCPKG_LINE_INFO, "error: reference to missing package: %s", spec); - } - Cluster* try_get(const PackageSpec& spec) { auto it = m_graph.find(spec); - if (it == m_graph.end()) return nullptr; - return &it->second; + if (it == m_graph.end()) + { + // Load on-demand from m_ports + auto it_ports = m_ports.find(spec.name()); + if (it_ports != m_ports.end()) + { + auto& clust = m_graph[spec]; + clust.spec = spec; + cluster_from_scf(*it_ports->second, clust); + return clust; + } + return m_graph[spec]; + } + return it->second; } private: + void cluster_from_scf(const SourceControlFile& scf, Cluster& out_cluster) + { + FeatureNodeEdges core_dependencies; + core_dependencies.build_edges = + filter_dependencies_to_specs(scf.core_paragraph->depends, out_cluster.spec.triplet()); + out_cluster.edges.emplace("core", std::move(core_dependencies)); + + for (const auto& feature : scf.feature_paragraphs) + { + FeatureNodeEdges added_edges; + added_edges.build_edges = filter_dependencies_to_specs(feature->depends, out_cluster.spec.triplet()); + out_cluster.edges.emplace(feature->name, std::move(added_edges)); + } + out_cluster.source_control_file = &scf; + } + ClusterGraph(const ClusterGraph&) = delete; std::unordered_map m_graph; + std::unordered_map m_ports; }; std::vector AnyParagraph::dependencies(const Triplet& triplet) const @@ -243,9 +270,9 @@ namespace vcpkg::Dependencies return left->spec.name() < right->spec.name(); } - MapPortFile::MapPortFile(const std::unordered_map& map) : ports(map) {} + MapPortFile::MapPortFile(const std::unordered_map& map) : ports(map) {} - const SourceControlFile& MapPortFile::get_control_file(const PackageSpec& spec) const + const SourceControlFile& MapPortFile::get_control_file(const std::string& spec) const { auto scf = ports.find(spec); if (scf == ports.end()) @@ -257,9 +284,9 @@ namespace vcpkg::Dependencies PathsPortFile::PathsPortFile(const VcpkgPaths& paths) : ports(paths) {} - const SourceControlFile& PathsPortFile::get_control_file(const PackageSpec& spec) const + const SourceControlFile& PathsPortFile::get_control_file(const std::string& spec) const { - std::unordered_map::iterator cache_it = cache.find(spec); + auto cache_it = cache.find(spec); if (cache_it != cache.end()) { return cache_it->second; @@ -307,7 +334,9 @@ namespace vcpkg::Dependencies auto it = status_db.find_installed(spec); if (it != status_db.end()) return InstallPlanAction{spec, {*it->get(), nullopt, nullopt}, request_type}; return InstallPlanAction{ - spec, {nullopt, nullopt, *port_file_provider.get_control_file(spec).core_paragraph}, request_type}; + spec, + {nullopt, nullopt, *port_file_provider.get_control_file(spec.name()).core_paragraph}, + request_type}; } }; @@ -504,35 +533,19 @@ namespace vcpkg::Dependencies } } - static ClusterGraph create_feature_install_graph(const std::unordered_map& map, + static ClusterGraph create_feature_install_graph(const std::unordered_map& map, const StatusParagraphs& status_db) { - std::unordered_map graph; - - for (const auto& it : map) - { - Cluster& node = graph[it.first]; - - node.spec = it.first; - FeatureNodeEdges core_dependencies; - core_dependencies.build_edges = - filter_dependencies_to_specs(it.second.core_paragraph->depends, node.spec.triplet()); - node.edges.emplace("core", std::move(core_dependencies)); - - for (const auto& feature : it.second.feature_paragraphs) - { - FeatureNodeEdges added_edges; - added_edges.build_edges = filter_dependencies_to_specs(feature->depends, node.spec.triplet()); - node.edges.emplace(feature->name, std::move(added_edges)); - } - node.source_control_file = &it.second; - } + std::unordered_map ptr_map; + for (auto&& p : map) + ptr_map.emplace(p.first, &p.second); + ClusterGraph graph(std::move(ptr_map)); auto installed_ports = get_installed_ports(status_db); for (auto&& status_paragraph : installed_ports) { - Cluster& cluster = graph[status_paragraph->package.spec]; + Cluster& cluster = graph.get(status_paragraph->package.spec); cluster.transient_uninstalled = false; @@ -559,20 +572,19 @@ namespace vcpkg::Dependencies for (auto&& dependency : reverse_edges) { - auto dep_cluster = graph.find(dependency.spec()); - if (dep_cluster == graph.end()) Checks::unreachable(VCPKG_LINE_INFO); + auto& dep_cluster = graph.get(dependency.spec()); auto depends_name = dependency.feature(); if (depends_name == "") depends_name = "core"; - auto& target_node = dep_cluster->second.edges[depends_name]; + auto& target_node = dep_cluster.edges[depends_name]; target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); } } - return ClusterGraph(std::move(graph)); + return graph; } - std::vector create_feature_install_plan(const std::unordered_map& map, + std::vector create_feature_install_plan(const std::unordered_map& map, const std::vector& specs, const StatusParagraphs& status_db) { @@ -598,15 +610,13 @@ namespace vcpkg::Dependencies for (auto&& like_cluster : remove_toposort) { auto scf = *like_cluster.ptr->source_control_file.get(); - - AnyAction any_plan; - any_plan.remove_plan = RemovePlanAction{ - PackageSpec::from_name_and_triplet(scf->core_paragraph->name, like_cluster.ptr->spec.triplet()) - .value_or_exit(VCPKG_LINE_INFO), + auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, like_cluster.ptr->spec.triplet()) + .value_or_exit(VCPKG_LINE_INFO); + install_plan.emplace_back(RemovePlanAction{ + std::move(spec), RemovePlanType::REMOVE, - RequestType::AUTO_SELECTED}; - - install_plan.emplace_back(std::move(any_plan)); + RequestType::AUTO_SELECTED, + }); } for (auto&& like_cluster : insert_toposort) @@ -617,12 +627,12 @@ namespace vcpkg::Dependencies auto pkg_spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, like_cluster.ptr->spec.triplet()) .value_or_exit(VCPKG_LINE_INFO); - auto action = - InstallPlanAction{pkg_spec, *scf, like_cluster.ptr->to_install_features, RequestType::AUTO_SELECTED}; - - AnyAction any_plan; - any_plan.install_plan = std::move(action); - install_plan.emplace_back(std::move(any_plan)); + install_plan.emplace_back(InstallPlanAction{ + pkg_spec, + *scf, + like_cluster.ptr->to_install_features, + RequestType::AUTO_SELECTED, + }); } return install_plan;