Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions toolsrc/include/vcpkg/base/files.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ namespace vcpkg::Files
void current_path(const fs::path& path, LineInfo li);

// waits forever for the file lock
// creates a non-existent file
Comment thread
strega-nil marked this conversation as resolved.
Outdated
virtual fs::SystemHandle take_exclusive_file_lock(const fs::path& path, std::error_code&) = 0;
// waits, at most, 1.5 seconds, for the file lock
virtual fs::SystemHandle try_take_exclusive_file_lock(const fs::path& path, std::error_code&) = 0;
Expand Down
2 changes: 1 addition & 1 deletion toolsrc/include/vcpkg/base/jsonreader.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ namespace vcpkg::Json
};
std::vector<Path> m_path;

public:
Comment thread
strega-nil marked this conversation as resolved.
// checks that an object doesn't contain any fields which both:
// * don't start with a `$`
// * are not in `valid_fields`
// if known_fields.empty(), then it's treated as if all field names are valid
void check_for_unexpected_fields(const Object& obj, View<StringView> valid_fields, StringView type_name);

public:
template<class Type>
void required_object_field(
StringView type, const Object& obj, StringView key, Type& place, IDeserializer<Type>& visitor)
Expand Down
33 changes: 7 additions & 26 deletions toolsrc/include/vcpkg/configurationdeserializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,11 @@

namespace vcpkg
{
struct RegistryImplDeserializer : Json::IDeserializer<std::unique_ptr<RegistryImpl>>
{
constexpr static StringLiteral KIND = "kind";
constexpr static StringLiteral PATH = "path";

constexpr static StringLiteral KIND_BUILTIN = "builtin";
constexpr static StringLiteral KIND_FILESYSTEM = "filesystem";

virtual StringView type_name() const override;
virtual View<StringView> valid_fields() const override;
std::unique_ptr<Json::IDeserializer<std::unique_ptr<RegistryImplementation>>>
Comment thread
strega-nil marked this conversation as resolved.
Outdated
get_registry_implementation_deserializer(const fs::path& configuration_directory);

virtual Optional<std::unique_ptr<RegistryImpl>> visit_null(Json::Reader&) override;
virtual Optional<std::unique_ptr<RegistryImpl>> visit_object(Json::Reader&, const Json::Object&) override;

static RegistryImplDeserializer instance;
};

struct RegistryDeserializer final : Json::IDeserializer<Registry>
{
constexpr static StringLiteral PACKAGES = "packages";

virtual StringView type_name() const override;
virtual View<StringView> valid_fields() const override;

virtual Optional<Registry> visit_object(Json::Reader&, const Json::Object&) override;
};
std::unique_ptr<Json::IDeserializer<std::vector<Registry>>> get_registry_array_deserializer(
const fs::path& configuration_directory);

struct ConfigurationDeserializer final : Json::IDeserializer<Configuration>
{
Expand All @@ -56,11 +35,13 @@ namespace vcpkg

virtual Optional<Configuration> visit_object(Json::Reader& r, const Json::Object& obj) override;

ConfigurationDeserializer(const VcpkgCmdArguments& args);
ConfigurationDeserializer(const VcpkgCmdArguments& args, const fs::path& configuration_directory);

private:
bool print_json;

bool registries_enabled;

fs::path configuration_directory;
};
}
3 changes: 2 additions & 1 deletion toolsrc/include/vcpkg/fwd/registries.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

namespace vcpkg
{
struct RegistryImpl;
struct RegistryEntry;
struct RegistryImplementation;
struct Registry;
struct RegistrySet;
}
12 changes: 6 additions & 6 deletions toolsrc/include/vcpkg/portfileprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <vcpkg/base/expected.h>
#include <vcpkg/base/util.h>

#include <vcpkg/registries.h>
#include <vcpkg/sourceparagraph.h>
#include <vcpkg/versions.h>

Expand Down Expand Up @@ -40,10 +41,10 @@ namespace vcpkg::PortFileProvider

