Skip to content
22 changes: 22 additions & 0 deletions include/vcpkg-test/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ namespace Catch
}
};

template<>
struct StringMaker<vcpkg::FeatureSpec>
{
static std::string convert(vcpkg::FeatureSpec const& value)
{
return vcpkg::Strings::concat(value.spec().name(), '[', value.feature(), "]:", value.spec().triplet());
}
};

template<>
struct StringMaker<vcpkg::Triplet>
{
Expand Down Expand Up @@ -107,6 +116,19 @@ namespace vcpkg::Test
return std::move(*opt.get());
}

inline std::vector<FullPackageSpec> parse_test_fspecs(StringView sv, Triplet t = X86_WINDOWS)
{
std::vector<FullPackageSpec> ret;
Parse::ParserBase parser(sv, "test");
while (!parser.at_eof())
{
auto opt = parse_qualified_specifier(parser);
REQUIRE(opt.has_value());
ret.push_back(unwrap(opt.get()->to_full_spec(t, true)));
}
return ret;
}

template<class R1, class R2>
void check_ranges(const R1& r1, const R2& r2)
{
Expand Down
14 changes: 8 additions & 6 deletions include/vcpkg/base/expected.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ namespace vcpkg
return this->m_t.get();
}

using const_ref_type = decltype(*std::declval<typename ExpectedHolder<T>::const_pointer>());
using move_ref_type = decltype(std::move(*std::declval<typename ExpectedHolder<T>::pointer>()));
template<class F>
using map_t = decltype(std::declval<F&>()(*std::declval<typename ExpectedHolder<T>::const_pointer>()));

Expand Down Expand Up @@ -198,25 +200,25 @@ namespace vcpkg
}
}

template<class F, class U = map_t<F>>
U then(F f) const&
template<class F, class... Args, class U = std::invoke_result_t<F, const_ref_type, Args&&...>>
Comment thread
ras0219-msft marked this conversation as resolved.
Outdated
U then(F f, Args&&... args) const&
{
if (has_value())
{
return f(*m_t.get());
return std::invoke(f, *m_t.get(), static_cast<Args&&>(args)...);
Comment thread
ras0219-msft marked this conversation as resolved.
}
else
{
return U{error(), expected_right_tag};
}
}

template<class F, class U = move_map_t<F>>
U then(F f) &&
template<class F, class... Args, class U = std::invoke_result_t<F, move_ref_type, Args&&...>>
Comment thread
ras0219-msft marked this conversation as resolved.
Outdated
U then(F f, Args&&... args) &&
{
if (has_value())
{
return f(std::move(*m_t.get()));
return std::invoke(f, std::move(*m_t.get()), static_cast<Args&&>(args)...);
}
else
{
Expand Down
9 changes: 1 addition & 8 deletions include/vcpkg/dependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ namespace vcpkg::Dependencies

std::map<std::string, std::vector<FeatureSpec>> feature_dependencies;
std::vector<PackageSpec> package_dependencies;
std::vector<std::string> feature_list;
InternalFeatureSet feature_list;
Triplet host_triplet;

Optional<Build::AbiInfo> abi_info;
Expand Down Expand Up @@ -196,13 +196,6 @@ namespace vcpkg::Dependencies
const StatusParagraphs& status_db,
const CreateInstallPlanOptions& options = {Triplet{}});

// `features` should have "default" instead of missing "core". This is only exposed for testing purposes.
std::vector<FullPackageSpec> resolve_deps_as_top_level(const SourceControlFile& scf,
Triplet triplet,
Triplet host_triplet,
std::vector<std::string> features,
CMakeVars::CMakeVarProvider& var_provider);

ExpectedS<ActionPlan> create_versioned_install_plan(const PortFileProvider::IVersionedPortfileProvider& vprovider,
const PortFileProvider::IBaselineProvider& bprovider,
const PortFileProvider::IOverlayProvider& oprovider,
Expand Down
7 changes: 5 additions & 2 deletions include/vcpkg/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ namespace vcpkg::Input
{
PackageSpec check_and_get_package_spec(std::string&& spec_string,
Triplet default_triplet,
CStringView example_text);
CStringView example_text,
const VcpkgPaths& paths);

FullPackageSpec check_and_get_full_package_spec(std::string&& spec_string,
Triplet default_triplet,
CStringView example_text);
CStringView example_text,
const VcpkgPaths& paths);

void check_triplet(Triplet t, const VcpkgPaths& paths);
}
45 changes: 23 additions & 22 deletions include/vcpkg/packagespec.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <vcpkg/base/expected.h>
#include <vcpkg/base/json.h>
#include <vcpkg/base/optional.h>
#include <vcpkg/base/view.h>

