[vcpkg-ci] Fix bug in "vcpkg ci" which results in different features being installed than originally desired.
MODIFY
include/vcpkg/commands.h
include/vcpkg/commands.h
@@ -25,17 +25,7 @@ namespace vcpkg::Commands
namespace CI
{
- struct UnknownCIPortsResults
- {
- std::vector<PackageSpec> unknown;
- std::map<PackageSpec, Build::BuildResult> known;
- };
-
extern const CommandStructure COMMAND_STRUCTURE;
- UnknownCIPortsResults find_unknown_ports_for_ci(const VcpkgPaths& paths,
- const std::set<std::string>& exclusions,
- const Dependencies::PortFileProvider& provider,
- const std::vector<FeatureSpec>& fspecs);
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
}

MODIFY
src/vcpkg/commands.ci.cpp
src/vcpkg/commands.ci.cpp
@@ -46,7 +46,14 @@ namespace vcpkg::Commands::CI
nullptr,
};
- UnknownCIPortsResults find_unknown_ports_for_ci(const VcpkgPaths& paths,
+ struct UnknownCIPortsResults
+ {
+ std::vector<FullPackageSpec> unknown;
+ std::map<PackageSpec, Build::BuildResult> known;
+ std::map<PackageSpec, std::vector<std::string>> features;
+ };
+
+ static UnknownCIPortsResults find_unknown_ports_for_ci(const VcpkgPaths& paths,
const std::set<std::string>& exclusions,
const Dependencies::PortFileProvider& provider,
const std::vector<FeatureSpec>& fspecs)
@@ -121,6 +128,8 @@ namespace vcpkg::Commands::CI
bool b_will_build = false;
+ ret.features.emplace(p->spec, std::vector<std::string>{p->feature_list.begin(), p->feature_list.end()});
+
if (Util::Sets::contains(exclusions, p->spec.name()))
{
ret.known.emplace(p->spec, BuildResult::EXCLUDED);
@@ -146,7 +155,7 @@ namespace vcpkg::Commands::CI
}
else
{
- ret.unknown.push_back(p->spec);
+ ret.unknown.push_back({p->spec, {p->feature_list.begin(), p->feature_list.end()}});
b_will_build = true;
}
@@ -208,13 +217,23 @@ namespace vcpkg::Commands::CI
{
Input::check_triplet(triplet, paths);
+ Dependencies::PackageGraph pgraph(paths_port_file, status_db);
+
std::vector<PackageSpec> specs = PackageSpec::to_package_specs(all_ports, triplet);
// Install the default features for every package
auto all_fspecs = Util::fmap(specs, [](auto& spec) { return FeatureSpec(spec, ""); });
auto split_specs = find_unknown_ports_for_ci(paths, exclusions_set, paths_port_file, all_fspecs);
- auto fspecs = Util::fmap(split_specs.unknown, [](auto& spec) { return FeatureSpec(spec, ""); });
+ auto fspecs = FullPackageSpec::to_feature_specs(split_specs.unknown);
- auto action_plan = Dependencies::create_feature_install_plan(paths_port_file, fspecs, status_db);
+ for (auto&& fspec : fspecs)
+ pgraph.install(fspec);
+
+ auto action_plan = [&]() {
+ int iterations = 0;
+ do
+ {
+ bool inconsistent = false;
+ auto action_plan = pgraph.serialize();
for (auto&& action : action_plan)
{
@@ -225,8 +244,20 @@ namespace vcpkg::Commands::CI
{
p->plan_type = InstallPlanType::EXCLUDED;
}
+
+ for (auto&& feature : split_specs.features[p->spec])
+ if (p->feature_list.find(feature) == p->feature_list.end())
+ {
+ pgraph.install({p->spec, feature});
+ inconsistent = true;
}
}
+ }
+
+ if (!inconsistent) return action_plan;
+ Checks::check_exit(VCPKG_LINE_INFO, ++iterations < 100);
+ } while (true);
+ }();
if (is_dry_run)
{

[vcpkg-ci] Fix bug in "vcpkg ci" which results in different features being installed than originally desired.