diff --git a/include/vcpkg/binarycaching.h b/include/vcpkg/binarycaching.h index 49f91f6ae2..5cca38758e 100644 --- a/include/vcpkg/binarycaching.h +++ b/include/vcpkg/binarycaching.h @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -52,7 +53,7 @@ namespace vcpkg explicit BinaryPackageReadInfo(const InstallPlanAction& action); std::string package_abi; PackageSpec spec; - std::string raw_version; + Version version; Path package_dir; }; diff --git a/include/vcpkg/binarycaching.private.h b/include/vcpkg/binarycaching.private.h index 0987e06381..e26d8fc27a 100644 --- a/include/vcpkg/binarycaching.private.h +++ b/include/vcpkg/binarycaching.private.h @@ -19,7 +19,7 @@ namespace vcpkg // - v?. -> ..0-vcpkg // - v?.. -> ..-vcpkg // - anything else -> 0.0.0-vcpkg - std::string format_version_for_nugetref(StringView version, StringView abi_tag); + std::string format_version_for_nugetref(StringView version_text, StringView abi_tag); struct NugetReference { diff --git a/include/vcpkg/binaryparagraph.h b/include/vcpkg/binaryparagraph.h index 9aef6a1fa9..a51db9b589 100644 --- a/include/vcpkg/binaryparagraph.h +++ b/include/vcpkg/binaryparagraph.h @@ -30,11 +30,8 @@ namespace vcpkg bool is_feature() const { return !feature.empty(); } - Version get_version() const { return {version, port_version}; } - PackageSpec spec; - std::string version; - int port_version = 0; + Version version; std::vector description; std::vector maintainers; std::string feature; diff --git a/include/vcpkg/commands.build.h b/include/vcpkg/commands.build.h index 573bd9c7c3..ae45504de8 100644 --- a/include/vcpkg/commands.build.h +++ b/include/vcpkg/commands.build.h @@ -230,7 +230,7 @@ namespace vcpkg LinkageType crt_linkage = LinkageType::DYNAMIC; LinkageType library_linkage = LinkageType::DYNAMIC; - Optional detected_head_version; + Optional detected_head_version; BuildPolicies policies; }; diff --git a/include/vcpkg/fwd/versions.h b/include/vcpkg/fwd/versions.h new file mode 100644 index 0000000000..554a8eb51d --- /dev/null +++ b/include/vcpkg/fwd/versions.h @@ -0,0 +1,37 @@ +#pragma once + +namespace vcpkg +{ + struct Version; + struct VersionDiff; + struct VersionMapLess; + struct SchemedVersion; + struct VersionSpec; + struct VersionSpecHasher; + struct DotVersion; + struct DateVersion; + struct ParsedExternalVersion; + + enum class VerComp + { + unk = -2, + lt = -1, // these values are chosen to align with traditional -1/0/1 for less/equal/greater + eq = 0, + gt = 1, + }; + + enum class VersionScheme + { + Missing, + Relaxed, + Semver, + Date, + String + }; + + enum class VersionConstraintKind + { + None, + Minimum + }; +} diff --git a/include/vcpkg/sourceparagraph.h b/include/vcpkg/sourceparagraph.h index 98cdc2fb20..f36ab18642 100644 --- a/include/vcpkg/sourceparagraph.h +++ b/include/vcpkg/sourceparagraph.h @@ -25,8 +25,7 @@ namespace vcpkg struct DependencyConstraint { VersionConstraintKind type = VersionConstraintKind::None; - std::string value; - int port_version = 0; + Version version; friend bool operator==(const DependencyConstraint& lhs, const DependencyConstraint& rhs); friend bool operator!=(const DependencyConstraint& lhs, const DependencyConstraint& rhs) @@ -111,8 +110,7 @@ namespace vcpkg { std::string name; VersionScheme version_scheme = VersionScheme::String; - std::string raw_version; - int port_version = 0; + Version version; std::vector description; std::vector summary; std::vector maintainers; @@ -136,8 +134,6 @@ namespace vcpkg Json::Object extra_info; - Version to_version() const { return Version{raw_version, port_version}; } - friend bool operator==(const SourceParagraph& lhs, const SourceParagraph& rhs); friend bool operator!=(const SourceParagraph& lhs, const SourceParagraph& rhs) { return !(lhs == rhs); } }; @@ -172,12 +168,12 @@ namespace vcpkg const FeatureFlagSettings& flags, bool is_default_builtin_registry = true) const; - Version to_version() const { return core_paragraph->to_version(); } + const Version& to_version() const { return core_paragraph->version; } SchemedVersion to_schemed_version() const { - return SchemedVersion{core_paragraph->version_scheme, core_paragraph->to_version()}; + return SchemedVersion{core_paragraph->version_scheme, core_paragraph->version}; } - VersionSpec to_version_spec() const { return {core_paragraph->name, core_paragraph->to_version()}; } + VersionSpec to_version_spec() const { return {core_paragraph->name, core_paragraph->version}; } friend bool operator==(const SourceControlFile& lhs, const SourceControlFile& rhs); friend bool operator!=(const SourceControlFile& lhs, const SourceControlFile& rhs) { return !(lhs == rhs); } @@ -194,7 +190,7 @@ namespace vcpkg /// struct SourceControlFileAndLocation { - Version to_version() const { return source_control_file->to_version(); } + const Version& to_version() const { return source_control_file->to_version(); } VersionScheme scheme() const { return source_control_file->core_paragraph->version_scheme; } SchemedVersion schemed_version() const { return {scheme(), to_version()}; } diff --git a/include/vcpkg/statusparagraph.h b/include/vcpkg/statusparagraph.h index bdf9e45131..1d03eb4390 100644 --- a/include/vcpkg/statusparagraph.h +++ b/include/vcpkg/statusparagraph.h @@ -62,7 +62,7 @@ namespace vcpkg std::vector dependencies() const; std::map> feature_dependencies() const; InternalFeatureSet feature_list() const; - Version version() const; + const Version& version() const; std::vector all_status_paragraphs() const; diff --git a/include/vcpkg/versiondeserializers.h b/include/vcpkg/versiondeserializers.h index ff3016836b..4d327717ad 100644 --- a/include/vcpkg/versiondeserializers.h +++ b/include/vcpkg/versiondeserializers.h @@ -2,6 +2,8 @@ #include +#include + #include #include @@ -22,7 +24,7 @@ namespace vcpkg bool allow_hash_portversion = false); View schemed_deserializer_fields(); - void serialize_schemed_version(Json::Object& out_obj, VersionScheme scheme, StringView version, int port_version); + void serialize_schemed_version(Json::Object& out_obj, VersionScheme scheme, const Version& version); struct VersionConstraintStringDeserializer : Json::StringDeserializer { diff --git a/include/vcpkg/versions.h b/include/vcpkg/versions.h index 64b9381c78..aa00010d51 100644 --- a/include/vcpkg/versions.h +++ b/include/vcpkg/versions.h @@ -1,21 +1,33 @@ #pragma once #include +#include #include +#include + #include +#include namespace vcpkg { struct Version { Version() noexcept; - Version(std::string&& value, int port_version); - Version(const std::string& value, int port_version); + Version(std::string&& value, int port_version) noexcept; + Version(StringView value, int port_version); + template + Version(const char (&str)[N], int port_version) : Version(StringLiteral{str}, port_version) + { + } std::string to_string() const; void to_string(std::string& out) const; + // Attempts to parse `content` as a version or empty [^#]+#\d+ + // If the port-version can't be parsed as a nonnegative integer, returns nullopt. + static Optional parse(StringView content); + friend bool operator==(const Version& left, const Version& right); friend bool operator!=(const Version& left, const Version& right); @@ -23,12 +35,8 @@ namespace vcpkg // VersionMapLess is provided as a less than comparison for use in std::map. friend struct VersionMapLess; - const std::string& text() const { return m_text; } - int port_version() const { return m_port_version; } - - private: - std::string m_text; - int m_port_version = 0; + std::string text; + int port_version = 0; }; struct VersionDiff @@ -47,26 +55,9 @@ namespace vcpkg bool operator()(const Version& left, const Version& right) const; }; - enum class VerComp - { - unk = -2, - lt = -1, // these values are chosen to align with traditional -1/0/1 for less/equal/greater - eq = 0, - gt = 1, - }; - // converts a strcmp <0/0/>0 style integer into a VerComp VerComp int_to_vercomp(int comparison_result); - enum class VersionScheme - { - Missing, - Relaxed, - Semver, - Date, - String - }; - struct SchemedVersion { VersionScheme scheme; @@ -149,12 +140,6 @@ namespace vcpkg VerComp compare_versions(const SchemedVersion& a, const SchemedVersion& b); VerComp compare_versions(VersionScheme sa, const Version& a, VersionScheme sb, const Version& b); - enum class VersionConstraintKind - { - None, - Minimum - }; - // this is for version parsing that isn't in vcpkg ports // stuff like tools, nuget, etc. struct ParsedExternalVersion diff --git a/src/vcpkg-test/dependencies.cpp b/src/vcpkg-test/dependencies.cpp index 0201138489..7f035e34fc 100644 --- a/src/vcpkg-test/dependencies.cpp +++ b/src/vcpkg-test/dependencies.cpp @@ -72,11 +72,10 @@ struct MockVersionedPortfileProvider : IVersionedPortfileProvider auto scf = std::make_unique(); auto core = std::make_unique(); core->name = name; - core->raw_version = version.text(); - core->port_version = version.port_version(); core->version_scheme = scheme; + core->version = version; scf->core_paragraph = std::move(core); - it2 = version_map.emplace(version, SourceControlFileAndLocation{std::move(scf), name}).first; + it2 = version_map.emplace(std::move(version), SourceControlFileAndLocation{std::move(scf), name}).first; } return it2->second; @@ -121,8 +120,7 @@ static void check_name_and_version(const InstallPlanAction& ipa, check_name_and_features(ipa, name, features); if (auto scfl = ipa.source_control_file_and_location.get()) { - CHECK(scfl->source_control_file->core_paragraph->raw_version == v.text()); - CHECK(scfl->source_control_file->core_paragraph->port_version == v.port_version()); + CHECK(scfl->source_control_file->core_paragraph->version == v); } } @@ -195,9 +193,8 @@ struct MockOverlayProvider : IOverlayProvider auto scf = std::make_unique(); auto core = std::make_unique(); core->name = name; - core->raw_version = version.text(); - core->port_version = version.port_version(); core->version_scheme = scheme; + core->version = std::move(version); scf->core_paragraph = std::move(core); it = mappings.emplace(name, SourceControlFileAndLocation{std::move(scf), name}).first; } @@ -394,7 +391,7 @@ TEST_CASE ("basic version install scheme baseline missing 2", "[versionplan]") bp, var_provider, { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "2"}}, + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"2", 0}}}, }, {}, toplevel_spec()); @@ -434,8 +431,13 @@ TEST_CASE ("version string baseline agree", "[versionplan]") MockCMakeVarProvider var_provider; - auto install_plan = create_versioned_install_plan( - vp, bp, var_provider, {Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "2"}}}, {}, toplevel_spec()); + auto install_plan = + create_versioned_install_plan(vp, + bp, + var_provider, + {Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"2", 0}}}}, + {}, + toplevel_spec()); REQUIRE(install_plan.has_value()); } @@ -457,7 +459,7 @@ TEST_CASE ("version install scheme baseline conflict", "[versionplan]") bp, var_provider, { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "3"}}, + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"3", 0}}}, }, {}, toplevel_spec()); @@ -495,7 +497,7 @@ TEST_CASE ("version install string port version", "[versionplan]") bp, var_provider, { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "2", 1}}, + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"2", 1}}}, }, {}, toplevel_spec()) @@ -522,7 +524,7 @@ TEST_CASE ("version install string port version 2", "[versionplan]") bp, var_provider, { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "2", 0}}, + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"2", 0}}}, }, {}, toplevel_spec()) @@ -541,10 +543,10 @@ TEST_CASE ("version install transitive string", "[versionplan]") MockVersionedPortfileProvider vp; vp.emplace("a", {"2", 0}).source_control_file->core_paragraph->dependencies = { - Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "1"}}, + Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"1", 0}}}, }; vp.emplace("a", {"2", 1}).source_control_file->core_paragraph->dependencies = { - Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "2"}}, + Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"2", 0}}}, }; vp.emplace("b", {"1", 0}); vp.emplace("b", {"2", 0}); @@ -556,7 +558,7 @@ TEST_CASE ("version install transitive string", "[versionplan]") bp, var_provider, { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "2", 1}}, + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"2", 1}}}, }, {}, toplevel_spec()); @@ -585,7 +587,7 @@ TEST_CASE ("version install simple relaxed", "[versionplan]") bp, var_provider, { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "3", 0}}, + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"3", 0}}}, }, {}, toplevel_spec()) @@ -604,7 +606,7 @@ TEST_CASE ("version install transitive relaxed", "[versionplan]") MockVersionedPortfileProvider vp; vp.emplace("a", {"2", 0}, VersionScheme::Relaxed); vp.emplace("a", {"3", 0}, VersionScheme::Relaxed).source_control_file->core_paragraph->dependencies = { - Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "3"}}, + Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"3", 0}}}, }; vp.emplace("b", {"2", 0}, VersionScheme::Relaxed); vp.emplace("b", {"3", 0}, VersionScheme::Relaxed); @@ -616,7 +618,7 @@ TEST_CASE ("version install transitive relaxed", "[versionplan]") bp, var_provider, { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "3", 0}}, + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"3", 0}}}, }, {}, toplevel_spec()) @@ -637,28 +639,29 @@ TEST_CASE ("version install diamond relaxed", "[versionplan]") MockVersionedPortfileProvider vp; vp.emplace("a", {"2", 0}, VersionScheme::Relaxed); vp.emplace("a", {"3", 0}, VersionScheme::Relaxed).source_control_file->core_paragraph->dependencies = { - Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "2", 1}}, - Dependency{"c", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "5", 1}}, + Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"2", 1}}}, + Dependency{"c", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"5", 1}}}, }; vp.emplace("b", {"2", 1}, VersionScheme::Relaxed); vp.emplace("b", {"3", 0}, VersionScheme::Relaxed).source_control_file->core_paragraph->dependencies = { - Dependency{"c", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "9", 2}}, + Dependency{"c", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"9", 2}}}, }; vp.emplace("c", {"5", 1}, VersionScheme::Relaxed); vp.emplace("c", {"9", 2}, VersionScheme::Relaxed); MockCMakeVarProvider var_provider; - WITH_EXPECTED(install_plan, - create_versioned_install_plan(vp, - bp, - var_provider, - { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "3", 0}}, - Dependency{"b", {}, {}, {VersionConstraintKind::Minimum, "2", 1}}, - }, - {}, - toplevel_spec())); + WITH_EXPECTED( + install_plan, + create_versioned_install_plan(vp, + bp, + var_provider, + { + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"3", 0}}}, + Dependency{"b", {}, {}, {VersionConstraintKind::Minimum, Version{"2", 1}}}, + }, + {}, + toplevel_spec())); REQUIRE(install_plan.size() == 3); check_name_and_version(install_plan.install_actions[0], "c", {"9", 2}); @@ -890,16 +893,16 @@ TEST_CASE ("version install simple semver", "[versionplan]") MockCMakeVarProvider var_provider; - auto install_plan = - create_versioned_install_plan(vp, - bp, - var_provider, - { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "3.0.0", 0}}, - }, - {}, - toplevel_spec()) - .value_or_exit(VCPKG_LINE_INFO); + auto install_plan = create_versioned_install_plan( + vp, + bp, + var_provider, + { + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"3.0.0", 0}}}, + }, + {}, + toplevel_spec()) + .value_or_exit(VCPKG_LINE_INFO); REQUIRE(install_plan.size() == 1); check_name_and_version(install_plan.install_actions[0], "a", {"3.0.0", 0}); @@ -914,23 +917,23 @@ TEST_CASE ("version install transitive semver", "[versionplan]") MockVersionedPortfileProvider vp; vp.emplace("a", {"2.0.0", 0}, VersionScheme::Semver); vp.emplace("a", {"3.0.0", 0}, VersionScheme::Semver).source_control_file->core_paragraph->dependencies = { - Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "3.0.0"}}, + Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"3.0.0", 0}}}, }; vp.emplace("b", {"2.0.0", 0}, VersionScheme::Semver); vp.emplace("b", {"3.0.0", 0}, VersionScheme::Semver); MockCMakeVarProvider var_provider; - auto install_plan = - create_versioned_install_plan(vp, - bp, - var_provider, - { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "3.0.0", 0}}, - }, - {}, - toplevel_spec()) - .value_or_exit(VCPKG_LINE_INFO); + auto install_plan = create_versioned_install_plan( + vp, + bp, + var_provider, + { + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"3.0.0", 0}}}, + }, + {}, + toplevel_spec()) + .value_or_exit(VCPKG_LINE_INFO); REQUIRE(install_plan.size() == 2); check_name_and_version(install_plan.install_actions[0], "b", {"3.0.0", 0}); @@ -947,29 +950,29 @@ TEST_CASE ("version install diamond semver", "[versionplan]") MockVersionedPortfileProvider vp; vp.emplace("a", {"2.0.0", 0}, VersionScheme::Semver); vp.emplace("a", {"3.0.0", 0}, VersionScheme::Semver).source_control_file->core_paragraph->dependencies = { - Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "2.0.0", 1}}, - Dependency{"c", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "5.0.0", 1}}, + Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"2.0.0", 1}}}, + Dependency{"c", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"5.0.0", 1}}}, }; vp.emplace("b", {"2.0.0", 1}, VersionScheme::Semver); vp.emplace("b", {"3.0.0", 0}, VersionScheme::Semver).source_control_file->core_paragraph->dependencies = { - Dependency{"c", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "9.0.0", 2}}, + Dependency{"c", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"9.0.0", 2}}}, }; vp.emplace("c", {"5.0.0", 1}, VersionScheme::Semver); vp.emplace("c", {"9.0.0", 2}, VersionScheme::Semver); MockCMakeVarProvider var_provider; - WITH_EXPECTED( - install_plan, - create_versioned_install_plan(vp, - bp, - var_provider, - { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "3.0.0", 0}}, - Dependency{"b", {}, {}, {VersionConstraintKind::Minimum, "2.0.0", 1}}, - }, - {}, - toplevel_spec())); + WITH_EXPECTED(install_plan, + create_versioned_install_plan( + vp, + bp, + var_provider, + { + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"3.0.0", 0}}}, + Dependency{"b", {}, {}, {VersionConstraintKind::Minimum, Version{"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}); @@ -988,19 +991,19 @@ TEST_CASE ("version install simple date", "[versionplan]") MockCMakeVarProvider var_provider; - WITH_EXPECTED( - install_plan, - create_versioned_install_plan(vp, - bp, - var_provider, - { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "2020-03-01", 0}}, - }, - {}, - toplevel_spec())); + WITH_EXPECTED(install_plan, + create_versioned_install_plan( + vp, + bp, + var_provider, + { + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"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}); + check_name_and_version(install_plan.install_actions[0], "a", Version{"2020-03-01", 0}); } TEST_CASE ("version install transitive date", "[versionplan]") @@ -1012,23 +1015,23 @@ TEST_CASE ("version install transitive date", "[versionplan]") MockVersionedPortfileProvider vp; vp.emplace("a", {"2020-01-01.2", 0}, VersionScheme::Date); vp.emplace("a", {"2020-01-01.3", 0}, VersionScheme::Date).source_control_file->core_paragraph->dependencies = { - Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "2020-01-01.3"}}, + Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"2020-01-01.3", 0}}}, }; vp.emplace("b", {"2020-01-01.2", 0}, VersionScheme::Date); vp.emplace("b", {"2020-01-01.3", 0}, VersionScheme::Date); MockCMakeVarProvider var_provider; - WITH_EXPECTED( - install_plan, - create_versioned_install_plan(vp, - bp, - var_provider, - { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "2020-01-01.3", 0}}, - }, - {}, - toplevel_spec())); + WITH_EXPECTED(install_plan, + create_versioned_install_plan( + vp, + bp, + var_provider, + { + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"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}); @@ -1045,34 +1048,34 @@ TEST_CASE ("version install diamond date", "[versionplan]") MockVersionedPortfileProvider vp; vp.emplace("a", {"2020-01-02", 0}, VersionScheme::Date); vp.emplace("a", {"2020-01-03", 0}, VersionScheme::Date).source_control_file->core_paragraph->dependencies = { - Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "2020-01-02", 1}}, - Dependency{"c", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "2020-01-05", 1}}, + Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"2020-01-02", 1}}}, + Dependency{"c", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"2020-01-05", 1}}}, }; vp.emplace("b", {"2020-01-02", 1}, VersionScheme::Date); vp.emplace("b", {"2020-01-03", 0}, VersionScheme::Date).source_control_file->core_paragraph->dependencies = { - Dependency{"c", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "2020-01-09", 2}}, + Dependency{"c", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"2020-01-09", 2}}}, }; vp.emplace("c", {"2020-01-05", 1}, VersionScheme::Date); vp.emplace("c", {"2020-01-09", 2}, VersionScheme::Date); MockCMakeVarProvider var_provider; - WITH_EXPECTED( - install_plan, - create_versioned_install_plan(vp, - bp, - var_provider, - { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "2020-01-03", 0}}, - Dependency{"b", {}, {}, {VersionConstraintKind::Minimum, "2020-01-02", 1}}, - }, - {}, - toplevel_spec())); + WITH_EXPECTED(install_plan, + create_versioned_install_plan( + vp, + bp, + var_provider, + { + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"2020-01-03", 0}}}, + Dependency{"b", {}, {}, {VersionConstraintKind::Minimum, Version{"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}); - check_name_and_version(install_plan.install_actions[1], "b", {"2020-01-03", 0}); - check_name_and_version(install_plan.install_actions[2], "a", {"2020-01-03", 0}); + check_name_and_version(install_plan.install_actions[0], "c", Version{"2020-01-09", 2}); + check_name_and_version(install_plan.install_actions[1], "b", Version{"2020-01-03", 0}); + check_name_and_version(install_plan.install_actions[2], "a", Version{"2020-01-03", 0}); } TEST_CASE ("version install scheme failure", "[versionplan]") @@ -1089,13 +1092,13 @@ TEST_CASE ("version install scheme failure", "[versionplan]") MockBaselineProvider bp; bp.v["a"] = {"1.0.0", 0}; - auto install_plan = - create_versioned_install_plan(vp, - bp, - var_provider, - {Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "1.0.1", 0}}}, - {}, - toplevel_spec()); + auto install_plan = create_versioned_install_plan( + vp, + bp, + var_provider, + {Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"1.0.1", 0}}}}, + {}, + toplevel_spec()); REQUIRE(!install_plan.error().empty()); REQUIRE_LINES( @@ -1119,13 +1122,13 @@ See `vcpkg help versioning` or https://learn.microsoft.com/vcpkg/users/versionin MockBaselineProvider bp; bp.v["a"] = {"1.0.2", 0}; - auto install_plan = - create_versioned_install_plan(vp, - bp, - var_provider, - {Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "1.0.1", 0}}}, - {}, - toplevel_spec()); + auto install_plan = create_versioned_install_plan( + vp, + bp, + var_provider, + {Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"1.0.1", 0}}}}, + {}, + toplevel_spec()); REQUIRE(!install_plan.error().empty()); REQUIRE_LINES( @@ -1160,14 +1163,14 @@ TEST_CASE ("version install relaxed cross with semver success", "[versionplan]") MockBaselineProvider bp; bp.v["a"] = {"1.0.0", 0}; - auto install_plan = - create_versioned_install_plan(vp, - bp, - var_provider, - {Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "1.0.1", 0}}}, - {}, - toplevel_spec()) - .value_or_exit(VCPKG_LINE_INFO); + auto install_plan = create_versioned_install_plan( + vp, + bp, + var_provider, + {Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"1.0.1", 0}}}}, + {}, + toplevel_spec()) + .value_or_exit(VCPKG_LINE_INFO); check_name_and_version(install_plan.install_actions[0], "a", {"1.0.1", 0}); } @@ -1176,16 +1179,16 @@ TEST_CASE ("version install relaxed cross with semver success", "[versionplan]") MockBaselineProvider bp; bp.v["a"] = {"1.0.2", 0}; - auto install_plan = - create_versioned_install_plan(vp, - bp, - var_provider, - {Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "1.0.1", 0}}}, - {}, - toplevel_spec()) - .value_or_exit(VCPKG_LINE_INFO); + auto install_plan = create_versioned_install_plan( + vp, + bp, + var_provider, + {Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"1.0.1", 0}}}}, + {}, + toplevel_spec()) + .value_or_exit(VCPKG_LINE_INFO); - check_name_and_version(install_plan.install_actions[0], "a", {"1.0.2", 0}); + check_name_and_version(install_plan.install_actions[0], "a", Version{"1.0.2", 0}); } } @@ -1193,10 +1196,10 @@ TEST_CASE ("version install scheme change in port version", "[versionplan]") { MockVersionedPortfileProvider vp; vp.emplace("a", {"2", 0}).source_control_file->core_paragraph->dependencies = { - Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "1"}}, + Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"1", 0}}}, }; vp.emplace("a", {"2", 1}).source_control_file->core_paragraph->dependencies = { - Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, "1", 1}}, + Dependency{"b", {}, {}, DependencyConstraint{VersionConstraintKind::Minimum, Version{"1", 1}}}, }; vp.emplace("b", {"1", 0}, VersionScheme::String); vp.emplace("b", {"1", 1}, VersionScheme::Relaxed); @@ -1209,15 +1212,15 @@ TEST_CASE ("version install scheme change in port version", "[versionplan]") bp.v["a"] = {"2", 0}; bp.v["b"] = {"1", 0}; - auto install_plan = - create_versioned_install_plan(vp, - bp, - var_provider, - { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "2", 1}}, - }, - {}, - toplevel_spec()); + auto install_plan = create_versioned_install_plan( + vp, + bp, + var_provider, + { + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"2", 1}}}, + }, + {}, + toplevel_spec()); REQUIRE(!install_plan.has_value()); REQUIRE_LINES( @@ -1242,16 +1245,16 @@ See `vcpkg help versioning` or https://learn.microsoft.com/vcpkg/users/versionin bp.v["a"] = {"2", 0}; bp.v["b"] = {"1", 1}; - WITH_EXPECTED( - install_plan, - create_versioned_install_plan(vp, - bp, - var_provider, - { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "2", 1}}, - }, - {}, - toplevel_spec())); + WITH_EXPECTED(install_plan, + create_versioned_install_plan( + vp, + bp, + var_provider, + { + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"2", 1}}}, + }, + {}, + toplevel_spec())); REQUIRE(install_plan.size() == 2); check_name_and_version(install_plan.install_actions[0], "b", {"1", 1}); @@ -1263,16 +1266,16 @@ See `vcpkg help versioning` or https://learn.microsoft.com/vcpkg/users/versionin bp.v["a"] = {"2", 1}; bp.v["b"] = {"1", 1}; - WITH_EXPECTED( - install_plan, - create_versioned_install_plan(vp, - bp, - var_provider, - { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "2", 0}}, - }, - {}, - toplevel_spec())); + WITH_EXPECTED(install_plan, + create_versioned_install_plan( + vp, + bp, + var_provider, + { + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"2", 0}}}, + }, + {}, + toplevel_spec())); REQUIRE(install_plan.size() == 2); check_name_and_version(install_plan.install_actions[0], "b", {"1", 1}); @@ -1362,15 +1365,15 @@ TEST_CASE ("version install simple feature", "[versionplan]") { MockBaselineProvider bp; - auto install_plan = - create_versioned_install_plan(vp, - bp, - var_provider, - { - Dependency{"a", {{"x"}}, {}, {VersionConstraintKind::Minimum, "1", 0}}, - }, - {}, - toplevel_spec()); + auto install_plan = create_versioned_install_plan( + vp, + bp, + var_provider, + { + Dependency{"a", {{"x"}}, {}, {VersionConstraintKind::Minimum, Version{"1", 0}}}, + }, + {}, + toplevel_spec()); REQUIRE_FALSE(install_plan.has_value()); REQUIRE(install_plan.error() == "MockBaselineProvider::get_baseline_version(a)"); @@ -1421,7 +1424,7 @@ TEST_CASE ("version install transitive feature versioned", "[versionplan]") MockVersionedPortfileProvider vp; auto a_x = make_fpgh("x"); - a_x->dependencies.push_back(Dependency{"b", {{"y"}}, {}, {VersionConstraintKind::Minimum, "2", 0}}); + a_x->dependencies.push_back(Dependency{"b", {{"y"}}, {}, {VersionConstraintKind::Minimum, Version{"2", 0}}}); vp.emplace("a", {"1", 0}, VersionScheme::Relaxed).source_control_file->feature_paragraphs.push_back(std::move(a_x)); { @@ -1473,10 +1476,10 @@ TEST_CASE ("version install constraint-reduction", "[versionplan]") MockVersionedPortfileProvider vp; vp.emplace("b", {"1", 0}, VersionScheme::Relaxed).source_control_file->core_paragraph->dependencies = { - Dependency{"c", {}, {}, {VersionConstraintKind::Minimum, "2"}}, + Dependency{"c", {}, {}, {VersionConstraintKind::Minimum, Version{"2", 0}}}, }; vp.emplace("b", {"2", 0}, VersionScheme::Relaxed).source_control_file->core_paragraph->dependencies = { - Dependency{"c", {}, {}, {VersionConstraintKind::Minimum, "1"}}, + Dependency{"c", {}, {}, {VersionConstraintKind::Minimum, Version{"1", 0}}}, }; vp.emplace("c", {"1", 0}, VersionScheme::Relaxed); @@ -1487,16 +1490,16 @@ TEST_CASE ("version install constraint-reduction", "[versionplan]") bp.v["b"] = {"2", 0}; bp.v["c"] = {"1", 0}; - auto install_plan = - create_versioned_install_plan(vp, - bp, - var_provider, - { - Dependency{"b", {}, {}, {VersionConstraintKind::Minimum, "1"}}, - }, - {}, - toplevel_spec()) - .value_or_exit(VCPKG_LINE_INFO); + auto install_plan = create_versioned_install_plan( + vp, + bp, + var_provider, + { + Dependency{"b", {}, {}, {VersionConstraintKind::Minimum, Version{"1", 0}}}, + }, + {}, + toplevel_spec()) + .value_or_exit(VCPKG_LINE_INFO); REQUIRE(install_plan.size() == 2); check_name_and_version(install_plan.install_actions[0], "c", {"1", 0}); @@ -1508,10 +1511,10 @@ TEST_CASE ("version install constraint-reduction", "[versionplan]") MockVersionedPortfileProvider vp; vp.emplace("b", {"1", 0}, VersionScheme::Relaxed).source_control_file->core_paragraph->dependencies = { - Dependency{"c", {}, {}, {VersionConstraintKind::Minimum, "2"}}, + Dependency{"c", {}, {}, {VersionConstraintKind::Minimum, Version{"2", 0}}}, }; vp.emplace("b", {"2", 0}, VersionScheme::Relaxed).source_control_file->core_paragraph->dependencies = { - Dependency{"c", {}, {}, {VersionConstraintKind::Minimum, "1"}}, + Dependency{"c", {}, {}, {VersionConstraintKind::Minimum, Version{"1", 0}}}, }; vp.emplace("c", {"1", 0}, VersionScheme::Relaxed); @@ -1523,18 +1526,19 @@ TEST_CASE ("version install constraint-reduction", "[versionplan]") bp.v["c"] = {"1", 0}; WITH_EXPECTED(install_plan, - create_versioned_install_plan(vp, - bp, - var_provider, - { - Dependency{"b", {}, {}, {VersionConstraintKind::Minimum, "2"}}, - }, - {}, - toplevel_spec())); + create_versioned_install_plan( + vp, + bp, + var_provider, + { + Dependency{"b", {}, {}, {VersionConstraintKind::Minimum, Version{"2", 0}}}, + }, + {}, + toplevel_spec())); REQUIRE(install_plan.size() == 2); - check_name_and_version(install_plan.install_actions[0], "c", {"2", 0}); - check_name_and_version(install_plan.install_actions[1], "b", {"2", 0}); + check_name_and_version(install_plan.install_actions[0], "c", Version{"2", 0}); + check_name_and_version(install_plan.install_actions[1], "b", Version{"2", 0}); } } @@ -1584,7 +1588,7 @@ TEST_CASE ("version install transitive overrides", "[versionplan]") vp.emplace("b", {"1", 0}, VersionScheme::Relaxed) .source_control_file->core_paragraph->dependencies.push_back( - {"c", {}, {}, {VersionConstraintKind::Minimum, "2", 1}}); + {"c", {}, {}, {VersionConstraintKind::Minimum, Version{"2", 1}}}); vp.emplace("b", {"2", 0}, VersionScheme::Relaxed); vp.emplace("c", {"1", 0}, VersionScheme::String); vp.emplace("c", {"2", 1}, VersionScheme::String); @@ -1599,8 +1603,8 @@ TEST_CASE ("version install transitive overrides", "[versionplan]") create_versioned_install_plan(vp, bp, var_provider, {Dependency{"b"}}, {bdo, cdo}, toplevel_spec())); REQUIRE(install_plan.size() == 2); - check_name_and_version(install_plan.install_actions[0], "c", {"1", 0}); - check_name_and_version(install_plan.install_actions[1], "b", {"1", 0}); + check_name_and_version(install_plan.install_actions[0], "c", Version{"1", 0}); + check_name_and_version(install_plan.install_actions[1], "b", Version{"1", 0}); } TEST_CASE ("version install default features", "[versionplan]") @@ -1944,7 +1948,7 @@ TEST_CASE ("version remove features during upgrade", "[versionplan]") // a@0 -> b[x], c>=1 auto& a_scf = vp.emplace("a", {"1", 0}).source_control_file; a_scf->core_paragraph->dependencies.push_back({"b", {{"x"}}}); - a_scf->core_paragraph->dependencies.push_back({"c", {}, {}, {VersionConstraintKind::Minimum, "1", 1}}); + a_scf->core_paragraph->dependencies.push_back({"c", {}, {}, {VersionConstraintKind::Minimum, Version{"1", 1}}}); // a@1 -> b auto& a1_scf = vp.emplace("a", {"1", 1}).source_control_file; a1_scf->core_paragraph->dependencies.push_back({"b"}); @@ -1961,17 +1965,17 @@ TEST_CASE ("version remove features during upgrade", "[versionplan]") create_versioned_install_plan(vp, bp, { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "1"}}, - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "1", 1}}, - Dependency{"b", {}, {}, {VersionConstraintKind::Minimum, "1", 1}}, + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"1", 0}}}, + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"1", 1}}}, + Dependency{"b", {}, {}, {VersionConstraintKind::Minimum, Version{"1", 1}}}, Dependency{"c"}, }) .value_or_exit(VCPKG_LINE_INFO); REQUIRE(install_plan.size() == 3); - check_name_and_version(install_plan.install_actions[0], "c", {"1", 1}); - check_name_and_version(install_plan.install_actions[1], "b", {"1", 1}); - check_name_and_version(install_plan.install_actions[2], "a", {"1", 1}); + check_name_and_version(install_plan.install_actions[0], "c", Version{"1", 1}); + check_name_and_version(install_plan.install_actions[1], "b", Version{"1", 1}); + check_name_and_version(install_plan.install_actions[2], "a", Version{"1", 1}); } TEST_CASE ("version install host tool", "[versionplan]") @@ -1998,9 +2002,9 @@ TEST_CASE ("version install host tool", "[versionplan]") auto install_plan = create_versioned_install_plan(vp, bp, {dep_c}).value_or_exit(VCPKG_LINE_INFO); REQUIRE(install_plan.size() == 2); - check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}); + check_name_and_version(install_plan.install_actions[0], "a", Version{"1", 0}); REQUIRE(install_plan.install_actions[0].spec.triplet() == Test::X86_WINDOWS); - check_name_and_version(install_plan.install_actions[1], "c", {"1", 0}); + check_name_and_version(install_plan.install_actions[1], "c", Version{"1", 0}); REQUIRE(install_plan.install_actions[1].spec.triplet() == Test::X86_WINDOWS); } SECTION ("toplevel") @@ -2011,7 +2015,7 @@ TEST_CASE ("version install host tool", "[versionplan]") WITH_EXPECTED(install_plan, create_versioned_install_plan(vp, bp, {dep_a})); REQUIRE(install_plan.size() == 1); - check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}); + check_name_and_version(install_plan.install_actions[0], "a", Version{"1", 0}); REQUIRE(install_plan.install_actions[0].spec.triplet() == Test::ARM_UWP); } SECTION ("transitive 1") @@ -2019,10 +2023,10 @@ TEST_CASE ("version install host tool", "[versionplan]") WITH_EXPECTED(install_plan, create_versioned_install_plan(vp, bp, {{"b"}})); REQUIRE(install_plan.size() == 2); - check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}); + check_name_and_version(install_plan.install_actions[0], "a", Version{"1", 0}); REQUIRE(install_plan.install_actions[0].spec.triplet() == Test::ARM_UWP); CHECK(install_plan.install_actions[0].request_type == RequestType::AUTO_SELECTED); - check_name_and_version(install_plan.install_actions[1], "b", {"1", 0}); + check_name_and_version(install_plan.install_actions[1], "b", Version{"1", 0}); REQUIRE(install_plan.install_actions[1].spec.triplet() == Test::X86_WINDOWS); CHECK(install_plan.install_actions[1].request_type == RequestType::USER_REQUESTED); } @@ -2034,10 +2038,10 @@ TEST_CASE ("version install host tool", "[versionplan]") WITH_EXPECTED(install_plan, create_versioned_install_plan(vp, bp, {dep_c})); REQUIRE(install_plan.size() == 2); - check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}); + check_name_and_version(install_plan.install_actions[0], "a", Version{"1", 0}); REQUIRE(install_plan.install_actions[0].spec.triplet() == Test::ARM_UWP); CHECK(install_plan.install_actions[0].request_type == RequestType::AUTO_SELECTED); - check_name_and_version(install_plan.install_actions[1], "c", {"1", 0}); + check_name_and_version(install_plan.install_actions[1], "c", Version{"1", 0}); REQUIRE(install_plan.install_actions[1].spec.triplet() == Test::ARM_UWP); CHECK(install_plan.install_actions[1].request_type == RequestType::USER_REQUESTED); } @@ -2046,10 +2050,10 @@ TEST_CASE ("version install host tool", "[versionplan]") WITH_EXPECTED(install_plan, create_versioned_install_plan(vp, bp, {{"d"}})); REQUIRE(install_plan.size() == 2); - check_name_and_version(install_plan.install_actions[0], "d", {"1", 0}); + check_name_and_version(install_plan.install_actions[0], "d", Version{"1", 0}); REQUIRE(install_plan.install_actions[0].spec.triplet() == Test::ARM_UWP); CHECK(install_plan.install_actions[0].request_type == RequestType::AUTO_SELECTED); - check_name_and_version(install_plan.install_actions[1], "d", {"1", 0}); + check_name_and_version(install_plan.install_actions[1], "d", Version{"1", 0}); REQUIRE(install_plan.install_actions[1].spec.triplet() == Test::X86_WINDOWS); CHECK(install_plan.install_actions[1].request_type == RequestType::USER_REQUESTED); } @@ -2068,7 +2072,7 @@ TEST_CASE ("version overlay ports", "[versionplan]") 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", {}, {}, {VersionConstraintKind::Minimum, "1", 1}}); + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"1", 1}}}); MockCMakeVarProvider var_provider; @@ -2084,7 +2088,7 @@ TEST_CASE ("version overlay ports", "[versionplan]") .value_or_exit(VCPKG_LINE_INFO); REQUIRE(install_plan.size() == 1); - check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0}); + check_name_and_version(install_plan.install_actions[0], "a", Version{"overlay", 0}); } SECTION ("transitive") @@ -2093,8 +2097,8 @@ TEST_CASE ("version overlay ports", "[versionplan]") .value_or_exit(VCPKG_LINE_INFO); 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}); + check_name_and_version(install_plan.install_actions[0], "a", Version{"overlay", 0}); + check_name_and_version(install_plan.install_actions[1], "b", Version{"1", 0}); } SECTION ("transitive constraint") @@ -2103,8 +2107,8 @@ TEST_CASE ("version overlay ports", "[versionplan]") .value_or_exit(VCPKG_LINE_INFO); 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}); + check_name_and_version(install_plan.install_actions[0], "a", Version{"overlay", 0}); + check_name_and_version(install_plan.install_actions[1], "c", Version{"1", 0}); } SECTION ("none") @@ -2117,36 +2121,36 @@ TEST_CASE ("version overlay ports", "[versionplan]") } SECTION ("constraint") { - auto install_plan = - create_versioned_install_plan(vp, - bp, - oprovider, - var_provider, - { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "1", 1}}, - }, - {}, - toplevel_spec()) - .value_or_exit(VCPKG_LINE_INFO); + auto install_plan = create_versioned_install_plan( + vp, + bp, + oprovider, + var_provider, + { + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"1", 1}}}, + }, + {}, + toplevel_spec()) + .value_or_exit(VCPKG_LINE_INFO); REQUIRE(install_plan.size() == 1); check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0}); } SECTION ("constraint+override") { - auto install_plan = - create_versioned_install_plan(vp, - bp, - oprovider, - var_provider, - { - Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, "1", 1}}, - }, - { - DependencyOverride{"a", Version{"2", 0}, VersionScheme::String}, - }, - toplevel_spec()) - .value_or_exit(VCPKG_LINE_INFO); + auto install_plan = create_versioned_install_plan( + vp, + bp, + oprovider, + var_provider, + { + Dependency{"a", {}, {}, {VersionConstraintKind::Minimum, Version{"1", 1}}}, + }, + { + DependencyOverride{"a", Version{"2", 0}, VersionScheme::String}, + }, + toplevel_spec()) + .value_or_exit(VCPKG_LINE_INFO); REQUIRE(install_plan.size() == 1); check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0}); diff --git a/src/vcpkg-test/manifests.cpp b/src/vcpkg-test/manifests.cpp index 5b3547b523..e98ce45498 100644 --- a/src/vcpkg-test/manifests.cpp +++ b/src/vcpkg-test/manifests.cpp @@ -98,8 +98,8 @@ TEST_CASE ("manifest construct minimum", "[manifests]") auto& pgh = **m_pgh.get(); REQUIRE(pgh.core_paragraph->name == "zlib"); - REQUIRE(pgh.core_paragraph->raw_version == "1.2.8"); REQUIRE(pgh.core_paragraph->version_scheme == VersionScheme::String); + REQUIRE(pgh.core_paragraph->version == Version{"1.2.8", 0}); REQUIRE(pgh.core_paragraph->maintainers.empty()); REQUIRE(pgh.core_paragraph->contacts.is_empty()); REQUIRE(pgh.core_paragraph->summary.empty()); @@ -131,8 +131,8 @@ TEST_CASE ("project manifest construct minimum", "[manifests]") auto& pgh = **m_pgh.get(); REQUIRE(pgh.core_paragraph->name.empty()); - REQUIRE(pgh.core_paragraph->raw_version == ""); REQUIRE(pgh.core_paragraph->version_scheme == VersionScheme::Missing); + REQUIRE(pgh.core_paragraph->version == Version{}); REQUIRE(pgh.core_paragraph->maintainers.empty()); REQUIRE(pgh.core_paragraph->contacts.is_empty()); REQUIRE(pgh.core_paragraph->summary.empty()); @@ -201,8 +201,7 @@ TEST_CASE ("manifest versioning", "[manifests]") auto& pgh = **m_pgh.get(); CHECK(Json::stringify(serialize_manifest(pgh)) == Json::stringify(projectManifest)); CHECK(pgh.core_paragraph->version_scheme == std::get<1>(v)); - CHECK(pgh.core_paragraph->raw_version == std::get<2>(v)); - CHECK(pgh.core_paragraph->port_version == 0); + CHECK(pgh.core_paragraph->version == Version{std::get<2>(v), 0}); } { // port manifest @@ -211,8 +210,7 @@ TEST_CASE ("manifest versioning", "[manifests]") auto& pgh = **m_pgh.get(); CHECK(Json::stringify(serialize_manifest(pgh)) == Json::stringify(portManifest)); CHECK(pgh.core_paragraph->version_scheme == std::get<1>(v)); - CHECK(pgh.core_paragraph->raw_version == std::get<2>(v)); - CHECK(pgh.core_paragraph->port_version == 0); + CHECK(pgh.core_paragraph->version == Version{std::get<2>(v), 0}); } } @@ -286,8 +284,7 @@ TEST_CASE ("manifest constraints hash", "[manifests]") })json"); REQUIRE(m_pgh.has_value()); const auto& p = *m_pgh.get(); - REQUIRE(p->core_paragraph->dependencies.at(0).constraint.value == "2018-09-01"); - REQUIRE(p->core_paragraph->dependencies.at(0).constraint.port_version == 1); + REQUIRE(p->core_paragraph->dependencies.at(0).constraint.version == Version{"2018-09-01", 1}); } { @@ -303,8 +300,7 @@ TEST_CASE ("manifest constraints hash", "[manifests]") })json"); REQUIRE(m_pgh.has_value()); const auto& p = *m_pgh.get(); - REQUIRE(p->core_paragraph->dependencies.at(0).constraint.value == "2018-09-01"); - REQUIRE(p->core_paragraph->dependencies.at(0).constraint.port_version == 0); + REQUIRE(p->core_paragraph->dependencies.at(0).constraint.version == Version{"2018-09-01", 0}); } REQUIRE_FALSE(port_manifest_is_parsable(R"json({ @@ -475,12 +471,12 @@ TEST_CASE ("manifest constraints", "[manifests]") REQUIRE(Json::stringify(serialize_manifest(pgh), Json::JsonStyle::with_spaces(4)) == raw); REQUIRE(pgh.core_paragraph->dependencies.size() == 3); REQUIRE(pgh.core_paragraph->dependencies[0].name == "a"); - REQUIRE(pgh.core_paragraph->dependencies[0].constraint == DependencyConstraint{VersionConstraintKind::None, "", 0}); + REQUIRE(pgh.core_paragraph->dependencies[0].constraint == DependencyConstraint{}); REQUIRE(pgh.core_paragraph->dependencies[1].name == "c"); - REQUIRE(pgh.core_paragraph->dependencies[1].constraint == DependencyConstraint{VersionConstraintKind::None, "", 0}); + REQUIRE(pgh.core_paragraph->dependencies[1].constraint == DependencyConstraint{}); REQUIRE(pgh.core_paragraph->dependencies[2].name == "d"); REQUIRE(pgh.core_paragraph->dependencies[2].constraint == - DependencyConstraint{VersionConstraintKind::Minimum, "2018-09-01", 0}); + DependencyConstraint{VersionConstraintKind::Minimum, Version{"2018-09-01", 0}}); REQUIRE(pgh.core_paragraph->builtin_baseline == "089fa4de7dca22c67dcab631f618d5cd0697c8d4"); REQUIRE_FALSE(port_manifest_is_parsable(R"json({ @@ -576,9 +572,8 @@ TEST_CASE ("manifest builtin-baseline", "[manifests]") REQUIRE(m_pgh.has_value()); auto& pgh = **m_pgh.get(); REQUIRE(pgh.core_paragraph->dependencies.size() == 1); - REQUIRE(pgh.core_paragraph->dependencies[0].constraint.value == "abcd"); - REQUIRE(pgh.core_paragraph->dependencies[0].constraint.port_version == 1); REQUIRE(pgh.core_paragraph->dependencies[0].constraint.type == VersionConstraintKind::Minimum); + REQUIRE(pgh.core_paragraph->dependencies[0].constraint.version == Version{"abcd", 1}); REQUIRE(pgh.core_paragraph->overrides.size() == 1); const auto& first_override = pgh.core_paragraph->overrides[0]; REQUIRE(first_override.version == Version{"abcd", 0}); @@ -613,13 +608,12 @@ TEST_CASE ("manifest builtin-baseline", "[manifests]") REQUIRE(m_pgh.has_value()); auto& pgh = **m_pgh.get(); REQUIRE(pgh.core_paragraph->dependencies.size() == 1); - REQUIRE(pgh.core_paragraph->dependencies[0].constraint.value == "abcd"); - REQUIRE(pgh.core_paragraph->dependencies[0].constraint.port_version == 1); REQUIRE(pgh.core_paragraph->dependencies[0].constraint.type == VersionConstraintKind::Minimum); + REQUIRE(pgh.core_paragraph->dependencies[0].constraint.version == Version{"abcd", 1}); REQUIRE(pgh.core_paragraph->overrides.size() == 1); const auto& first_override = pgh.core_paragraph->overrides[0]; - REQUIRE(first_override.version == Version{"abcd", 0}); REQUIRE(first_override.scheme == VersionScheme::String); + REQUIRE(first_override.version == Version{"abcd", 0}); REQUIRE(!pgh.core_paragraph->builtin_baseline.has_value()); REQUIRE(!pgh.check_against_feature_flags({}, feature_flags_without_versioning)); REQUIRE(!pgh.check_against_feature_flags({}, feature_flags_with_versioning)); @@ -695,8 +689,8 @@ TEST_CASE ("manifest overrides", "[manifests]") REQUIRE(Json::stringify(serialize_manifest(pgh), Json::JsonStyle::with_spaces(4)) == std::get<0>(v)); REQUIRE(pgh.core_paragraph->overrides.size() == 1); const auto& first_override = pgh.core_paragraph->overrides[0]; - REQUIRE(first_override.version == Version{std::get<2>(v).to_string(), 0}); REQUIRE(first_override.scheme == std::get<1>(v)); + REQUIRE(first_override.version == Version{std::get<2>(v).to_string(), 0}); REQUIRE(!pgh.check_against_feature_flags({}, feature_flags_without_versioning)); REQUIRE(pgh.check_against_feature_flags({}, feature_flags_with_versioning)); } @@ -752,11 +746,11 @@ TEST_CASE ("manifest overrides", "[manifests]") const auto& first_override = pgh.core_paragraph->overrides[0]; const auto& second_override = pgh.core_paragraph->overrides[1]; REQUIRE(first_override.name == "abc"); - REQUIRE(first_override.version == Version{"hello", 5}); REQUIRE(first_override.scheme == VersionScheme::String); + REQUIRE(first_override.version == Version{"hello", 5}); REQUIRE(second_override.name == "abcd"); - REQUIRE(second_override.version == Version{"hello", 7}); REQUIRE(second_override.scheme == VersionScheme::String); + REQUIRE(second_override.version == Version{"hello", 7}); } REQUIRE(!pgh.check_against_feature_flags({}, feature_flags_without_versioning)); @@ -834,12 +828,12 @@ TEST_CASE ("manifest embed configuration", "[manifests]") REQUIRE(pgh.core_paragraph->builtin_baseline == "089fa4de7dca22c67dcab631f618d5cd0697c8d4"); REQUIRE(pgh.core_paragraph->dependencies.size() == 3); REQUIRE(pgh.core_paragraph->dependencies[0].name == "a"); - REQUIRE(pgh.core_paragraph->dependencies[0].constraint == DependencyConstraint{VersionConstraintKind::None, "", 0}); + REQUIRE(pgh.core_paragraph->dependencies[0].constraint == DependencyConstraint{}); REQUIRE(pgh.core_paragraph->dependencies[1].name == "b"); - REQUIRE(pgh.core_paragraph->dependencies[1].constraint == DependencyConstraint{VersionConstraintKind::None, "", 0}); + REQUIRE(pgh.core_paragraph->dependencies[1].constraint == DependencyConstraint{}); REQUIRE(pgh.core_paragraph->dependencies[2].name == "c"); REQUIRE(pgh.core_paragraph->dependencies[2].constraint == - DependencyConstraint{VersionConstraintKind::Minimum, "2018-09-01", 0}); + DependencyConstraint{VersionConstraintKind::Minimum, Version{"2018-09-01", 0}}); auto config = Json::parse(raw_config, "").value(VCPKG_LINE_INFO).value; REQUIRE(config.is_object()); @@ -915,7 +909,8 @@ TEST_CASE ("manifest construct maximum", "[manifests]") auto& pgh = **res.get(); REQUIRE(pgh.core_paragraph->name == "s"); - REQUIRE(pgh.core_paragraph->raw_version == "v"); + REQUIRE(pgh.core_paragraph->version_scheme == VersionScheme::String); + REQUIRE(pgh.core_paragraph->version == Version{"v", 0}); REQUIRE(pgh.core_paragraph->maintainers.size() == 1); REQUIRE(pgh.core_paragraph->maintainers[0] == "m"); REQUIRE(pgh.core_paragraph->contacts.size() == 1); @@ -1038,7 +1033,8 @@ TEST_CASE ("SourceParagraph manifest construct qualified dependencies", "[manife auto& pgh = **m_pgh.get(); REQUIRE(pgh.core_paragraph->name == "zlib"); - REQUIRE(pgh.core_paragraph->raw_version == "1.2.8"); + REQUIRE(pgh.core_paragraph->version_scheme == VersionScheme::String); + REQUIRE(pgh.core_paragraph->version == Version{"1.2.8", 0}); REQUIRE(pgh.core_paragraph->maintainers.empty()); REQUIRE(pgh.core_paragraph->description.empty()); REQUIRE(pgh.core_paragraph->dependencies.size() == 2); @@ -1067,7 +1063,8 @@ TEST_CASE ("SourceParagraph manifest construct host dependencies", "[manifests]" auto& pgh = **m_pgh.get(); REQUIRE(pgh.core_paragraph->name == "zlib"); - REQUIRE(pgh.core_paragraph->raw_version == "1.2.8"); + REQUIRE(pgh.core_paragraph->version_scheme == VersionScheme::String); + REQUIRE(pgh.core_paragraph->version == Version{"1.2.8", 0}); REQUIRE(pgh.core_paragraph->maintainers.empty()); REQUIRE(pgh.core_paragraph->description.empty()); REQUIRE(pgh.core_paragraph->dependencies.size() == 2); diff --git a/src/vcpkg-test/paragraph.cpp b/src/vcpkg-test/paragraph.cpp index cf60cbeb13..c5b8740381 100644 --- a/src/vcpkg-test/paragraph.cpp +++ b/src/vcpkg-test/paragraph.cpp @@ -4,8 +4,7 @@ #include -namespace Strings = vcpkg::Strings; -using vcpkg::Paragraph; +using namespace vcpkg; namespace { @@ -43,7 +42,7 @@ TEST_CASE ("SourceParagraph construct minimum", "[paragraph]") auto& pgh = **m_pgh.get(); REQUIRE(pgh.core_paragraph->name == "zlib"); - REQUIRE(pgh.core_paragraph->raw_version == "1.2.8"); + REQUIRE(pgh.core_paragraph->version == Version{"1.2.8", 0}); REQUIRE(pgh.core_paragraph->maintainers.empty()); REQUIRE(pgh.core_paragraph->description.empty()); REQUIRE(pgh.core_paragraph->dependencies.size() == 0); @@ -107,7 +106,7 @@ TEST_CASE ("SourceParagraph construct maximum", "[paragraph]") auto& pgh = **m_pgh.get(); REQUIRE(pgh.core_paragraph->name == "s"); - REQUIRE(pgh.core_paragraph->raw_version == "v"); + REQUIRE(pgh.core_paragraph->version == Version{"v", 0}); REQUIRE(pgh.core_paragraph->maintainers.size() == 1); REQUIRE(pgh.core_paragraph->maintainers[0] == "m"); REQUIRE(pgh.core_paragraph->description.size() == 1); @@ -181,7 +180,7 @@ TEST_CASE ("SourceParagraph construct qualified dependencies", "[paragraph]") auto& pgh = **m_pgh.get(); REQUIRE(pgh.core_paragraph->name == "zlib"); - REQUIRE(pgh.core_paragraph->raw_version == "1.2.8"); + REQUIRE(pgh.core_paragraph->version == Version{"1.2.8", 0}); REQUIRE(pgh.core_paragraph->maintainers.empty()); REQUIRE(pgh.core_paragraph->description.empty()); REQUIRE(pgh.core_paragraph->dependencies.size() == 2); @@ -216,7 +215,25 @@ TEST_CASE ("BinaryParagraph construct minimum", "[paragraph]") }); REQUIRE(pgh.spec.name() == "zlib"); - REQUIRE(pgh.version == "1.2.8"); + REQUIRE(pgh.version == Version{"1.2.8", 0}); + REQUIRE(pgh.maintainers.empty()); + REQUIRE(pgh.description.empty()); + REQUIRE(pgh.spec.triplet().canonical_name() == "x86-windows"); + REQUIRE(pgh.dependencies.size() == 0); +} + +TEST_CASE ("BinaryParagraph construct minimum with port-version", "[paragraph]") +{ + auto pgh = test_make_binary_paragraph({ + {"Package", "zlib"}, + {"Version", "1.2.8"}, + {"Port-Version", "2"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + }); + + REQUIRE(pgh.spec.name() == "zlib"); + REQUIRE(pgh.version == Version{"1.2.8", 2}); REQUIRE(pgh.maintainers.empty()); REQUIRE(pgh.description.empty()); REQUIRE(pgh.spec.triplet().canonical_name() == "x86-windows"); @@ -236,7 +253,7 @@ TEST_CASE ("BinaryParagraph construct maximum", "[paragraph]") }); REQUIRE(pgh.spec.name() == "s"); - REQUIRE(pgh.version == "v"); + REQUIRE(pgh.version == Version{"v", 0}); REQUIRE(pgh.maintainers.size() == 1); REQUIRE(pgh.maintainers[0] == "m"); REQUIRE(pgh.description.size() == 1); diff --git a/src/vcpkg-test/spdx.cpp b/src/vcpkg-test/spdx.cpp index 7250181a05..c90bf2d085 100644 --- a/src/vcpkg-test/spdx.cpp +++ b/src/vcpkg-test/spdx.cpp @@ -17,9 +17,8 @@ TEST_CASE ("spdx maximum serialization", "[spdx]") cpgh.description = {"description"}; cpgh.homepage = "homepage"; cpgh.license = "MIT"; - cpgh.port_version = 5; - cpgh.raw_version = "1.0"; cpgh.version_scheme = VersionScheme::Relaxed; + cpgh.version = Version{"1.0", 5}; InstallPlanAction ipa(spec, scfl, "test_packages_root", RequestType::USER_REQUESTED, Test::X86_WINDOWS, {}, {}, {}); auto& abi = *(ipa.abi_info = AbiInfo{}).get(); @@ -171,9 +170,8 @@ TEST_CASE ("spdx minimum serialization", "[spdx]") auto& scf = *(scfl.source_control_file = std::make_unique()); auto& cpgh = *(scf.core_paragraph = std::make_unique()); cpgh.name = "zlib"; - cpgh.port_version = 0; - cpgh.raw_version = "1.0"; cpgh.version_scheme = VersionScheme::String; + cpgh.version = Version{"1.0", 0}; InstallPlanAction ipa(spec, scfl, "test_packages_root", RequestType::USER_REQUESTED, Test::X86_WINDOWS, {}, {}, {}); auto& abi = *(ipa.abi_info = AbiInfo{}).get(); @@ -299,9 +297,8 @@ TEST_CASE ("spdx concat resources", "[spdx]") auto& scf = *(scfl.source_control_file = std::make_unique()); auto& cpgh = *(scf.core_paragraph = std::make_unique()); cpgh.name = "zlib"; - cpgh.port_version = 0; - cpgh.raw_version = "1.0"; cpgh.version_scheme = VersionScheme::String; + cpgh.version = Version{"1.0", 0}; InstallPlanAction ipa(spec, scfl, "test_packages_root", RequestType::USER_REQUESTED, Test::X86_WINDOWS, {}, {}, {}); auto& abi = *(ipa.abi_info = AbiInfo{}).get(); diff --git a/src/vcpkg-test/update.cpp b/src/vcpkg-test/update.cpp index f2cd0f1cb1..59eb818a1c 100644 --- a/src/vcpkg-test/update.cpp +++ b/src/vcpkg-test/update.cpp @@ -15,7 +15,7 @@ TEST_CASE ("find outdated packages basic", "[update]") { std::vector> status_paragraphs; status_paragraphs.push_back(make_status_pgh("a")); - status_paragraphs.back()->package.version = "2"; + status_paragraphs.back()->package.version = Version{"2", 0}; StatusParagraphs status_db(std::move(status_paragraphs)); @@ -36,10 +36,10 @@ TEST_CASE ("find outdated packages features", "[update]") { std::vector> status_paragraphs; status_paragraphs.push_back(make_status_pgh("a")); - status_paragraphs.back()->package.version = "2"; + status_paragraphs.back()->package.version = Version{"2", 0}; status_paragraphs.push_back(make_status_feature_pgh("a", "b")); - status_paragraphs.back()->package.version = "2"; + status_paragraphs.back()->package.version = Version{"2", 0}; StatusParagraphs status_db(std::move(status_paragraphs)); @@ -60,10 +60,10 @@ TEST_CASE ("find outdated packages features 2", "[update]") { std::vector> status_paragraphs; status_paragraphs.push_back(make_status_pgh("a")); - status_paragraphs.back()->package.version = "2"; + status_paragraphs.back()->package.version = Version{"2", 0}; status_paragraphs.push_back(make_status_feature_pgh("a", "b")); - status_paragraphs.back()->package.version = "0"; + status_paragraphs.back()->package.version = Version{"0", 0}; status_paragraphs.back()->state = InstallState::NOT_INSTALLED; status_paragraphs.back()->want = Want::PURGE; @@ -86,7 +86,7 @@ TEST_CASE ("find outdated packages none", "[update]") { std::vector> status_paragraphs; status_paragraphs.push_back(make_status_pgh("a")); - status_paragraphs.back()->package.version = "2"; + status_paragraphs.back()->package.version = Version{"2", 0}; StatusParagraphs status_db(std::move(status_paragraphs)); diff --git a/src/vcpkg-test/versions.cpp b/src/vcpkg-test/versions.cpp index 6f41c1fe8f..d7b92c77aa 100644 --- a/src/vcpkg-test/versions.cpp +++ b/src/vcpkg-test/versions.cpp @@ -6,6 +6,19 @@ using namespace vcpkg; +TEST_CASE ("parse version", "[versions]") +{ + CHECK(Version::parse("").value_or_exit(VCPKG_LINE_INFO) == Version{}); + CHECK(Version::parse("#1").value_or_exit(VCPKG_LINE_INFO) == Version{"", 1}); + CHECK(Version::parse("a#1").value_or_exit(VCPKG_LINE_INFO) == Version{"a", 1}); + CHECK(Version::parse("example").value_or_exit(VCPKG_LINE_INFO) == Version{"example", 0}); + CHECK(Version::parse("example#0").value_or_exit(VCPKG_LINE_INFO) == Version{"example", 0}); + CHECK(Version::parse("example#1").value_or_exit(VCPKG_LINE_INFO) == Version{"example", 1}); + CHECK(!Version::parse("example#").has_value()); + CHECK(!Version::parse("example#-1").has_value()); + CHECK(!Version::parse("example#1234#hello").has_value()); +} + TEST_CASE ("sanitize", "[versions]") { std::string content; diff --git a/src/vcpkg/binarycaching.cpp b/src/vcpkg/binarycaching.cpp index f9ba7cfddf..0e1e9e191c 100644 --- a/src/vcpkg/binarycaching.cpp +++ b/src/vcpkg/binarycaching.cpp @@ -186,13 +186,13 @@ namespace return ret; } - NugetReference make_nugetref(const PackageSpec& spec, StringView raw_version, StringView abi_tag, StringView prefix) + NugetReference make_nugetref(const PackageSpec& spec, const Version& version, StringView abi_tag, StringView prefix) { - return {Strings::concat(prefix, spec.dir()), format_version_for_nugetref(raw_version, abi_tag)}; + return {Strings::concat(prefix, spec.dir()), format_version_for_nugetref(version.text, abi_tag)}; } NugetReference make_nugetref(const BinaryPackageReadInfo& info, StringView prefix) { - return make_nugetref(info.spec, info.raw_version, info.package_abi, prefix); + return make_nugetref(info.spec, info.version, info.package_abi, prefix); } void clean_prepare_dir(const Filesystem& fs, const Path& dir) @@ -1770,7 +1770,7 @@ namespace vcpkg [&](std::string& out, StringView key) { if (key == "version") { - out += info.raw_version; + out += info.version.text; } else if (key == "name") { @@ -2286,8 +2286,7 @@ namespace vcpkg BinaryPackageReadInfo::BinaryPackageReadInfo(const InstallPlanAction& action) : package_abi(action.package_abi().value_or_exit(VCPKG_LINE_INFO)) , spec(action.spec) - , raw_version(action.source_control_file_and_location.value_or_exit(VCPKG_LINE_INFO) - .source_control_file->core_paragraph->raw_version) + , version(action.version()) , package_dir(action.package_dir.value_or_exit(VCPKG_LINE_INFO)) { } @@ -2381,25 +2380,25 @@ ExpectedL vcpkg::parse_binary_provider_configs(const st return s; } -std::string vcpkg::format_version_for_nugetref(StringView version, StringView abi_tag) +std::string vcpkg::format_version_for_nugetref(StringView version_text, StringView abi_tag) { // this cannot use DotVersion::try_parse or DateVersion::try_parse, // since this is a subtly different algorithm // and ignores random extra stuff from the end ParsedExternalVersion parsed_version; - if (try_extract_external_date_version(parsed_version, version)) + if (try_extract_external_date_version(parsed_version, version_text)) { parsed_version.normalize(); return fmt::format( "{}.{}.{}-vcpkg{}", parsed_version.major, parsed_version.minor, parsed_version.patch, abi_tag); } - if (!version.empty() && version[0] == 'v') + if (!version_text.empty() && version_text[0] == 'v') { - version = version.substr(1); + version_text = version_text.substr(1); } - if (try_extract_external_dot_version(parsed_version, version)) + if (try_extract_external_dot_version(parsed_version, version_text)) { parsed_version.normalize(); return fmt::format( @@ -2416,7 +2415,7 @@ std::string vcpkg::generate_nuspec(const Path& package_dir, { auto& spec = action.spec; auto& scf = *action.source_control_file_and_location.value_or_exit(VCPKG_LINE_INFO).source_control_file; - auto& version = scf.core_paragraph->raw_version; + auto& version = scf.core_paragraph->version; const auto& abi_info = action.abi_info.value_or_exit(VCPKG_LINE_INFO); const auto& compiler_info = abi_info.compiler_info.value_or_exit(VCPKG_LINE_INFO); auto ref = make_nugetref(action, id_prefix); @@ -2570,9 +2569,6 @@ std::string vcpkg::generate_nuget_packages_config(const ActionPlan& plan, String NugetReference vcpkg::make_nugetref(const InstallPlanAction& action, StringView prefix) { - return ::make_nugetref(action.spec, - action.source_control_file_and_location.value_or_exit(VCPKG_LINE_INFO) - .source_control_file->core_paragraph->raw_version, - action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi, - prefix); + return ::make_nugetref( + action.spec, action.version(), action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi, prefix); } diff --git a/src/vcpkg/binaryparagraph.cpp b/src/vcpkg/binaryparagraph.cpp index b412fa9154..e12b0ba594 100644 --- a/src/vcpkg/binaryparagraph.cpp +++ b/src/vcpkg/binaryparagraph.cpp @@ -42,17 +42,15 @@ namespace vcpkg } // one or the other - this->version = parser.optional_field(Fields::VERSION); - this->feature = parser.optional_field(Fields::FEATURE); - + this->version.text = parser.optional_field(Fields::VERSION); auto pv_str = parser.optional_field(Fields::PORT_VERSION); - this->port_version = 0; + this->version.port_version = 0; if (!pv_str.empty()) { auto pv_opt = Strings::strto(pv_str); if (auto pv = pv_opt.get()) { - this->port_version = *pv; + this->version.port_version = *pv; } else { @@ -60,6 +58,7 @@ namespace vcpkg } } + this->feature = parser.optional_field(Fields::FEATURE); this->description = Strings::split(parser.optional_field(Fields::DESCRIPTION), '\n'); this->maintainers = Strings::split(parser.optional_field(Fields::MAINTAINER), '\n'); @@ -106,8 +105,7 @@ namespace vcpkg const std::string& abi_tag, std::vector deps) : spec(spgh.name, triplet) - , version(spgh.raw_version) - , port_version(spgh.port_version) + , version(spgh.version) , description(spgh.description) , maintainers(spgh.maintainers) , feature() @@ -123,7 +121,6 @@ namespace vcpkg std::vector deps) : spec(spec) , version() - , port_version() , description(fpgh.description) , maintainers() , feature(fpgh.name) @@ -175,14 +172,13 @@ namespace vcpkg std::string BinaryParagraph::fullstem() const { - return fmt::format("{}_{}_{}", this->spec.name(), this->version, this->spec.triplet()); + return fmt::format("{}_{}_{}", this->spec.name(), this->version.text, this->spec.triplet()); } bool operator==(const BinaryParagraph& lhs, const BinaryParagraph& rhs) { if (lhs.spec != rhs.spec) return false; if (lhs.version != rhs.version) return false; - if (lhs.port_version != rhs.port_version) return false; if (lhs.description != rhs.description) return false; if (lhs.maintainers != rhs.maintainers) return false; if (lhs.feature != rhs.feature) return false; @@ -202,7 +198,7 @@ namespace vcpkg return; } - out_str.append(name.begin(), name.end()).append(": ").append(field).push_back('\n'); + out_str.append(name.data(), name.size()).append(": ").append(field).push_back('\n'); } static void serialize_array(StringView name, const std::vector& array, @@ -214,7 +210,7 @@ namespace vcpkg return; } - out_str.append(name.begin(), name.end()).append(": "); + out_str.append(name.data(), name.size()).append(": "); out_str.append(Strings::join(joiner, array)); out_str.push_back('\n'); } @@ -243,13 +239,10 @@ namespace vcpkg serialize_string(Fields::PACKAGE, pgh.spec.name(), out_str); - serialize_string(Fields::VERSION, pgh.version, out_str); - if (pgh.port_version != 0) + serialize_string(Fields::VERSION, pgh.version.text, out_str); + if (pgh.version.port_version != 0) { - out_str.append(Fields::PORT_VERSION.data(), Fields::PORT_VERSION.size()) - .append(": ") - .append(std::to_string(pgh.port_version)) - .push_back('\n'); + fmt::format_to(std::back_inserter(out_str), "{}: {}\n", Fields::PORT_VERSION, pgh.version.port_version); } if (pgh.is_feature()) @@ -305,8 +298,8 @@ namespace vcpkg "\nspec: \"{}\"\nversion: \"{}\"\nport_version: {}\ndescription: [\"{}\"]\nmaintainers: [\"{}\"]\nfeature: " "\"{}\"\ndefault_features: [\"{}\"]\ndependencies: [\"{}\"]\nabi: \"{}\"", paragraph.spec.to_string(), - paragraph.version, - paragraph.port_version, + paragraph.version.text, + paragraph.version.port_version, Strings::join(join_str, paragraph.description), Strings::join(join_str, paragraph.maintainers), paragraph.feature, diff --git a/src/vcpkg/commands.add-version.cpp b/src/vcpkg/commands.add-version.cpp index 4e5af3c8db..857cec2033 100644 --- a/src/vcpkg/commands.add-version.cpp +++ b/src/vcpkg/commands.add-version.cpp @@ -39,8 +39,8 @@ namespace void insert_version_to_json_object(Json::Object& obj, const Version& version, StringLiteral version_field) { - obj.insert(version_field, Json::Value::string(version.text())); - obj.insert("port-version", Json::Value::integer(version.port_version())); + obj.insert(version_field, Json::Value::string(version.text)); + obj.insert("port-version", Json::Value::integer(version.port_version)); } void insert_schemed_version_to_json_object(Json::Object& obj, const SchemedVersion& version) @@ -71,7 +71,7 @@ namespace { if (version.scheme == VersionScheme::String) { - if (DateVersion::try_parse(version.version.text())) + if (DateVersion::try_parse(version.version.text)) { Checks::msg_exit_with_message(VCPKG_LINE_INFO, msgAddVersionSuggestNewVersionScheme, @@ -80,7 +80,7 @@ namespace msg::package_name = port_name, msg::option = OPTION_SKIP_VERSION_FORMAT_CHECK); } - if (DotVersion::try_parse_relaxed(version.version.text())) + if (DotVersion::try_parse_relaxed(version.version.text)) { Checks::msg_exit_with_message(VCPKG_LINE_INFO, msgAddVersionSuggestNewVersionScheme, diff --git a/src/vcpkg/commands.build.cpp b/src/vcpkg/commands.build.cpp index e96b1c0f4e..11bf5cba8f 100644 --- a/src/vcpkg/commands.build.cpp +++ b/src/vcpkg/commands.build.cpp @@ -760,7 +760,7 @@ namespace vcpkg {"_HOST_TRIPLET", action.host_triplet.canonical_name()}, {"FEATURES", Strings::join(";", action.feature_list)}, {"PORT", scf.core_paragraph->name}, - {"VERSION", scf.core_paragraph->raw_version}, + {"VERSION", scf.core_paragraph->version.text}, {"VCPKG_USE_HEAD_VERSION", Util::Enum::to_bool(action.build_options.use_head_version) ? "1" : "0"}, {"_VCPKG_DOWNLOAD_TOOL", to_string_view(action.build_options.download_tool)}, {"_VCPKG_EDITABLE", Util::Enum::to_bool(action.build_options.editable) ? "1" : "0"}, @@ -1276,7 +1276,7 @@ namespace vcpkg abi_info.relative_port_files = std::move(files); abi_info.relative_port_hashes = std::move(hashes); abi_info.heuristic_resources.push_back( - run_resource_heuristics(portfile_cmake_contents, scf->core_paragraph->raw_version)); + run_resource_heuristics(portfile_cmake_contents, scf->core_paragraph->version.text)); } void compute_all_abis(const VcpkgPaths& paths, @@ -1664,7 +1664,7 @@ namespace vcpkg if (!version.empty()) { sanitize_version_string(version); - build_info.detected_head_version = std::move(version); + build_info.detected_head_version = Version::parse(std::move(version)).value_or_exit(VCPKG_LINE_INFO); } std::unordered_map policies; diff --git a/src/vcpkg/commands.find.cpp b/src/vcpkg/commands.find.cpp index 89975f774b..7767ecf7cc 100644 --- a/src/vcpkg/commands.find.cpp +++ b/src/vcpkg/commands.find.cpp @@ -28,8 +28,8 @@ namespace auto& source_paragraph = scf->core_paragraph; Json::Object& library_obj = obj.insert(source_paragraph->name, Json::Object()); library_obj.insert("package_name", Json::Value::string(source_paragraph->name)); - library_obj.insert("version", Json::Value::string(source_paragraph->raw_version)); - library_obj.insert("port_version", Json::Value::integer(source_paragraph->port_version)); + library_obj.insert("version", Json::Value::string(source_paragraph->version.text)); + library_obj.insert("port_version", Json::Value::integer(source_paragraph->version.port_version)); Json::Array& desc = library_obj.insert("description", Json::Array()); for (const auto& line : source_paragraph->description) { @@ -41,7 +41,7 @@ namespace constexpr const int s_name_and_ver_columns = 41; void do_print(const SourceParagraph& source_paragraph, bool full_desc) { - auto full_version = Version(source_paragraph.raw_version, source_paragraph.port_version).to_string(); + auto full_version = source_paragraph.version.to_string(); if (full_desc) { msg::write_unlocalized_text_to_stdout(Color::none, diff --git a/src/vcpkg/commands.list.cpp b/src/vcpkg/commands.list.cpp index 51bc88e962..0c49f8ae4e 100644 --- a/src/vcpkg/commands.list.cpp +++ b/src/vcpkg/commands.list.cpp @@ -35,8 +35,9 @@ namespace Json::Object& library_obj = obj.insert(current_spec.to_string(), Json::Object()); library_obj.insert("package_name", Json::Value::string(current_spec.name())); library_obj.insert("triplet", Json::Value::string(current_spec.triplet().to_string())); - library_obj.insert("version", Json::Value::string(status_paragraph->package.version)); - library_obj.insert("port_version", Json::Value::integer(status_paragraph->package.port_version)); + library_obj.insert("version", Json::Value::string(status_paragraph->package.version.text)); + library_obj.insert("port_version", + Json::Value::integer(status_paragraph->package.version.port_version)); Json::Array& features_array = library_obj.insert("features", Json::Array()); if (status_paragraph->package.is_feature()) { @@ -55,7 +56,7 @@ namespace void do_print(const StatusParagraph& pgh, const bool full_desc) { - auto full_version = Version(pgh.package.version, pgh.package.port_version).to_string(); + auto full_version = pgh.package.version.to_string(); if (full_desc) { msg::write_unlocalized_text_to_stdout(Color::none, diff --git a/src/vcpkg/commands.portsdiff.cpp b/src/vcpkg/commands.portsdiff.cpp index bc888daf52..fa570f4f22 100644 --- a/src/vcpkg/commands.portsdiff.cpp +++ b/src/vcpkg/commands.portsdiff.cpp @@ -56,12 +56,9 @@ namespace const auto ports_at_commit = Paragraphs::load_overlay_ports(fs, temp_checkout_path / ports_dir_name); fs.remove_all(temp_checkout_path, VCPKG_LINE_INFO); - std::vector results; - for (auto&& port : ports_at_commit) - { - const auto& core_pgh = *port.source_control_file->core_paragraph; - results.emplace_back(VersionSpec{core_pgh.name, Version{core_pgh.raw_version, core_pgh.port_version}}); - } + auto results = Util::fmap(ports_at_commit, [](const SourceControlFileAndLocation& scfl) { + return scfl.source_control_file->to_version_spec(); + }); Util::sort(results, [](const VersionSpec& lhs, const VersionSpec& rhs) { return lhs.port_name < rhs.port_name; }); diff --git a/src/vcpkg/commands.update.cpp b/src/vcpkg/commands.update.cpp index 1c6f82b7b8..df2be61b59 100644 --- a/src/vcpkg/commands.update.cpp +++ b/src/vcpkg/commands.update.cpp @@ -29,13 +29,10 @@ namespace vcpkg auto maybe_scfl = provider.get_control_file(pgh->package.spec.name()); if (auto p_scfl = maybe_scfl.get()) { - const auto& latest_pgh = *p_scfl->source_control_file->core_paragraph; - auto latest_version = Version(latest_pgh.raw_version, latest_pgh.port_version); - auto installed_version = Version(pgh->package.version, pgh->package.port_version); - if (latest_version != installed_version) + const auto& latest_version = p_scfl->to_version(); + if (latest_version != pgh->package.version) { - output.push_back( - {pgh->package.spec, VersionDiff(std::move(installed_version), std::move(latest_version))}); + output.push_back({pgh->package.spec, VersionDiff(pgh->package.version, latest_version)}); } } else diff --git a/src/vcpkg/commands.upgrade.cpp b/src/vcpkg/commands.upgrade.cpp index c2b2b45b11..539b67bda3 100644 --- a/src/vcpkg/commands.upgrade.cpp +++ b/src/vcpkg/commands.upgrade.cpp @@ -136,11 +136,7 @@ namespace vcpkg if (skip_version_check) continue; const auto& control_file = maybe_control_file.value_or_exit(VCPKG_LINE_INFO); - const auto& control_paragraph = *control_file.source_control_file->core_paragraph; - auto control_version = Version(control_paragraph.raw_version, control_paragraph.port_version); - const auto& installed_paragraph = (*installed_status)->package; - auto installed_version = Version(installed_paragraph.version, installed_paragraph.port_version); - if (control_version == installed_version) + if (control_file.to_version() == (*installed_status)->package.version) { up_to_date.push_back(spec); } diff --git a/src/vcpkg/dependencies.cpp b/src/vcpkg/dependencies.cpp index eb5a289008..ff1faa328d 100644 --- a/src/vcpkg/dependencies.cpp +++ b/src/vcpkg/dependencies.cpp @@ -314,7 +314,7 @@ namespace vcpkg { if (auto p_installed = m_installed.get()) { - return p_installed->ipv.core->package.get_version(); + return p_installed->ipv.core->package.version; } else if (auto p_scfl = m_scfl.get()) { diff --git a/src/vcpkg/export.chocolatey.cpp b/src/vcpkg/export.chocolatey.cpp index 976f918462..f305070951 100644 --- a/src/vcpkg/export.chocolatey.cpp +++ b/src/vcpkg/export.chocolatey.cpp @@ -178,7 +178,7 @@ if (Test-Path $installedDir) } const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO); - auto norm_version = binary_paragraph.version; + auto norm_version = binary_paragraph.version.to_string(); // normalize the version string to be separated by dots to be compliant with Nuspec. Strings::inplace_replace_all(norm_version, '-', '.'); diff --git a/src/vcpkg/export.prefab.cpp b/src/vcpkg/export.prefab.cpp index c202b5a176..c80b1a881a 100644 --- a/src/vcpkg/export.prefab.cpp +++ b/src/vcpkg/export.prefab.cpp @@ -398,7 +398,7 @@ namespace vcpkg::Prefab const auto per_package_dir_path = paths.prefab / name; const auto& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO); - const std::string norm_version = binary_paragraph.version; + const std::string norm_version = binary_paragraph.version.to_string(); version_map[name] = norm_version; diff --git a/src/vcpkg/portfileprovider.cpp b/src/vcpkg/portfileprovider.cpp index 321c5ea8f0..fbd788e7fa 100644 --- a/src/vcpkg/portfileprovider.cpp +++ b/src/vcpkg/portfileprovider.cpp @@ -246,10 +246,10 @@ namespace vcpkg auto all_ports = Paragraphs::load_all_registry_ports(m_fs, m_registry_set); for (auto&& scfl : all_ports) { - auto port_name = scfl.source_control_file->core_paragraph->name; - auto version = scfl.source_control_file->core_paragraph->to_version(); + // make version spec before moving from scfl + auto version_spec = scfl.source_control_file->to_version_spec(); auto it = m_control_cache - .emplace(VersionSpec{port_name, version}, + .emplace(std::move(version_spec), std::make_unique(std::move(scfl))) .first; out.emplace(it->first.port_name, it->second.value_or_exit(VCPKG_LINE_INFO).get()); diff --git a/src/vcpkg/sourceparagraph.cpp b/src/vcpkg/sourceparagraph.cpp index ff8fe343f7..a3f6b2b527 100644 --- a/src/vcpkg/sourceparagraph.cpp +++ b/src/vcpkg/sourceparagraph.cpp @@ -23,8 +23,7 @@ namespace vcpkg bool operator==(const DependencyConstraint& lhs, const DependencyConstraint& rhs) { if (lhs.type != rhs.type) return false; - if (lhs.value != rhs.value) return false; - return lhs.port_version == rhs.port_version; + return lhs.version == rhs.version; } Optional DependencyConstraint::try_get_minimum_version() const @@ -34,10 +33,7 @@ namespace vcpkg return nullopt; } - return Version{ - value, - port_version, - }; + return version; } bool Dependency::has_platform_expressions() const @@ -109,9 +105,8 @@ namespace vcpkg bool operator==(const SourceParagraph& lhs, const SourceParagraph& rhs) { if (lhs.name != rhs.name) return false; - if (lhs.raw_version != rhs.raw_version) return false; if (lhs.version_scheme != rhs.version_scheme) return false; - if (lhs.port_version != rhs.port_version) return false; + if (lhs.version != rhs.version) return false; if (!paragraph_equal(lhs.description, rhs.description)) return false; if (!paragraph_equal(lhs.maintainers, rhs.maintainers)) return false; if (lhs.homepage != rhs.homepage) return false; @@ -325,7 +320,7 @@ namespace vcpkg auto spgh = std::make_unique(); parser.required_field(SourceParagraphFields::NAME, spgh->name); - parser.required_field(SourceParagraphFields::VERSION, spgh->raw_version); + parser.required_field(SourceParagraphFields::VERSION, spgh->version.text); auto pv_str = parser.optional_field(SourceParagraphFields::PORT_VERSION); if (!pv_str.empty()) @@ -333,7 +328,7 @@ namespace vcpkg auto pv_opt = Strings::strto(pv_str); if (auto pv = pv_opt.get()) { - spgh->port_version = *pv; + spgh->version.port_version = *pv; } else { @@ -692,27 +687,21 @@ namespace vcpkg r.optional_object_field(obj, DEFAULT_FEATURES, dep.default_features, Json::BooleanDeserializer::instance); r.optional_object_field(obj, HOST, dep.host, Json::BooleanDeserializer::instance); r.optional_object_field(obj, PLATFORM, dep.platform, PlatformExprDeserializer::instance); + + std::string raw_version_ge_text; auto has_ge_constraint = r.optional_object_field( - obj, VERSION_GE, dep.constraint.value, VersionConstraintStringDeserializer::instance); + obj, VERSION_GE, raw_version_ge_text, VersionConstraintStringDeserializer::instance); if (has_ge_constraint) { dep.constraint.type = VersionConstraintKind::Minimum; - const auto& constraint_value = dep.constraint.value; - auto h = constraint_value.find('#'); - if (h != std::string::npos) + auto maybe_version = Version::parse(raw_version_ge_text); + if (auto version = maybe_version.get()) { - auto opt = Strings::strto(ZStringView{constraint_value}.substr(h + 1)); - auto v = opt.get(); - if (v && *v >= 0) - { - dep.constraint.port_version = *v; - } - else - { - r.add_generic_error(type_name(), - msg::format(msgVersionConstraintPortVersionMustBePositiveInteger)); - } - dep.constraint.value.erase(h); + dep.constraint.version = std::move(*version); + } + else + { + r.add_generic_error(type_name(), msg::format(msgVersionConstraintPortVersionMustBePositiveInteger)); } } @@ -1319,9 +1308,8 @@ namespace vcpkg auto maybe_schemed_version = visit_optional_schemed_deserializer(type_name(), r, obj, false); if (auto p = maybe_schemed_version.get()) { - spgh.raw_version = p->version.text(); spgh.version_scheme = p->scheme; - spgh.port_version = p->version.port_version(); + spgh.version = p->version; } else { @@ -1348,9 +1336,8 @@ namespace vcpkg r.required_object_field(type_name(), obj, NAME, spgh.name, Json::PackageNameDeserializer::instance); auto schemed_version = visit_required_schemed_deserializer(type_name(), r, obj, false); - spgh.raw_version = schemed_version.version.text(); spgh.version_scheme = schemed_version.scheme; - spgh.port_version = schemed_version.version.port_version(); + spgh.version = schemed_version.version; return visit_object_common(obj, spgh, r, control_file); } @@ -1789,12 +1776,7 @@ namespace vcpkg serialize_optional_string(dep_obj, DependencyDeserializer::PLATFORM, to_string(dep.platform)); if (dep.constraint.type == VersionConstraintKind::Minimum) { - auto s = dep.constraint.value; - if (dep.constraint.port_version != 0) - { - fmt::format_to(std::back_inserter(s), "#{}", dep.constraint.port_version); - } - dep_obj.insert(DependencyDeserializer::VERSION_GE, std::move(s)); + dep_obj.insert(DependencyDeserializer::VERSION_GE, dep.constraint.version.to_string()); } } }; @@ -1807,8 +1789,7 @@ namespace vcpkg } dep_obj.insert(DependencyOverrideDeserializer::NAME, Json::Value::string(dep.name)); - - serialize_schemed_version(dep_obj, dep.scheme, dep.version.text(), dep.version.port_version()); + serialize_schemed_version(dep_obj, dep.scheme, dep.version); }; auto serialize_license = @@ -1845,10 +1826,7 @@ namespace vcpkg if (scf.core_paragraph->version_scheme != VersionScheme::Missing) { - serialize_schemed_version(obj, - scf.core_paragraph->version_scheme, - scf.core_paragraph->raw_version, - scf.core_paragraph->port_version); + serialize_schemed_version(obj, scf.core_paragraph->version_scheme, scf.core_paragraph->version); } serialize_paragraph(obj, ManifestDeserializer::MAINTAINERS, scf.core_paragraph->maintainers); diff --git a/src/vcpkg/spdx.cpp b/src/vcpkg/spdx.cpp index 374e36a1f6..69bfc29323 100644 --- a/src/vcpkg/spdx.cpp +++ b/src/vcpkg/spdx.cpp @@ -81,7 +81,7 @@ static Json::Object make_resource( return obj; } -Json::Value vcpkg::run_resource_heuristics(StringView contents, StringView portRawVersion) +Json::Value vcpkg::run_resource_heuristics(StringView contents, StringView version_text) { // These are a sequence of heuristics to enable proof-of-concept extraction of remote resources for SPDX SBOM // inclusion @@ -92,7 +92,7 @@ Json::Value vcpkg::run_resource_heuristics(StringView contents, StringView portR if (!github.empty()) { auto repo = extract_cmake_invocation_argument(github, "REPO"); - auto ref = fix_ref_version(extract_cmake_invocation_argument(github, "REF"), portRawVersion); + auto ref = fix_ref_version(extract_cmake_invocation_argument(github, "REF"), version_text); auto sha = extract_cmake_invocation_argument(github, "SHA512"); packages.push_back(make_resource(fmt::format("SPDXRef-resource-{}", ++n), @@ -105,7 +105,7 @@ Json::Value vcpkg::run_resource_heuristics(StringView contents, StringView portR if (!git.empty()) { auto url = extract_cmake_invocation_argument(github, "URL"); - auto ref = fix_ref_version(extract_cmake_invocation_argument(github, "REF"), portRawVersion); + auto ref = fix_ref_version(extract_cmake_invocation_argument(github, "REF"), version_text); packages.push_back(make_resource( fmt::format("SPDXRef-resource-{}", ++n), url.to_string(), fmt::format("git+{}@{}", url, ref), {}, {})); } @@ -122,7 +122,7 @@ Json::Value vcpkg::run_resource_heuristics(StringView contents, StringView portR if (!sfg.empty()) { auto repo = extract_cmake_invocation_argument(sfg, "REPO"); - auto ref = fix_ref_version(extract_cmake_invocation_argument(sfg, "REF"), portRawVersion); + auto ref = fix_ref_version(extract_cmake_invocation_argument(sfg, "REF"), version_text); auto filename = extract_cmake_invocation_argument(sfg, "FILENAME"); auto sha = extract_cmake_invocation_argument(sfg, "SHA512"); auto url = Strings::concat("https://sourceforge.net/projects/", repo, "/files/", ref, '/', filename); @@ -152,7 +152,7 @@ std::string vcpkg::create_spdx_sbom(const InstallPlanAction& action, doc.insert("dataLicense", "CC0-1.0"); doc.insert("SPDXID", "SPDXRef-DOCUMENT"); doc.insert("documentNamespace", std::move(document_namespace)); - doc.insert("name", Strings::concat(action.spec.to_string(), '@', cpgh.to_version().to_string(), ' ', abi)); + doc.insert("name", Strings::concat(action.spec.to_string(), '@', cpgh.version.to_string(), ' ', abi)); { auto& cinfo = doc.insert("creationInfo", Json::Object()); auto& creators = cinfo.insert("creators", Json::Array()); @@ -166,7 +166,7 @@ std::string vcpkg::create_spdx_sbom(const InstallPlanAction& action, auto& obj = packages.push_back(Json::Object()); obj.insert("name", action.spec.name()); obj.insert("SPDXID", "SPDXRef-port"); - obj.insert("versionInfo", cpgh.to_version().to_string()); + obj.insert("versionInfo", cpgh.version.to_string()); obj.insert("downloadLocation", scfl.registry_location.empty() ? noassert : scfl.registry_location); if (!cpgh.homepage.empty()) { diff --git a/src/vcpkg/statusparagraph.cpp b/src/vcpkg/statusparagraph.cpp index a739b58b07..b961a3c18f 100644 --- a/src/vcpkg/statusparagraph.cpp +++ b/src/vcpkg/statusparagraph.cpp @@ -106,7 +106,8 @@ namespace vcpkg } return ret; } - Version InstalledPackageView::version() const { return {core->package.version, core->package.port_version}; } + + const Version& InstalledPackageView::version() const { return core->package.version; } std::vector InstalledPackageView::dependencies() const { diff --git a/src/vcpkg/statusparagraphs.cpp b/src/vcpkg/statusparagraphs.cpp index 3c110c58d6..a3eb66b527 100644 --- a/src/vcpkg/statusparagraphs.cpp +++ b/src/vcpkg/statusparagraphs.cpp @@ -156,8 +156,8 @@ namespace vcpkg const ReadOnlyFilesystem& fs) { Json::Object iobj; - iobj.insert("version-string", Json::Value::string(ipv.core->package.version)); - iobj.insert("port-version", Json::Value::integer(ipv.core->package.port_version)); + iobj.insert("version-string", Json::Value::string(ipv.core->package.version.text)); + iobj.insert("port-version", Json::Value::integer(ipv.core->package.version.port_version)); iobj.insert("triplet", Json::Value::string(ipv.spec().triplet().to_string())); iobj.insert("abi", Json::Value::string(ipv.core->package.abi)); Json::Array deps; diff --git a/src/vcpkg/versiondeserializers.cpp b/src/vcpkg/versiondeserializers.cpp index 9ab1437eb9..8d976f8906 100644 --- a/src/vcpkg/versiondeserializers.cpp +++ b/src/vcpkg/versiondeserializers.cpp @@ -193,7 +193,7 @@ namespace vcpkg return t; } - void serialize_schemed_version(Json::Object& out_obj, VersionScheme scheme, StringView version, int port_version) + void serialize_schemed_version(Json::Object& out_obj, VersionScheme scheme, const Version& version) { auto version_field = [](VersionScheme version_scheme) { switch (version_scheme) @@ -206,11 +206,11 @@ namespace vcpkg } }; - out_obj.insert(version_field(scheme), Json::Value::string(version)); + out_obj.insert(version_field(scheme), Json::Value::string(version.text)); - if (port_version != 0) + if (version.port_version != 0) { - out_obj.insert(PORT_VERSION, Json::Value::integer(port_version)); + out_obj.insert(PORT_VERSION, Json::Value::integer(version.port_version)); } } diff --git a/src/vcpkg/versions.cpp b/src/vcpkg/versions.cpp index 0b0918b578..25c8a8b9d2 100644 --- a/src/vcpkg/versions.cpp +++ b/src/vcpkg/versions.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -8,9 +9,14 @@ namespace vcpkg { - Version::Version() noexcept : m_text("0.0.0"), m_port_version(0) { } - Version::Version(std::string&& value, int port_version) : m_text(std::move(value)), m_port_version(port_version) { } - Version::Version(const std::string& value, int port_version) : m_text(value), m_port_version(port_version) { } + Version::Version() noexcept : text(), port_version(0) { } + Version::Version(std::string&& value, int port_version) noexcept + : text(std::move(value)), port_version(port_version) + { + } + Version::Version(StringView value, int port_version) : text(value.data(), value.size()), port_version(port_version) + { + } std::string Version::to_string() const { @@ -21,22 +27,45 @@ namespace vcpkg void Version::to_string(std::string& out) const { - out.append(m_text); - if (m_port_version) + out.append(text); + if (port_version) + { + fmt::format_to(std::back_inserter(out), "#{}", port_version); + } + } + + Optional Version::parse(StringView content) + { + const auto hash = std::find(content.begin(), content.end(), '#'); + auto port_version_text_start = hash; + int port_version = 0; + if (port_version_text_start != content.end()) { - fmt::format_to(std::back_inserter(out), "#{}", m_port_version); + ++port_version_text_start; + auto maybe_parsed = Strings::strto(StringView(port_version_text_start, content.end())); + auto parsed = maybe_parsed.get(); + if (parsed && *parsed >= 0) + { + port_version = *parsed; + } + else + { + return nullopt; + } } + + return Version{StringView{content.begin(), hash}, port_version}; } bool operator==(const Version& left, const Version& right) { - return left.m_port_version == right.m_port_version && left.m_text == right.m_text; + return left.text == right.text && left.port_version == right.port_version; } bool operator!=(const Version& left, const Version& right) { return !(left == right); } bool VersionMapLess::operator()(const Version& left, const Version& right) const { - auto cmp = left.m_text.compare(right.m_text); + auto cmp = left.text.compare(right.text); if (cmp < 0) { return true; @@ -46,7 +75,7 @@ namespace vcpkg return false; } - return left.m_port_version < right.m_port_version; + return left.port_version < right.port_version; } VersionDiff::VersionDiff() noexcept : left(), right() { } @@ -378,20 +407,20 @@ namespace vcpkg { if (sa == VersionScheme::String && sb == VersionScheme::String) { - return a.text() == b.text() ? VerComp::eq : VerComp::unk; + return a.text == b.text ? VerComp::eq : VerComp::unk; } if (sa == VersionScheme::Date && sb == VersionScheme::Date) { - return compare(DateVersion::try_parse(a.text()).value_or_exit(VCPKG_LINE_INFO), - DateVersion::try_parse(b.text()).value_or_exit(VCPKG_LINE_INFO)); + return compare(DateVersion::try_parse(a.text).value_or_exit(VCPKG_LINE_INFO), + DateVersion::try_parse(b.text).value_or_exit(VCPKG_LINE_INFO)); } if ((sa == VersionScheme::Semver || sa == VersionScheme::Relaxed) && (sb == VersionScheme::Semver || sb == VersionScheme::Relaxed)) { - return compare(DotVersion::try_parse(a.text(), sa).value_or_exit(VCPKG_LINE_INFO), - DotVersion::try_parse(b.text(), sb).value_or_exit(VCPKG_LINE_INFO)); + return compare(DotVersion::try_parse(a.text, sa).value_or_exit(VCPKG_LINE_INFO), + DotVersion::try_parse(b.text, sb).value_or_exit(VCPKG_LINE_INFO)); } return VerComp::unk; @@ -414,7 +443,7 @@ namespace vcpkg VerComp compare_versions(VersionScheme sa, const Version& a, VersionScheme sb, const Version& b) { - return portversion_vercomp(compare_version_texts(sa, a, sb, b), a.port_version(), b.port_version()); + return portversion_vercomp(compare_version_texts(sa, a, sb, b), a.port_version, b.port_version); } VerComp compare(const DateVersion& a, const DateVersion& b) @@ -429,27 +458,27 @@ namespace vcpkg VerComp compare_any(const Version& a, const Version& b) { - if (a.text() == b.text()) + if (a.text == b.text) { - return integer_vercomp(a.port_version(), b.port_version()); + return integer_vercomp(a.port_version, b.port_version); } - auto date_a = DateVersion::try_parse(a.text()); + auto date_a = DateVersion::try_parse(a.text); if (auto p_date_a = date_a.get()) { - auto date_b = DateVersion::try_parse(b.text()); + auto date_b = DateVersion::try_parse(b.text); if (auto p_date_b = date_b.get()) { - return portversion_vercomp(compare(*p_date_a, *p_date_b), a.port_version(), b.port_version()); + return portversion_vercomp(compare(*p_date_a, *p_date_b), a.port_version, b.port_version); } } - auto dot_a = DotVersion::try_parse_relaxed(a.text()); + auto dot_a = DotVersion::try_parse_relaxed(a.text); if (auto p_dot_a = dot_a.get()) { - auto dot_b = DotVersion::try_parse_relaxed(b.text()); + auto dot_b = DotVersion::try_parse_relaxed(b.text); if (auto p_dot_b = dot_b.get()) { - return portversion_vercomp(compare(*p_dot_a, *p_dot_b), a.port_version(), b.port_version()); + return portversion_vercomp(compare(*p_dot_a, *p_dot_b), a.port_version, b.port_version); } } return VerComp::unk;