#include <vcpkg/platform-expression.h>
#include <vcpkg/triplet.h>
Expand Down Expand Up @@ -92,6 +93,12 @@ namespace vcpkg
std::string m_feature;
};

/// In an internal feature set, "default" represents default features and missing "core" has no semantic
struct InternalFeatureSet : std::vector<std::string>
Comment thread
ras0219-msft marked this conversation as resolved.
{
using std::vector<std::string>::vector;
};

///
/// <summary>
/// Full specification of a package. Contains all information to reference
Expand All @@ -101,37 +108,22 @@ namespace vcpkg
struct FullPackageSpec
{
PackageSpec package_spec;
std::vector<std::string> features;
InternalFeatureSet features;

FullPackageSpec() = default;
explicit FullPackageSpec(PackageSpec spec, std::vector<std::string> features = {})
explicit FullPackageSpec(PackageSpec spec, InternalFeatureSet features)
: package_spec(std::move(spec)), features(std::move(features))
{
}

std::vector<FeatureSpec> to_feature_specs(const std::vector<std::string>& default_features,
const std::vector<std::string>& all_features) const;

static ExpectedS<FullPackageSpec> from_string(const std::string& spec_as_string, Triplet default_triplet);
/// Splats into individual FeatureSpec's
void expand_to(std::vector<FeatureSpec>& out) const;
Comment thread
ras0219-msft marked this conversation as resolved.
Outdated

bool operator==(const FullPackageSpec& o) const
friend bool operator==(const FullPackageSpec& l, const FullPackageSpec& r)
{
return package_spec == o.package_spec && features == o.features;
return l.package_spec == r.package_spec && l.features == r.features;
}
bool operator!=(const FullPackageSpec& o) const { return !(*this == o); }
};

///
/// <summary>
/// Contains all information to reference a collection of features in a single package by their names.
/// </summary>
///
struct Features
{
std::string name;
std::vector<std::string> features;

static ExpectedS<Features> from_string(const std::string& input);
friend bool operator!=(const FullPackageSpec& l, const FullPackageSpec& r) { return !(l == r); }
};

struct DependencyConstraint
Expand All @@ -157,6 +149,9 @@ namespace vcpkg

Json::Object extra_info;

/// @param implicit_default adds "default" if "core" not present.
FullPackageSpec to_full_spec(Triplet target, Triplet host, bool implicit_default) const;
Comment thread
ras0219-msft marked this conversation as resolved.
Outdated

friend bool operator==(const Dependency& lhs, const Dependency& rhs);
friend bool operator!=(const Dependency& lhs, const Dependency& rhs) { return !(lhs == rhs); }
};
Expand All @@ -180,6 +175,12 @@ namespace vcpkg
Optional<std::vector<std::string>> features;
Optional<std::string> triplet;
Optional<PlatformExpression::Expr> platform;

/// @param implicit_default add "default" if "core" is not present
/// @return nullopt on success. On failure, caller should supplement returned string with more context.
ExpectedS<FullPackageSpec> to_full_spec(Triplet default_triplet, bool implicit_default) const;
Comment thread
ras0219-msft marked this conversation as resolved.
Outdated

ExpectedS<PackageSpec> to_package_spec(Triplet default_triplet) const;
};

Optional<std::string> parse_feature_name(Parse::ParserBase& parser);
Expand Down
3 changes: 2 additions & 1 deletion include/vcpkg/sourceparagraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ namespace vcpkg
std::vector<FullPackageSpec> filter_dependencies(const std::vector<Dependency>& deps,
Triplet t,
Triplet host,
const std::unordered_map<std::string, std::string>& cmake_vars);
const std::unordered_map<std::string, std::string>& cmake_vars,
bool implicit_default);

struct Type
{
Expand Down
2 changes: 1 addition & 1 deletion include/vcpkg/triplet.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace vcpkg
public:
constexpr Triplet() noexcept : m_instance(&DEFAULT_INSTANCE) { }

static Triplet from_canonical_name(std::string&& triplet_as_string);
static Triplet from_canonical_name(std::string triplet_as_string);

const std::string& canonical_name() const;
const std::string& to_string() const;
Expand Down
Loading