[vcpkg] Fix feature packages for non-default triplets. Reduce duplication between normal installs and feature installs.

This commit is contained in:
Robert Schumacher 2017-08-21 17:16:14 -07:00
parent c7de717cbc
commit 27be8b5c74
7 changed files with 208 additions and 210 deletions

View File

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

View File

@ -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<InstallPlanAction> install_plan;
Optional<RemovePlanAction> 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<PackageSpec, SourceControlFile>& ports;
explicit MapPortFile(const std::unordered_map<PackageSpec, SourceControlFile>& map);
const SourceControlFile& get_control_file(const PackageSpec& spec) const override;
const std::unordered_map<std::string, SourceControlFile>& ports;
explicit MapPortFile(const std::unordered_map<std::string, SourceControlFile>& map);
const SourceControlFile& get_control_file(const std::string& spec) const override;
};
struct PathsPortFile : PortFileProvider
{
const VcpkgPaths& ports;
mutable std::unordered_map<PackageSpec, SourceControlFile> cache;
mutable std::unordered_map<std::string, SourceControlFile> 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<PackageSpec>& specs,
const StatusParagraphs& status_db);
std::vector<AnyAction> create_feature_install_plan(const std::unordered_map<PackageSpec, SourceControlFile>& map,
std::vector<AnyAction> create_feature_install_plan(const std::unordered_map<std::string, SourceControlFile>& map,
const std::vector<FeatureSpec>& specs,
const StatusParagraphs& status_db);
}

View File

@ -7,12 +7,12 @@
namespace vcpkg::Util
{
template<class Cont, class Func>
using FmapOut = decltype(std::declval<Func>()(std::declval<Cont>()[0]));
using FmapOut = decltype(std::declval<Func>()(*begin(std::declval<Cont>())));
template<class Cont, class Func, class Out = FmapOut<Cont, Func>>
std::vector<Out> fmap(const Cont& xs, Func&& f)
std::vector<Out> fmap(Cont&& xs, Func&& f)
{
using O = decltype(f(xs[0]));
using O = decltype(f(*begin(xs)));
std::vector<O> ret;
ret.reserve(xs.size());

View File

@ -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
{

View File

@ -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::string>(std::move(installed_files));
}
static void print_plan(const std::map<InstallPlanType, std::vector<const InstallPlanAction*>>& group_by_plan_type)
{
static constexpr std::array<InstallPlanType, 3> 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<const InstallPlanAction*> 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<const InstallPlanAction*> rebuilt_plans,
const std::vector<const InstallPlanAction*> new_plans)
static void print_plan(const std::vector<AnyAction>& action_plan, bool is_recursive)
{
std::vector<const RemovePlanAction*> remove_plans;
std::vector<const InstallPlanAction*> rebuilt_plans;
std::vector<const InstallPlanAction*> only_install_plans;
std::vector<const InstallPlanAction*> 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<PackageSpec> specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
return Input::check_and_get_package_spec(arg, default_triplet, example);
const std::vector<FullPackageSpec> 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<std::string> 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<AnyAction> action_plan;
if (g_feature_packages)
{
const std::vector<FullPackageSpec> full_specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
return Input::check_and_get_full_package_spec(arg, default_triplet, example);
});
std::unordered_map<PackageSpec, SourceControlFile> scf_map;
std::unordered_map<std::string, SourceControlFile> 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<Dependencies::AnyAction> 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<const RemovePlanAction*> 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<const InstallPlanAction*> rebuilt_plans;
std::vector<const InstallPlanAction*> 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<InstallPlanAction> 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<InstallPlanType, std::vector<const InstallPlanAction*>> 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);
}
}
}

View File

@ -12,7 +12,7 @@ namespace UnitTest1
{
struct PackageSpecMap
{
std::unordered_map<PackageSpec, SourceControlFile> map;
std::unordered_map<std::string, SourceControlFile> 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)

View File

@ -63,24 +63,51 @@ namespace vcpkg::Dependencies
struct ClusterGraph
{
explicit ClusterGraph(std::unordered_map<PackageSpec, Cluster>&& graph) : m_graph(std::move(graph)) {}
explicit ClusterGraph(std::unordered_map<std::string, const SourceControlFile*>&& 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<PackageSpec, Cluster> m_graph;
std::unordered_map<std::string, const SourceControlFile*> m_ports;
};
std::vector<PackageSpec> 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<PackageSpec, SourceControlFile>& map) : ports(map) {}
MapPortFile::MapPortFile(const std::unordered_map<std::string, SourceControlFile>& 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<PackageSpec, SourceControlFile>::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<PackageSpec, SourceControlFile>& map,
static ClusterGraph create_feature_install_graph(const std::unordered_map<std::string, SourceControlFile>& map,
const StatusParagraphs& status_db)
{
std::unordered_map<PackageSpec, Cluster> 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<std::string, const SourceControlFile*> 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<AnyAction> create_feature_install_plan(const std::unordered_map<PackageSpec, SourceControlFile>& map,
std::vector<AnyAction> create_feature_install_plan(const std::unordered_map<std::string, SourceControlFile>& map,
const std::vector<FeatureSpec>& 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;