Skip to content

Commit

Permalink
[vcpkg] Add support for --overlay-ports to versioning (microsoft#15013)
Browse files Browse the repository at this point in the history
Co-authored-by: Robert Schumacher <[email protected]>
  • Loading branch information
ras0219 and ras0219-msft authored Jan 8, 2021
1 parent d1ef42c commit d717d41
Show file tree
Hide file tree
Showing 7 changed files with 534 additions and 286 deletions.
1 change: 1 addition & 0 deletions toolsrc/include/vcpkg/dependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions toolsrc/include/vcpkg/fwd/portfileprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ namespace vcpkg::PortFileProvider
struct PathsPortFileProvider;
struct IVersionedPortfileProvider;
struct IBaselineProvider;
struct IOverlayProvider;
}
12 changes: 10 additions & 2 deletions toolsrc/include/vcpkg/portfileprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
705 changes: 429 additions & 276 deletions toolsrc/src/vcpkg-test/dependencies.cpp

Large diffs are not rendered by default.

49 changes: 41 additions & 8 deletions toolsrc/src/vcpkg/dependencies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
}

Expand All @@ -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
Expand Down Expand Up @@ -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())
{
Expand Down Expand Up @@ -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())
{
Expand Down Expand Up @@ -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);
Expand All @@ -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()))
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions toolsrc/src/vcpkg/install.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
50 changes: 50 additions & 0 deletions toolsrc/src/vcpkg/portfileprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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));
}
}

0 comments on commit d717d41

Please sign in to comment.