struct IVersionedPortfileProvider
{
virtual const std::vector<vcpkg::Versions::VersionSpec>& get_port_versions(StringView port_name) const = 0;
virtual View<VersionT> get_port_versions(StringView port_name) const = 0;

virtual ExpectedS<const SourceControlFileLocation&> get_control_file(
const vcpkg::Versions::VersionSpec& version_spec) const = 0;
const Versions::VersionSpec& version_spec) const = 0;
};

struct IBaselineProvider
Expand All @@ -62,19 +63,18 @@ namespace vcpkg::PortFileProvider
explicit VersionedPortfileProvider(const vcpkg::VcpkgPaths& paths);
~VersionedPortfileProvider();

const std::vector<vcpkg::Versions::VersionSpec>& get_port_versions(StringView port_name) const override;
View<VersionT> get_port_versions(StringView port_name) const override;

ExpectedS<const SourceControlFileLocation&> get_control_file(
const vcpkg::Versions::VersionSpec& version_spec) const override;
const Versions::VersionSpec& version) const override;

private:
std::unique_ptr<details::VersionedPortfileProviderImpl> m_impl;
};

struct BaselineProvider : IBaselineProvider, Util::ResourceBase
struct BaselineProvider final : IBaselineProvider, Util::ResourceBase
{
explicit BaselineProvider(const vcpkg::VcpkgPaths& paths);
BaselineProvider(const vcpkg::VcpkgPaths& paths, const std::string& baseline);
~BaselineProvider();

Optional<VersionT> get_baseline_version(StringView port_name) const override;
Expand Down
35 changes: 23 additions & 12 deletions toolsrc/include/vcpkg/registries.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <vcpkg/fwd/registries.h>
#include <vcpkg/fwd/vcpkgpaths.h>

#include <vcpkg/base/files.h>
Expand All @@ -17,40 +18,46 @@ namespace vcpkg
{
struct RegistryEntry
{
// returns fs::path() if version doesn't exist
virtual fs::path get_port_directory(const VcpkgPaths& paths, const VersionT& version) const = 0;
virtual View<VersionT> get_port_versions() const = 0;

// precondition: version \in get_port_versions(). Otherwise, this function asserts.
Comment thread
strega-nil marked this conversation as resolved.
Outdated
virtual ExpectedS<fs::path> get_path_to_version(const VcpkgPaths& paths, const VersionT& version) const = 0;

virtual ~RegistryEntry() = default;
};

struct RegistryImpl
struct RegistryImplementation
{
// returns nullptr if the port doesn't exist
virtual std::unique_ptr<RegistryEntry> get_port_entry(const VcpkgPaths& paths, StringView port_name) const = 0;

// appends the names of the ports to the out parameter
// may result in duplicated port names; make sure to Util::sort_unique_erase at the end
virtual void get_all_port_names(std::vector<std::string>& port_names, const VcpkgPaths& paths) const = 0;

virtual Optional<VersionT> get_baseline_version(const VcpkgPaths& paths, StringView port_name) const = 0;

virtual ~RegistryImpl() = default;
virtual ~RegistryImplementation() = default;
};

struct Registry
{
// requires: static_cast<bool>(implementation)
Registry(std::vector<std::string>&& packages, std::unique_ptr<RegistryImpl>&& implementation);
Registry(std::vector<std::string>&& packages, std::unique_ptr<RegistryImplementation>&& implementation);

Registry(std::vector<std::string>&&, std::nullptr_t) = delete;

// always ordered lexicographically
View<std::string> packages() const { return packages_; }
const RegistryImpl& implementation() const { return *implementation_; }
const RegistryImplementation& implementation() const { return *implementation_; }
Comment thread
strega-nil marked this conversation as resolved.

static std::unique_ptr<RegistryImpl> builtin_registry();
static std::unique_ptr<RegistryImplementation> builtin_registry(std::string&& baseline = {});

friend RegistrySet; // for experimental_set_builtin_registry_baseline

private:
std::vector<std::string> packages_;
std::unique_ptr<RegistryImpl> implementation_;
std::unique_ptr<RegistryImplementation> implementation_;
};

// this type implements the registry fall back logic from the registries RFC:
Expand All @@ -65,19 +72,23 @@ namespace vcpkg

// finds the correct registry for the port name
// Returns the null pointer if there is no registry set up for that name
const RegistryImpl* registry_for_port(StringView port_name) const;
const RegistryImplementation* registry_for_port(StringView port_name) const;
Optional<VersionT> baseline_for_port(const VcpkgPaths& paths, StringView port_name) const;

View<Registry> registries() const { return registries_; }

const RegistryImpl* default_registry() const { return default_registry_.get(); }
const RegistryImplementation* default_registry() const { return default_registry_.get(); }

// TODO: figure out how to get this to return an error (or maybe it should be a warning?)
void add_registry(Registry&& r);
void set_default_registry(std::unique_ptr<RegistryImpl>&& r);
void set_default_registry(std::unique_ptr<RegistryImplementation>&& r);
void set_default_registry(std::nullptr_t r);

// this exists in order to allow versioning and registries to be developed and tested separately
void experimental_set_builtin_registry_baseline(StringView baseline) const;

private:
std::unique_ptr<RegistryImpl> default_registry_;
std::unique_ptr<RegistryImplementation> default_registry_;
std::vector<Registry> registries_;
};

Expand Down
2 changes: 1 addition & 1 deletion toolsrc/include/vcpkg/sourceparagraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ namespace vcpkg

/// <summary>
/// Full metadata of a package: core and other features. As well as the location the SourceControlFile was
/// loaded from.
/// loaded from (the port directory, not the actual CONTROL/vcpkg.json file).
Comment thread
strega-nil marked this conversation as resolved.
Outdated
/// </summary>
struct SourceControlFileLocation
{
Expand Down
2 changes: 1 addition & 1 deletion toolsrc/include/vcpkg/vcpkgpaths.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ namespace vcpkg
const fs::path& get_tool_exe(const std::string& tool) const;
const std::string& get_tool_version(const std::string& tool) const;

// Git manipulation
// Git manipulation in vcpkg directory
Comment thread
strega-nil marked this conversation as resolved.
Outdated
fs::path git_checkout_baseline(Files::Filesystem& filesystem, StringView commit_sha) const;
fs::path git_checkout_port(Files::Filesystem& filesystem, StringView port_name, StringView git_tree) const;
ExpectedS<std::string> git_show(const std::string& treeish, const fs::path& dot_git_dir) const;
Expand Down
17 changes: 1 addition & 16 deletions toolsrc/include/vcpkg/versiondeserializers.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@

namespace vcpkg
{
struct VersionDbEntry
{
VersionT version;
Versions::Scheme scheme = Versions::Scheme::String;
std::string git_tree;
};

Json::IDeserializer<VersionT>& get_versiont_deserializer_instance();
std::unique_ptr<Json::IDeserializer<std::string>> make_version_deserializer(StringLiteral type_name);

Expand All @@ -39,12 +32,4 @@ namespace vcpkg
const std::string& version,
int port_version,
bool always_emit_port_version = false);

ExpectedS<std::map<std::string, VersionT, std::less<>>> parse_baseline_file(Files::Filesystem& fs,
StringView baseline_name,
const fs::path& baseline_file_path);

ExpectedS<std::vector<VersionDbEntry>> parse_versions_file(Files::Filesystem& fs,
StringView port_name,
const fs::path& versions_file_path);
}
}
5 changes: 1 addition & 4 deletions toolsrc/src/vcpkg-test/dependencies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,7 @@ struct MockVersionedPortfileProvider : PortFileProvider::IVersionedPortfileProvi
return it2->second;
}

