[vcpkg] Add support for --overlay-ports to versioning
MODIFY
include/vcpkg/dependencies.h
include/vcpkg/dependencies.h
@@ -178,6 +178,7 @@ namespace vcpkg::Dependencies
/// <param name="status_db">Status of installed packages in the current environment.</param>
ExpectedS<ActionPlan> create_versioned_install_plan(const PortFileProvider::IVersionedPortfileProvider& vprovider,
const PortFileProvider::IBaselineProvider& bprovider,
+ const PortFileProvider::IOverlayProvider& oprovider,
const CMakeVars::CMakeVarProvider& var_provider,
const std::vector<Dependency>& deps,
const std::vector<DependencyOverride>& overrides,

MODIFY
include/vcpkg/fwd/portfileprovider.h
include/vcpkg/fwd/portfileprovider.h
@@ -6,4 +6,5 @@ namespace vcpkg::PortFileProvider
struct PathsPortFileProvider;
struct IVersionedPortfileProvider;
struct IBaselineProvider;
+ struct IOverlayProvider;
}

MODIFY
include/vcpkg/portfileprovider.h
include/vcpkg/portfileprovider.h
@@ -55,6 +55,14 @@ namespace vcpkg::PortFileProvider
virtual ~IBaselineProvider() = default;
};
- std::unique_ptr<IBaselineProvider> make_baseline_provider(const VcpkgPaths&);
- std::unique_ptr<IVersionedPortfileProvider> make_versioned_portfile_provider(const VcpkgPaths&);
+ struct IOverlayProvider
+ {
+ virtual ~IOverlayProvider() = default;
+ virtual Optional<const SourceControlFileLocation&> get_control_file(StringView port_name) const = 0;
+ };
+
+ std::unique_ptr<IBaselineProvider> make_baseline_provider(const vcpkg::VcpkgPaths& paths);
+ std::unique_ptr<IVersionedPortfileProvider> make_versioned_portfile_provider(const vcpkg::VcpkgPaths& paths);
+ std::unique_ptr<IOverlayProvider> make_overlay_provider(const vcpkg::VcpkgPaths& paths,
+ View<std::string> overlay_ports);
}

