aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbpkg/manifest.cxx32
-rw-r--r--libbpkg/manifest.hxx2
-rw-r--r--tests/package-version/driver.cxx64
3 files changed, 69 insertions, 29 deletions
diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx
index f155c5a..0fa2a4c 100644
--- a/libbpkg/manifest.cxx
+++ b/libbpkg/manifest.cxx
@@ -238,8 +238,18 @@ namespace bpkg
size_t len_ = 0; // Length without the trailing digit-only zero components.
};
+ // Return zero for versions having the '0[+<revision>]' form (stubs) and one
+ // otherwise. Used for both version and version::data_type types.
+ //
+ template <typename T>
+ inline static uint16_t
+ default_epoch (const T& v)
+ {
+ return v.canonical_upstream.empty () && !v.release ? 0 : 1;
+ }
+
version::data_type::
- data_type (const char* v, parse pr): epoch (0), revision (0)
+ data_type (const char* v, parse pr): revision (0)
{
// Otherwise compiler gets confused with string() member.
//
@@ -255,6 +265,8 @@ namespace bpkg
assert (v != nullptr);
+ optional<uint16_t> ep;
+
auto bad_arg = [](const string& d) {throw invalid_argument (d);};
auto uint16 = [&bad_arg](const string& s, const char* what) -> uint16_t
@@ -331,7 +343,7 @@ namespace bpkg
if (lnn >= cb) // Contains non-digits.
bad_arg ("epoch should be 2-byte unsigned integer");
- epoch = uint16 (string (cb, p), "epoch");
+ ep = uint16 (string (cb, p), "epoch");
}
else
canon_part->add (cb, p, lnn < cb);
@@ -467,11 +479,17 @@ namespace bpkg
}
}
- if (pr == parse::full && epoch == 0 && canonical_upstream.empty () &&
- canonical_release.empty ())
+ if (pr == parse::full)
{
- assert (revision == 0); // Can't happen if through all previous checks.
- bad_arg ("empty version");
+ epoch = ep ? *ep : default_epoch (*this);
+
+ if (epoch == 0 &&
+ canonical_upstream.empty () &&
+ canonical_release.empty ())
+ {
+ assert (revision == 0); // Can't happen if through all previous checks.
+ bad_arg ("empty version");
+ }
}
}
@@ -502,7 +520,7 @@ namespace bpkg
if (empty ())
throw logic_error ("empty version");
- std::string v (epoch != 0
+ std::string v (epoch != default_epoch (*this)
? '+' + to_string (epoch) + '-' + upstream
: upstream);
diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx
index 5e7a748..fc6c332 100644
--- a/libbpkg/manifest.hxx
+++ b/libbpkg/manifest.hxx
@@ -50,7 +50,7 @@ namespace bpkg
const std::string canonical_release;
// Create a special empty version. It is less than any other valid
- // version (and is conceptually equivalent to 0-).
+ // version (and is conceptually equivalent to +0-0-).
//
version (): epoch (0), release (""), revision (0), iteration (0) {}
diff --git a/tests/package-version/driver.cxx b/tests/package-version/driver.cxx
index 70ea892..5cdf4f9 100644
--- a/tests/package-version/driver.cxx
+++ b/tests/package-version/driver.cxx
@@ -114,8 +114,8 @@ namespace bpkg
assert (bad_version ("a.b-+1")); // Revision for empty release.
assert (bad_version ("0.0-+3")); // Same.
assert (bad_version ("1.2.3-~")); // Invalid release.
- assert (bad_version ("0-")); // Illegal version.
- assert (bad_version ("0.0-")); // Same.
+ assert (bad_version ("+0-0-")); // Empty version.
+ assert (bad_version ("+0-0.0-")); // Same.
assert (bad_version ("1.2.3+1#1")); // Unexpected iteration.
assert (bad_version ("a.39485739122323231.3")); // Too long component.
@@ -151,7 +151,15 @@ namespace bpkg
{
version v ("+1-0.0-");
assert (!v.empty ());
- assert (v.string () == "+1-0.0-");
+ assert (v.string () == "0.0-");
+ assert (v.canonical_upstream.empty ());
+ assert (v.canonical_release.empty ());
+ assert (test_constructor (v));
+ }
+ {
+ version v ("0-");
+ assert (!v.empty ());
+ assert (v.string () == "0-");
assert (v.canonical_upstream.empty ());
assert (v.canonical_release.empty ());
assert (test_constructor (v));
@@ -181,6 +189,12 @@ namespace bpkg
assert (test_constructor (v));
}
{
+ version v ("0+1");
+ assert (v.string () == "0+1");
+ assert (v.canonical_upstream.empty ());
+ assert (test_constructor (v));
+ }
+ {
version v ("0.0.0");
assert (v.string () == "0.0.0");
assert (v.canonical_upstream.empty ());
@@ -217,8 +231,14 @@ namespace bpkg
assert (test_constructor (v));
}
{
+ version v ("+0-0+1");
+ assert (v.string () == "0+1");
+ assert (v.canonical_upstream.empty ());
+ assert (test_constructor (v));
+ }
+ {
version v ("+0-A+1");
- assert (v.string () == "A+1");
+ assert (v.string () == "+0-A+1");
assert (v.canonical_upstream == "a");
assert (test_constructor (v));
}
@@ -258,7 +278,7 @@ namespace bpkg
}
{
version v ("+1-A-1.2.3B.00+0");
- assert (v.string () == "+1-A-1.2.3B.00");
+ assert (v.string () == "A-1.2.3B.00");
assert (v.release && *v.release == "1.2.3B.00");
assert (v.canonical_release == "0000000000000001.0000000000000002.3b");
assert (test_constructor (v));
@@ -271,43 +291,46 @@ namespace bpkg
assert (test_constructor (v));
}
{
- version v (1, "1", nullopt, 2, 0);
- assert (v.string () == "+1-1+2");
+ version v (2, "1", nullopt, 2, 0);
+ assert (v.string () == "+2-1+2");
assert (!v.release);
assert (v.canonical_release == "~");
assert (test_constructor (v));
}
{
- version v (1, "1", string (), 0, 0);
- assert (v.string () == "+1-1-");
+ version v (2, "1", string (), 0, 0);
+ assert (v.string () == "+2-1-");
assert (v.release && v.release->empty ());
assert (v.canonical_release.empty ());
assert (test_constructor (v));
}
{
- version v (1, "2.0", nullopt, 3, 4);
- assert (v.string (false, false) == "+1-2.0+3#4");
- assert (v.string (true, true) == "+1-2.0");
- assert (v.string (true, false) == "+1-2.0");
- assert (v.string (false, true) == "+1-2.0+3");
+ version v (3, "2.0", nullopt, 3, 4);
+ assert (v.string (false, false) == "+3-2.0+3#4");
+ assert (v.string (true, true) == "+3-2.0");
+ assert (v.string (true, false) == "+3-2.0");
+ assert (v.string (false, true) == "+3-2.0+3");
- assert (version (1, "2.0", nullopt, 0, 3).string () == "+1-2.0#3");
- assert (version (1, "2.0", nullopt, 3, 0).string () == "+1-2.0+3");
+ assert (version (3, "2.0", nullopt, 0, 1).string () == "+3-2.0#1");
+ assert (version (3, "2.0", nullopt, 1, 0).string () == "+3-2.0+1");
}
+ assert (version ("+1-0-") == version ("0-")); // Not a stub.
+ assert (version ("00+1") == version ("0+1")); // Stub.
+ assert (version ("0.0.0") == version ("0")); // Stub.
assert (version ("a") == version ("a"));
assert (version ("a") < version ("b"));
assert (version ("a") < version ("aa"));
assert (version ("a.a") < version ("aaa"));
assert (version ("a") < version ("a.a"));
- assert (version ("ab") == version ("ab"));
+ assert (version ("+1-ab") == version ("ab"));
assert (version ("ac") < version ("bc"));
assert (version ("ab+0") == version ("ab"));
assert (version ("a.1+1") > version ("a.1"));
- assert (version ("+0-ab") == version ("ab"));
+ assert (version ("ab") == version ("ab"));
assert (version ("1.2") > version ("1.1"));
- assert (version ("+1-1.0") > version ("2.0"));
- assert (version ("+0-ab+1") == version ("ab+1"));
+ assert (version ("1.0") > version ("+0-2.0"));
+ assert (version ("+1-ab+1") == version ("ab+1"));
assert (version ("+0-ab+1").compare (version ("+0-ab+2"), true) == 0);
assert (version ("12") > version ("2"));
assert (version ("2") < version ("12"));
@@ -322,7 +345,6 @@ namespace bpkg
assert (version ("1.Alpha.1") == version ("1.ALPHA.1"));
assert (version ("a.1") < version ("ab1"));
assert (version ("a.2") < version ("a.1b"));
- assert (version ("0.0.0") == version ("0"));
assert (version ("1.0.0") == version ("01"));
assert (version ("0.1.00") == version ("00.1"));
assert (version ("0.0a.00") == version ("00.0a"));