virtual const std::vector<vcpkg::Versions::VersionSpec>& get_port_versions(StringView) const override
{
Checks::unreachable(VCPKG_LINE_INFO);
}
virtual View<vcpkg::VersionT> get_port_versions(StringView) const override { Checks::unreachable(VCPKG_LINE_INFO); }

SourceControlFileLocation& emplace(std::string&& name,
Versions::Version&& version,
Expand Down
8 changes: 4 additions & 4 deletions toolsrc/src/vcpkg/base/files.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,7 @@ namespace vcpkg::Files
{
}

#if defined(WIN32)
#if defined(_WIN32)
Comment thread
strega-nil marked this conversation as resolved.
void assign_busy_error(std::error_code& ec) { ec.assign(ERROR_BUSY, std::system_category()); }

bool operator()(std::error_code& ec)
Expand All @@ -1218,7 +1218,7 @@ namespace vcpkg::Files
res.system_handle = reinterpret_cast<intptr_t>(handle);
return true;
}
#else // ^^^ WIN32 / !WIN32 vvv
#else // ^^^ _WIN32 / !_WIN32 vvv
int fd = -1;

void assign_busy_error(std::error_code& ec) { ec.assign(EBUSY, std::generic_category()); }
Expand All @@ -1228,7 +1228,7 @@ namespace vcpkg::Files
ec.clear();
if (fd == -1)
{
fd = ::open(native.c_str(), 0);
fd = ::open(native.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Comment thread
strega-nil marked this conversation as resolved.
if (fd < 0)
{
ec.assign(errno, std::generic_category());
Expand Down Expand Up @@ -1311,7 +1311,7 @@ namespace vcpkg::Files

virtual void unlock_file_lock(fs::SystemHandle handle, std::error_code& ec) override
{
#if defined(WIN32)
#if defined(_WIN32)
if (CloseHandle(reinterpret_cast<HANDLE>(handle.system_handle)) == 0)
{
ec.assign(GetLastError(), std::system_category());
Expand Down
20 changes: 14 additions & 6 deletions toolsrc/src/vcpkg/configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ namespace vcpkg

bool registries_feature_flags_warning = false;

auto impl_des = get_registry_implementation_deserializer(configuration_directory);

{
std::unique_ptr<RegistryImpl> default_registry;
if (r.optional_object_field(obj, DEFAULT_REGISTRY, default_registry, RegistryImplDeserializer::instance))
std::unique_ptr<RegistryImplementation> default_registry;
if (r.optional_object_field(obj, DEFAULT_REGISTRY, default_registry, *impl_des))
{
if (!registries_enabled)
{
Expand All @@ -28,17 +30,21 @@ namespace vcpkg
}
}

static Json::ArrayDeserializer<RegistryDeserializer> array_of_registries{"an array of registries"};

auto reg_des = get_registry_array_deserializer(configuration_directory);
std::vector<Registry> regs;
r.optional_object_field(obj, REGISTRIES, regs, array_of_registries);
r.optional_object_field(obj, REGISTRIES, regs, *reg_des);

if (!regs.empty() && !registries_enabled)
{
registries_feature_flags_warning = true;
regs.clear();
}

if (!r.errors().empty())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is almost certainly not the right condition -- this will test whether any errors have occurred anywhere in the reader to this point, not just in child objects.

If you need to detect errors in child objects and return early, you'll need to check those objects for an appropriate error state (empty collection, etc).

{
return nullopt;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nullopt implies to the caller that the current object is completely outside the bounds of the current deserializer to handle -- for example, asking StringDeserializer to operate on null or 10. The caller will then emit a message to the effect of Error: expected $.field to be of type string.

However, in this case, you're (presumably?) trying to test for whether an error was emitted above as part of parsing the optional object fields. If one of those did result in an error, then the user will already see that more specific error and does not need the generic one.

This is fixed by returning a default constructed object of some kind; the code consuming this deserializer should handle this case accordingly (either by testing r for errors if it's outside the deserializer framework or handling the default constructed form if within the deserializer framework).

}
Comment thread
strega-nil marked this conversation as resolved.
Outdated

for (Registry& reg : regs)
{
registries.add_registry(std::move(reg));
Expand All @@ -58,7 +64,9 @@ namespace vcpkg
constexpr StringLiteral ConfigurationDeserializer::DEFAULT_REGISTRY;
constexpr StringLiteral ConfigurationDeserializer::REGISTRIES;

ConfigurationDeserializer::ConfigurationDeserializer(const VcpkgCmdArguments& args)
ConfigurationDeserializer::ConfigurationDeserializer(const VcpkgCmdArguments& args,
const fs::path& configuration_directory)
: configuration_directory(configuration_directory)
{
registries_enabled = args.registries_enabled();
print_json = args.output_json();
Expand Down
Loading