MODIFY
src/vcpkg-test/dependencies.cpp
src/vcpkg-test/dependencies.cpp
@@ -160,6 +160,54 @@ static const PackageSpec& toplevel_spec()
return ret;
}
+struct MockOverlayProvider : PortFileProvider::IOverlayProvider, Util::ResourceBase
+{
+ virtual Optional<const SourceControlFileLocation&> get_control_file(StringView name) const override
+ {
+ auto it = mappings.find(name);
+ if (it != mappings.end())
+ return it->second;
+ else
+ return nullopt;
+ }
+
+ SourceControlFileLocation& emplace(const std::string& name,
+ Versions::Version&& version,
+ Versions::Scheme scheme = Versions::Scheme::String)
+ {
+ auto it = mappings.find(name);
+ if (it == mappings.end())
+ {
+ auto scf = std::make_unique<SourceControlFile>();
+ auto core = std::make_unique<SourceParagraph>();
+ core->name = name;
+ core->version = version.text();
+ core->port_version = version.port_version();
+ core->version_scheme = scheme;
+ scf->core_paragraph = std::move(core);
+ it = mappings.emplace(name, SourceControlFileLocation{std::move(scf), fs::u8path(name)}).first;
+ }
+ return it->second;
+ }
+
+private:
+ std::map<std::string, SourceControlFileLocation, std::less<>> mappings;
+};
+
+static const MockOverlayProvider s_empty_mock_overlay;
+
+ExpectedS<Dependencies::ActionPlan> create_versioned_install_plan(
+ const PortFileProvider::IVersionedPortfileProvider& provider,
+ const PortFileProvider::IBaselineProvider& bprovider,
+ const CMakeVars::CMakeVarProvider& var_provider,
+ const std::vector<Dependency>& deps,
+ const std::vector<DependencyOverride>& overrides,
+ const PackageSpec& toplevel)
+{
+ return Dependencies::create_versioned_install_plan(
+ provider, bprovider, s_empty_mock_overlay, var_provider, deps, overrides, toplevel);
+}
+
TEST_CASE ("basic version install single", "[versionplan]")
{
MockBaselineProvider bp;
@@ -170,8 +218,7 @@ TEST_CASE ("basic version install single", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan =
- unwrap(Dependencies::create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec()));
+ auto install_plan = unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec()));
REQUIRE(install_plan.size() == 1);
REQUIRE(install_plan.install_actions.at(0).spec.name() == "a");
@@ -193,7 +240,7 @@ TEST_CASE ("basic version install detect cycle", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan = Dependencies::create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec());
+ auto install_plan = create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec());
REQUIRE(!install_plan.has_value());
}
@@ -212,8 +259,7 @@ TEST_CASE ("basic version install scheme", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan =
- unwrap(Dependencies::create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec()));
+ auto install_plan = unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec()));
CHECK(install_plan.size() == 2);
@@ -248,8 +294,7 @@ TEST_CASE ("basic version install scheme diamond", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan =
- unwrap(Dependencies::create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec()));
+ auto install_plan = unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec()));
CHECK(install_plan.size() == 4);
@@ -269,7 +314,7 @@ TEST_CASE ("basic version install scheme baseline missing", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan = Dependencies::create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec());
+ auto install_plan = create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec());
REQUIRE(!install_plan.has_value());
}
@@ -286,7 +331,7 @@ TEST_CASE ("basic version install scheme baseline missing success", "[versionpla
MockCMakeVarProvider var_provider;
auto install_plan =
- unwrap(Dependencies::create_versioned_install_plan(vp,
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -311,8 +356,7 @@ TEST_CASE ("basic version install scheme baseline", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan =
- unwrap(Dependencies::create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec()));
+ auto install_plan = unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "a", {"2", 0});
@@ -330,7 +374,7 @@ TEST_CASE ("version string baseline agree", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan = Dependencies::create_versioned_install_plan(
+ auto install_plan = create_versioned_install_plan(
vp, bp, var_provider, {Dependency{"a", {}, {}, {Constraint::Type::Exact, "2"}}}, {}, toplevel_spec());
REQUIRE(install_plan.has_value());
@@ -348,8 +392,7 @@ TEST_CASE ("version install scheme baseline conflict", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan =
- Dependencies::create_versioned_install_plan(vp,
+ auto install_plan = create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -373,8 +416,8 @@ TEST_CASE ("version install string port version", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -399,8 +442,8 @@ TEST_CASE ("version install string port version 2", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -430,8 +473,8 @@ TEST_CASE ("version install transitive string", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -456,8 +499,8 @@ TEST_CASE ("version install simple relaxed", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -486,8 +529,8 @@ TEST_CASE ("version install transitive relaxed", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -522,8 +565,8 @@ TEST_CASE ("version install diamond relaxed", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -739,8 +782,8 @@ TEST_CASE ("version install simple semver", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
- vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -769,8 +812,8 @@ TEST_CASE ("version install transitive semver", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
- vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -805,8 +848,8 @@ TEST_CASE ("version install diamond semver", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
- vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -833,8 +876,8 @@ TEST_CASE ("version install simple date", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
- vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -863,8 +906,8 @@ TEST_CASE ("version install transitive date", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
- vp,
+ auto install_plan = unwrap(
+ create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -899,8 +942,8 @@ TEST_CASE ("version install diamond date", "[versionplan]")
MockCMakeVarProvider var_provider;
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
- vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -930,8 +973,8 @@ TEST_CASE ("version install scheme failure", "[versionplan]")
MockBaselineProvider bp;
bp.v["a"] = {"1.0.0", 0};
- auto install_plan = Dependencies::create_versioned_install_plan(
- vp,
+ auto install_plan =
+ create_versioned_install_plan(vp,
bp,
var_provider,
{Dependency{"a", {}, {}, {Constraint::Type::Minimum, "1.0.1", 0}}},
@@ -946,8 +989,8 @@ TEST_CASE ("version install scheme failure", "[versionplan]")
MockBaselineProvider bp;
bp.v["a"] = {"1.0.2", 0};
- auto install_plan = Dependencies::create_versioned_install_plan(
- vp,
+ auto install_plan =
+ create_versioned_install_plan(vp,
bp,
var_provider,
{Dependency{"a", {}, {}, {Constraint::Type::Minimum, "1.0.1", 0}}},
@@ -978,8 +1021,8 @@ TEST_CASE ("version install scheme change in port version", "[versionplan]")
MockBaselineProvider bp;
bp.v["a"] = {"2", 0};
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -997,8 +1040,8 @@ TEST_CASE ("version install scheme change in port version", "[versionplan]")
MockBaselineProvider bp;
bp.v["a"] = {"2", 1};
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -1027,7 +1070,7 @@ TEST_CASE ("version install simple feature", "[versionplan]")
MockBaselineProvider bp;
bp.v["a"] = {"1", 0};
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(vp,
+ auto install_plan = unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -1044,8 +1087,8 @@ TEST_CASE ("version install simple feature", "[versionplan]")
{
MockBaselineProvider bp;
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
- vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -1083,7 +1126,7 @@ TEST_CASE ("version install transitive features", "[versionplan]")
bp.v["a"] = {"1", 0};
bp.v["b"] = {"1", 0};
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(vp,
+ auto install_plan = unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -1123,7 +1166,7 @@ TEST_CASE ("version install transitive feature versioned", "[versionplan]")
bp.v["a"] = {"1", 0};
bp.v["c"] = {"1", 0};
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(vp,
+ auto install_plan = unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -1161,8 +1204,8 @@ TEST_CASE ("version install constraint-reduction", "[versionplan]")
bp.v["b"] = {"2", 0};
bp.v["c"] = {"1", 0};
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -1195,8 +1238,8 @@ TEST_CASE ("version install constraint-reduction", "[versionplan]")
bp.v["b"] = {"1", 0};
bp.v["c"] = {"1", 0};
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
@@ -1228,8 +1271,8 @@ TEST_CASE ("version install overrides", "[versionplan]")
SECTION ("string")
{
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{Dependency{"c"}},
@@ -1242,8 +1285,8 @@ TEST_CASE ("version install overrides", "[versionplan]")
SECTION ("relaxed")
{
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp,
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{Dependency{"b"}},
@@ -1272,7 +1315,7 @@ TEST_CASE ("version install transitive overrides", "[versionplan]")
bp.v["c"] = {"2", 1};
auto install_plan =
- unwrap(Dependencies::create_versioned_install_plan(vp,
+ unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{Dependency{"b"}},
@@ -1298,8 +1341,8 @@ TEST_CASE ("version install default features", "[versionplan]")
MockBaselineProvider bp;
bp.v["a"] = {"1", 0};
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp, bp, var_provider, {Dependency{"a"}}, {}, toplevel_spec()));
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp, bp, var_provider, {Dependency{"a"}}, {}, toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}, {"x"});
@@ -1319,8 +1362,8 @@ TEST_CASE ("version dont install default features", "[versionplan]")
MockBaselineProvider bp;
bp.v["a"] = {"1", 0};
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
- vp, bp, var_provider, {Dependency{"a", {"core"}}}, {}, toplevel_spec()));
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp, bp, var_provider, {Dependency{"a", {"core"}}}, {}, toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "a", {"1", 0});
@@ -1344,8 +1387,8 @@ TEST_CASE ("version install transitive default features", "[versionplan]")
bp.v["a"] = {"1", 0};
bp.v["b"] = {"1", 0};
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp, bp, var_provider, {Dependency{"b"}}, {}, toplevel_spec()));
+ auto install_plan =
+ unwrap(create_versioned_install_plan(vp, bp, var_provider, {Dependency{"b"}}, {}, toplevel_spec()));
REQUIRE(install_plan.size() == 2);
check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}, {"x"});
@@ -1373,8 +1416,8 @@ TEST_CASE ("version install qualified dependencies", "[versionplan]")
MockCMakeVarProvider var_provider;
var_provider.dep_info_vars[toplevel_spec()] = {{"VCPKG_CMAKE_SYSTEM_NAME", "Windows"}};
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
- vp,
+ auto install_plan = unwrap(
+ create_versioned_install_plan(vp,
bp,
var_provider,
{{"b", {}, parse_platform("!linux")}, {"c", {}, parse_platform("linux")}},
@@ -1390,8 +1433,8 @@ TEST_CASE ("version install qualified dependencies", "[versionplan]")
MockCMakeVarProvider var_provider;
var_provider.dep_info_vars[toplevel_spec()] = {{"VCPKG_CMAKE_SYSTEM_NAME", "Linux"}};
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
- vp,
+ auto install_plan = unwrap(
+ create_versioned_install_plan(vp,
bp,
var_provider,
{{"b", {}, parse_platform("!linux")}, {"c", {}, parse_platform("linux")}},
@@ -1420,8 +1463,8 @@ TEST_CASE ("version install qualified default suppression", "[versionplan]")
bp.v["a"] = {"1", 0};
bp.v["b"] = {"1", 0};
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
- vp,
+ auto install_plan = unwrap(
+ create_versioned_install_plan(vp,
bp,
var_provider,
{{"b", {}, parse_platform("!linux")}, {"a", {"core"}, parse_platform("linux")}},
@@ -1451,8 +1494,7 @@ TEST_CASE ("version install qualified transitive", "[versionplan]")
bp.v["b"] = {"1", 0};
bp.v["c"] = {"1", 0};
- auto install_plan =
- unwrap(Dependencies::create_versioned_install_plan(vp, bp, var_provider, {{"b"}}, {}, toplevel_spec()));
+ auto install_plan = unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"b"}}, {}, toplevel_spec()));
REQUIRE(install_plan.size() == 2);
check_name_and_version(install_plan.install_actions[0], "a", {"1", 0});
@@ -1479,8 +1521,7 @@ TEST_CASE ("version install different vars", "[versionplan]")
bp.v["b"] = {"1", 0};
bp.v["c"] = {"1", 0};
- auto install_plan =
- unwrap(Dependencies::create_versioned_install_plan(vp, bp, var_provider, {{"b"}}, {}, toplevel_spec()));
+ auto install_plan = unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"b"}}, {}, toplevel_spec()));
REQUIRE(install_plan.size() == 3);
check_name_and_version(install_plan.install_actions[0], "c", {"1", 0});
@@ -1518,8 +1559,7 @@ TEST_CASE ("version install qualified features", "[versionplan]")
bp.v["c"] = {"1", 0};
bp.v["d"] = {"1", 0};
- auto install_plan =
- unwrap(Dependencies::create_versioned_install_plan(vp, bp, var_provider, {{"b"}}, {}, toplevel_spec()));
+ auto install_plan = unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"b"}}, {}, toplevel_spec()));
REQUIRE(install_plan.size() == 3);
check_name_and_version(install_plan.install_actions[0], "c", {"1", 0}, {"z"});
@@ -1542,8 +1582,121 @@ TEST_CASE ("version install self features", "[versionplan]")
MockCMakeVarProvider var_provider;
auto install_plan =
- unwrap(Dependencies::create_versioned_install_plan(vp, bp, var_provider, {{"a", {"x"}}}, {}, toplevel_spec()));
+ unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"a", {"x"}}}, {}, toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}, {"x", "y"});
}
+
+TEST_CASE ("version overlay ports", "[versionplan]")
+{
+ MockBaselineProvider bp;
+ bp.v["a"] = {"1", 0};
+ bp.v["b"] = {"1", 0};
+ bp.v["c"] = {"1", 0};
+
+ MockVersionedPortfileProvider vp;
+ vp.emplace("a", {"1", 0});
+ vp.emplace("a", {"1", 1});
+ vp.emplace("a", {"2", 0});
+ vp.emplace("b", {"1", 0}).source_control_file->core_paragraph->dependencies.emplace_back(Dependency{"a"});
+ vp.emplace("c", {"1", 0})
+ .source_control_file->core_paragraph->dependencies.emplace_back(
+ Dependency{"a", {}, {}, {Constraint::Type::Minimum, "1", 1}});
+
+ MockCMakeVarProvider var_provider;
+
+ MockOverlayProvider oprovider;
+ oprovider.emplace("a", {"overlay", 0});
+
+ SECTION ("no baseline")
+ {
+ const MockBaselineProvider empty_bp;
+
+ auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
+ vp, empty_bp, oprovider, var_provider, {{"a"}}, {}, toplevel_spec()));
+
+ REQUIRE(install_plan.size() == 1);
+ check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0});
+ }
+
+ SECTION ("transitive")
+ {
+ auto install_plan = unwrap(
+ Dependencies::create_versioned_install_plan(vp, bp, oprovider, var_provider, {{"b"}}, {}, toplevel_spec()));
+
+ REQUIRE(install_plan.size() == 2);
+ check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0});
+ check_name_and_version(install_plan.install_actions[1], "b", {"1", 0});
+ }
+
+ SECTION ("transitive constraint")
+ {
+ auto install_plan = unwrap(
+ Dependencies::create_versioned_install_plan(vp, bp, oprovider, var_provider, {{"c"}}, {}, toplevel_spec()));
+
+ REQUIRE(install_plan.size() == 2);
+ check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0});
+ check_name_and_version(install_plan.install_actions[1], "c", {"1", 0});
+ }
+
+ SECTION ("none")
+ {
+ auto install_plan = unwrap(
+ Dependencies::create_versioned_install_plan(vp, bp, oprovider, var_provider, {{"a"}}, {}, toplevel_spec()));
+
+ REQUIRE(install_plan.size() == 1);
+ check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0});
+ }
+ SECTION ("constraint")
+ {
+ auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
+ vp,
+ bp,
+ oprovider,
+ var_provider,
+ {
+ Dependency{"a", {}, {}, {Constraint::Type::Minimum, "1", 1}},
+ },
+ {},
+ toplevel_spec()));
+
+ REQUIRE(install_plan.size() == 1);
+ check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0});
+ }
+ SECTION ("constraint+override")
+ {
+ auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
+ vp,
+ bp,
+ oprovider,
+ var_provider,
+ {
+ Dependency{"a", {}, {}, {Constraint::Type::Minimum, "1", 1}},
+ },
+ {
+ DependencyOverride{"a", {"2", 0}},
+ },
+ toplevel_spec()));
+
+ REQUIRE(install_plan.size() == 1);
+ check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0});
+ }
+ SECTION ("override")
+ {
+ auto install_plan = unwrap(Dependencies::create_versioned_install_plan(vp,
+ bp,
+ oprovider,
+ var_provider,
+ {
+ Dependency{"a"},
+ },
+ {
+ DependencyOverride{"a", {"2", 0}},
+ },
+ toplevel_spec()));
+
+ REQUIRE(install_plan.size() == 1);
+ check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0});
+ }
+}

