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

Co-authored-by: Robert Schumacher <roschuma@microsoft.com>
This commit is contained in:
ras0219 2021-01-07 17:44:45 -08:00 committed by GitHub
parent d1ef42c0fd
commit d717d4119e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 534 additions and 286 deletions

View File

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

View File

@ -6,4 +6,5 @@ namespace vcpkg::PortFileProvider
struct PathsPortFileProvider;
struct IVersionedPortfileProvider;
struct IBaselineProvider;
struct IOverlayProvider;
}

View File

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

View File

@ -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,14 +331,14 @@ TEST_CASE ("basic version install scheme baseline missing success", "[versionpla
MockCMakeVarProvider var_provider;
auto install_plan =
unwrap(Dependencies::create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Exact, "2"}},
},
{},
toplevel_spec()));
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Exact, "2"}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "a", {"2", 0});
@ -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,15 +392,14 @@ TEST_CASE ("version install scheme baseline conflict", "[versionplan]")
MockCMakeVarProvider var_provider;
auto install_plan =
Dependencies::create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Exact, "3"}},
},
{},
toplevel_spec());
auto install_plan = create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Exact, "3"}},
},
{},
toplevel_spec());
REQUIRE(!install_plan.has_value());
}
@ -373,15 +416,15 @@ TEST_CASE ("version install string port version", "[versionplan]")
MockCMakeVarProvider var_provider;
auto install_plan = unwrap(
Dependencies::create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Exact, "2", 1}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Exact, "2", 1}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "a", {"2", 1});
@ -399,15 +442,15 @@ TEST_CASE ("version install string port version 2", "[versionplan]")
MockCMakeVarProvider var_provider;
auto install_plan = unwrap(
Dependencies::create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Exact, "2", 0}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Exact, "2", 0}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "a", {"2", 1});
@ -430,15 +473,15 @@ TEST_CASE ("version install transitive string", "[versionplan]")
MockCMakeVarProvider var_provider;
auto install_plan = unwrap(
Dependencies::create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Exact, "2", 1}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Exact, "2", 1}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 2);
check_name_and_version(install_plan.install_actions[0], "b", {"2", 0});
@ -456,15 +499,15 @@ TEST_CASE ("version install simple relaxed", "[versionplan]")
MockCMakeVarProvider var_provider;
auto install_plan = unwrap(
Dependencies::create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3", 0}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3", 0}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "a", {"3", 0});
@ -486,15 +529,15 @@ TEST_CASE ("version install transitive relaxed", "[versionplan]")
MockCMakeVarProvider var_provider;
auto install_plan = unwrap(
Dependencies::create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3", 0}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3", 0}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 2);
check_name_and_version(install_plan.install_actions[0], "b", {"3", 0});
@ -522,16 +565,16 @@ TEST_CASE ("version install diamond relaxed", "[versionplan]")
MockCMakeVarProvider var_provider;
auto install_plan = unwrap(
Dependencies::create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3", 0}},
Dependency{"b", {}, {}, {Constraint::Type::Minimum, "2", 1}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3", 0}},
Dependency{"b", {}, {}, {Constraint::Type::Minimum, "2", 1}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 3);
check_name_and_version(install_plan.install_actions[0], "c", {"9", 2});
@ -739,15 +782,15 @@ TEST_CASE ("version install simple semver", "[versionplan]")
MockCMakeVarProvider var_provider;
auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3.0.0", 0}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3.0.0", 0}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "a", {"3.0.0", 0});
@ -769,15 +812,15 @@ TEST_CASE ("version install transitive semver", "[versionplan]")
MockCMakeVarProvider var_provider;
auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3.0.0", 0}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3.0.0", 0}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 2);
check_name_and_version(install_plan.install_actions[0], "b", {"3.0.0", 0});
@ -805,16 +848,16 @@ TEST_CASE ("version install diamond semver", "[versionplan]")
MockCMakeVarProvider var_provider;
auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3.0.0", 0}},
Dependency{"b", {}, {}, {Constraint::Type::Minimum, "2.0.0", 1}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3.0.0", 0}},
Dependency{"b", {}, {}, {Constraint::Type::Minimum, "2.0.0", 1}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 3);
check_name_and_version(install_plan.install_actions[0], "c", {"9.0.0", 2});
@ -833,15 +876,15 @@ TEST_CASE ("version install simple date", "[versionplan]")
MockCMakeVarProvider var_provider;
auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2020-03-01", 0}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2020-03-01", 0}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "a", {"2020-03-01", 0});
@ -863,15 +906,15 @@ TEST_CASE ("version install transitive date", "[versionplan]")
MockCMakeVarProvider var_provider;
auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2020-01-01.3", 0}},
},
{},
toplevel_spec()));
auto install_plan = unwrap(
create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2020-01-01.3", 0}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 2);
check_name_and_version(install_plan.install_actions[0], "b", {"2020-01-01.3", 0});
@ -899,16 +942,16 @@ TEST_CASE ("version install diamond date", "[versionplan]")
MockCMakeVarProvider var_provider;
auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2020-01-03", 0}},
Dependency{"b", {}, {}, {Constraint::Type::Minimum, "2020-01-02", 1}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2020-01-03", 0}},
Dependency{"b", {}, {}, {Constraint::Type::Minimum, "2020-01-02", 1}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 3);
check_name_and_version(install_plan.install_actions[0], "c", {"2020-01-09", 2});
@ -930,13 +973,13 @@ 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,
bp,
var_provider,
{Dependency{"a", {}, {}, {Constraint::Type::Minimum, "1.0.1", 0}}},
{},
toplevel_spec());
auto install_plan =
create_versioned_install_plan(vp,
bp,
var_provider,
{Dependency{"a", {}, {}, {Constraint::Type::Minimum, "1.0.1", 0}}},
{},
toplevel_spec());
REQUIRE(!install_plan.error().empty());
CHECK(install_plan.error() == "Version conflict on a@1.0.1: baseline required 1.0.0");
@ -946,13 +989,13 @@ 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,
bp,
var_provider,
{Dependency{"a", {}, {}, {Constraint::Type::Minimum, "1.0.1", 0}}},
{},
toplevel_spec());
auto install_plan =
create_versioned_install_plan(vp,
bp,
var_provider,
{Dependency{"a", {}, {}, {Constraint::Type::Minimum, "1.0.1", 0}}},
{},
toplevel_spec());
REQUIRE(!install_plan.error().empty());
CHECK(install_plan.error() == "Version conflict on a@1.0.1: baseline required 1.0.2");
@ -978,15 +1021,15 @@ 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,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Exact, "2", 1}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Exact, "2", 1}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 2);
check_name_and_version(install_plan.install_actions[0], "b", {"1", 1});
@ -997,15 +1040,15 @@ 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,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Exact, "2", 0}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {}, {}, {Constraint::Type::Exact, "2", 0}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 2);
check_name_and_version(install_plan.install_actions[0], "b", {"1", 1});
@ -1027,14 +1070,14 @@ TEST_CASE ("version install simple feature", "[versionplan]")
MockBaselineProvider bp;
bp.v["a"] = {"1", 0};
auto install_plan = unwrap(Dependencies::create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {"x"}},
},
{},
toplevel_spec()));
auto install_plan = unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {"x"}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}, {"x"});
@ -1044,15 +1087,15 @@ TEST_CASE ("version install simple feature", "[versionplan]")
{
MockBaselineProvider bp;
auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
vp,
bp,
var_provider,
{
Dependency{"a", {"x"}, {}, {Constraint::Type::Minimum, "1", 0}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {"x"}, {}, {Constraint::Type::Minimum, "1", 0}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}, {"x"});
@ -1083,14 +1126,14 @@ 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,
bp,
var_provider,
{
Dependency{"a", {"x"}},
},
{},
toplevel_spec()));
auto install_plan = unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {"x"}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 2);
check_name_and_version(install_plan.install_actions[0], "b", {"1", 0}, {"y"});
@ -1123,14 +1166,14 @@ 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,
bp,
var_provider,
{
Dependency{"a", {"x"}},
},
{},
toplevel_spec()));
auto install_plan = unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"a", {"x"}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 3);
check_name_and_version(install_plan.install_actions[0], "c", {"1", 0});
@ -1161,15 +1204,15 @@ 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,
bp,
var_provider,
{
Dependency{"b", {}, {}, {Constraint::Type::Minimum, "1"}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"b", {}, {}, {Constraint::Type::Minimum, "1"}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 2);
check_name_and_version(install_plan.install_actions[0], "c", {"1", 0});
@ -1195,15 +1238,15 @@ 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,
bp,
var_provider,
{
Dependency{"b", {}, {}, {Constraint::Type::Minimum, "2"}},
},
{},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{
Dependency{"b", {}, {}, {Constraint::Type::Minimum, "2"}},
},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 2);
check_name_and_version(install_plan.install_actions[0], "c", {"1", 0});
@ -1228,13 +1271,13 @@ TEST_CASE ("version install overrides", "[versionplan]")
SECTION ("string")
{
auto install_plan = unwrap(
Dependencies::create_versioned_install_plan(vp,
bp,
var_provider,
{Dependency{"c"}},
{DependencyOverride{"b", "1"}, DependencyOverride{"c", "1"}},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{Dependency{"c"}},
{DependencyOverride{"b", "1"}, DependencyOverride{"c", "1"}},
toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "c", {"1", 0});
@ -1242,13 +1285,13 @@ TEST_CASE ("version install overrides", "[versionplan]")
SECTION ("relaxed")
{
auto install_plan = unwrap(
Dependencies::create_versioned_install_plan(vp,
bp,
var_provider,
{Dependency{"b"}},
{DependencyOverride{"b", "1"}, DependencyOverride{"c", "1"}},
toplevel_spec()));
auto install_plan =
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{Dependency{"b"}},
{DependencyOverride{"b", "1"}, DependencyOverride{"c", "1"}},
toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "b", {"1", 0});
@ -1272,12 +1315,12 @@ TEST_CASE ("version install transitive overrides", "[versionplan]")
bp.v["c"] = {"2", 1};
auto install_plan =
unwrap(Dependencies::create_versioned_install_plan(vp,
bp,
var_provider,
{Dependency{"b"}},
{DependencyOverride{"b", "1"}, DependencyOverride{"c", "1"}},
toplevel_spec()));
unwrap(create_versioned_install_plan(vp,
bp,
var_provider,
{Dependency{"b"}},
{DependencyOverride{"b", "1"}, DependencyOverride{"c", "1"}},
toplevel_spec()));
REQUIRE(install_plan.size() == 2);
check_name_and_version(install_plan.install_actions[0], "c", {"1", 0});
@ -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,13 +1416,13 @@ 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,
bp,
var_provider,
{{"b", {}, parse_platform("!linux")}, {"c", {}, parse_platform("linux")}},
{},
toplevel_spec()));
auto install_plan = unwrap(
create_versioned_install_plan(vp,
bp,
var_provider,
{{"b", {}, parse_platform("!linux")}, {"c", {}, parse_platform("linux")}},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "b", {"1", 0});
@ -1390,13 +1433,13 @@ 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,
bp,
var_provider,
{{"b", {}, parse_platform("!linux")}, {"c", {}, parse_platform("linux")}},
{},
toplevel_spec()));
auto install_plan = unwrap(
create_versioned_install_plan(vp,
bp,
var_provider,
{{"b", {}, parse_platform("!linux")}, {"c", {}, parse_platform("linux")}},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 1);
check_name_and_version(install_plan.install_actions[0], "c", {"1", 0});
@ -1420,13 +1463,13 @@ 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,
bp,
var_provider,
{{"b", {}, parse_platform("!linux")}, {"a", {"core"}, parse_platform("linux")}},
{},
toplevel_spec()));
auto install_plan = unwrap(
create_versioned_install_plan(vp,
bp,
var_provider,
{{"b", {}, parse_platform("!linux")}, {"a", {"core"}, parse_platform("linux")}},
{},
toplevel_spec()));
REQUIRE(install_plan.size() == 2);
check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}, {"x"});
@ -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});
}
}

View File

@ -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
@ -1465,12 +1470,27 @@ namespace vcpkg::Dependencies
const Versions::Version& version,
const std::string& origin)
{
auto over_it = m_overrides.find(ref.first.name());
if (over_it != m_overrides.end() && over_it->second != version)
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())
{
return add_constraint(ref, over_it->second, origin);
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);
}
maybe_scfl = m_ver_provider.get_control_file({ref.first.name(), version});
}
auto 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);

View File

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

View File

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