MODIFY
src/vcpkg/dependencies.cpp
src/vcpkg/dependencies.cpp
@@ -1173,8 +1173,12 @@ namespace vcpkg::Dependencies
public:
VersionedPackageGraph(const IVersionedPortfileProvider& ver_provider,
const IBaselineProvider& base_provider,
+ const PortFileProvider::IOverlayProvider& oprovider,
const CMakeVars::CMakeVarProvider& var_provider)
- : m_ver_provider(ver_provider), m_base_provider(base_provider), m_var_provider(var_provider)
+ : m_ver_provider(ver_provider)
+ , m_base_provider(base_provider)
+ , m_o_provider(oprovider)
+ , m_var_provider(var_provider)
{
}
@@ -1187,6 +1191,7 @@ namespace vcpkg::Dependencies
private:
const IVersionedPortfileProvider& m_ver_provider;
const IBaselineProvider& m_base_provider;
+ const PortFileProvider::IOverlayProvider& m_o_provider;
const CMakeVars::CMakeVarProvider& m_var_provider;
struct DepSpec
@@ -1464,13 +1469,28 @@ namespace vcpkg::Dependencies
void VersionedPackageGraph::add_constraint(std::pair<const PackageSpec, PackageNode>& ref,
const Versions::Version& version,
const std::string& origin)
+ {
+ ExpectedS<const vcpkg::SourceControlFileLocation&> maybe_scfl;
+
+ auto maybe_overlay = m_o_provider.get_control_file(ref.first.name());
+ if (auto p_overlay = maybe_overlay.get())
+ {
+ auto overlay_version = to_version(*p_overlay->source_control_file);
+ if (version != overlay_version)
+ {
+ return add_constraint(ref, overlay_version, origin);
+ }
+ maybe_scfl = *p_overlay;
+ }
+ else
{
auto over_it = m_overrides.find(ref.first.name());
if (over_it != m_overrides.end() && over_it->second != version)
{
return add_constraint(ref, over_it->second, origin);
}
- auto maybe_scfl = m_ver_provider.get_control_file({ref.first.name(), version});
+ maybe_scfl = m_ver_provider.get_control_file({ref.first.name(), version});
+ }
if (auto p_scfl = maybe_scfl.get())
{
@@ -1599,6 +1619,15 @@ namespace vcpkg::Dependencies
auto& node = emplace_package(spec);
+ auto maybe_overlay = m_o_provider.get_control_file(dep.name);
+ if (auto p_overlay = maybe_overlay.get())
+ {
+ auto ver = to_version(*p_overlay->source_control_file);
+ m_roots.push_back(DepSpec{spec, ver, dep.features});
+ add_constraint(node, ver, toplevel.name());
+ continue;
+ }
+
auto over_it = m_overrides.find(dep.name);
if (over_it != m_overrides.end())
{
@@ -1690,10 +1719,13 @@ namespace vcpkg::Dependencies
auto push = [&emitted, this, &stack](const PackageSpec& spec,
const Versions::Version& new_ver) -> Optional<std::string> {
auto&& node = m_graph[spec];
+ auto overlay = m_o_provider.get_control_file(spec.name());
auto over_it = m_overrides.find(spec.name());
VersionedPackageGraph::VersionSchemeInfo* p_vnode;
- if (over_it != m_overrides.end())
+ if (auto p_overlay = overlay.get())
+ p_vnode = node.get_node(to_version(*p_overlay->source_control_file));
+ else if (over_it != m_overrides.end())
p_vnode = node.get_node(over_it->second);
else
p_vnode = node.get_node(new_ver);
@@ -1704,7 +1736,7 @@ namespace vcpkg::Dependencies
if (p.second)
{
// Newly inserted
- if (over_it == m_overrides.end())
+ if (!overlay && over_it == m_overrides.end())
{
// Not overridden -- Compare against baseline
if (auto baseline = m_base_provider.get_baseline_version(spec.name()))
@@ -1818,12 +1850,13 @@ namespace vcpkg::Dependencies
ExpectedS<ActionPlan> create_versioned_install_plan(const PortFileProvider::IVersionedPortfileProvider& provider,
const PortFileProvider::IBaselineProvider& bprovider,
+ const PortFileProvider::IOverlayProvider& oprovider,
const CMakeVars::CMakeVarProvider& var_provider,
const std::vector<Dependency>& deps,
const std::vector<DependencyOverride>& overrides,
const PackageSpec& toplevel)
{
- VersionedPackageGraph vpg(provider, bprovider, var_provider);
+ VersionedPackageGraph vpg(provider, bprovider, oprovider, var_provider);
for (auto&& o : overrides)
vpg.add_override(o.name, {o.version, o.port_version});
vpg.add_roots(deps, toplevel);

MODIFY
src/vcpkg/install.cpp
src/vcpkg/install.cpp
@@ -853,10 +853,12 @@ namespace vcpkg::Install
paths.get_configuration().registry_set.experimental_set_builtin_registry_baseline(
p_baseline->string());
}
+ auto oprovider = PortFileProvider::make_overlay_provider(paths, args.overlay_ports);
auto install_plan =
Dependencies::create_versioned_install_plan(*verprovider,
*baseprovider,
+ *oprovider,
var_provider,
manifest_scf.core_paragraph->dependencies,
manifest_scf.core_paragraph->overrides,

MODIFY
src/vcpkg/portfileprovider.cpp
src/vcpkg/portfileprovider.cpp
@@ -402,6 +402,50 @@ namespace vcpkg::PortFileProvider
mutable std::unordered_map<VersionSpec, SourceControlFileLocation, VersionSpecHasher> m_control_cache;
mutable std::map<std::string, std::unique_ptr<RegistryEntry>, std::less<>> m_entry_cache;
};
+
+ struct OverlayProviderImpl : IOverlayProvider, Util::ResourceBase
+ {
+ OverlayProviderImpl(const VcpkgPaths& paths, View<std::string> overlay_ports)
+ : paths(paths), m_overlay_ports(Util::fmap(overlay_ports, [&paths](const std::string& s) -> fs::path {
+ return Files::combine(paths.original_cwd, fs::u8path(s));
+ }))
+ {
+ }
+
+ virtual Optional<const SourceControlFileLocation&> get_control_file(StringView port_name) const override
+ {
+ auto it = m_overlay_cache.find(port_name);
+ if (it == m_overlay_cache.end())
+ {
+ auto s_port_name = port_name.to_string();
+ auto maybe_overlay = try_load_overlay_port(paths.get_filesystem(), m_overlay_ports, s_port_name);
+ Optional<SourceControlFileLocation> v;
+ if (maybe_overlay)
+ {
+ auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), maybe_overlay->path);
+ if (auto scf = maybe_scf.get())
+ {
+ v = SourceControlFileLocation{std::move(*scf), maybe_overlay->path};
+ }
+ else
+ {
+ print_error_message(maybe_scf.error());
+ Checks::exit_with_message(VCPKG_LINE_INFO,
+ "Error: Failed to load port %s from %s",
+ port_name,
+ fs::u8string(maybe_overlay->path));
+ }
+ }
+ it = m_overlay_cache.emplace(std::move(s_port_name), std::move(v)).first;
+ }
+ return it->second;
+ }
+
+ private:
+ const VcpkgPaths& paths;
+ const std::vector<fs::path> m_overlay_ports;
+ mutable std::map<std::string, Optional<SourceControlFileLocation>, std::less<>> m_overlay_cache;
+ };
}
std::unique_ptr<IBaselineProvider> make_baseline_provider(const vcpkg::VcpkgPaths& paths)
@@ -413,4 +457,10 @@ namespace vcpkg::PortFileProvider
{
return std::make_unique<VersionedPortfileProviderImpl>(paths);
}
+
+ std::unique_ptr<IOverlayProvider> make_overlay_provider(const vcpkg::VcpkgPaths& paths,
+ View<std::string> overlay_ports)
+ {
+ return std::make_unique<OverlayProviderImpl>(paths, std::move(overlay_ports));
+ }
}

[vcpkg] Add support for --overlay-ports to versioning (#15013)

Co-authored-by: Robert Schumacher <roschuma@microsoft.com>