aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2019-08-30 20:55:55 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2019-09-05 16:33:50 +0300
commita6bf026d143b559ac0358dfd4b89f317901fd02e (patch)
tree77d47f219e97c222a641749af0ad1d3f0e366b53
parentad801af7a975a5400f798c77d3d9cdaf3ed5121a (diff)
Make version revision optional
-rw-r--r--libbpkg/manifest.cxx62
-rw-r--r--libbpkg/manifest.hxx47
-rw-r--r--tests/manifest/testscript1166
-rw-r--r--tests/package-version/driver.cxx23
4 files changed, 678 insertions, 620 deletions
diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx
index bba616f..19f24ab 100644
--- a/libbpkg/manifest.cxx
+++ b/libbpkg/manifest.cxx
@@ -162,7 +162,7 @@ namespace bpkg
version (uint16_t e,
std::string u,
optional<std::string> l,
- uint16_t r,
+ optional<uint16_t> r,
uint32_t i)
: epoch (e),
upstream (move (u)),
@@ -170,11 +170,14 @@ namespace bpkg
revision (r),
iteration (i),
canonical_upstream (
- data_type (upstream.c_str (), data_type::parse::upstream).
+ data_type (upstream.c_str (),
+ data_type::parse::upstream,
+ false /* fold_zero_revision */).
canonical_upstream),
canonical_release (
data_type (release ? release->c_str () : nullptr,
- data_type::parse::release).
+ data_type::parse::release,
+ false /* fold_zero_revision */).
canonical_release)
{
// Check members constrains.
@@ -187,7 +190,7 @@ namespace bpkg
if (!release || !release->empty ())
throw invalid_argument ("not-empty release for empty version");
- if (revision != 0)
+ if (revision)
throw invalid_argument ("revision for empty version");
if (iteration != 0)
@@ -196,7 +199,7 @@ namespace bpkg
// Empty release signifies the earliest possible release. Revision and/or
// iteration are meaningless in such a context.
//
- else if (release && release->empty () && (revision != 0 || iteration != 0))
+ else if (release && release->empty () && (revision || iteration != 0))
throw invalid_argument ("revision for earliest possible release");
}
@@ -251,8 +254,11 @@ namespace bpkg
}
version::data_type::
- data_type (const char* v, parse pr): revision (0)
+ data_type (const char* v, parse pr, bool fold_zero_rev)
{
+ if (fold_zero_rev)
+ assert (pr == parse::full);
+
// Otherwise compiler gets confused with string() member.
//
using std::string;
@@ -418,7 +424,10 @@ namespace bpkg
if (lnn >= cb) // Contains non-digits.
bad_arg ("revision should be 2-byte unsigned integer");
- revision = uint16 (cb, "revision");
+ std::uint16_t rev (uint16 (cb, "revision"));
+
+ if (rev != 0 || !fold_zero_rev)
+ revision = rev;
}
else if (cb != p)
{
@@ -489,7 +498,7 @@ namespace bpkg
canonical_upstream.empty () &&
canonical_release.empty ())
{
- assert (revision == 0); // Can't happen if through all previous checks.
+ assert (!revision); // Can't happen if through all previous checks.
bad_arg ("empty version");
}
}
@@ -534,10 +543,10 @@ namespace bpkg
if (!ignore_revision)
{
- if (revision != 0)
+ if (revision)
{
v += '+';
- v += to_string (revision);
+ v += to_string (*revision);
}
if (!ignore_iteration && iteration != 0)
@@ -646,7 +655,7 @@ namespace bpkg
if (mnv != "$")
try
{
- min_version = version (mnv);
+ min_version = version (mnv, false /* fold_zero_revision */);
}
catch (const invalid_argument& e)
{
@@ -674,7 +683,7 @@ namespace bpkg
if (mxv != "$")
try
{
- max_version = version (mxv);
+ max_version = version (mxv, false /* fold_zero_revision */);
}
catch (const invalid_argument& e)
{
@@ -735,6 +744,11 @@ namespace bpkg
{
assert (vc.min_version && vc.max_version);
+ // Note that standard_version::string() folds the zero revision.
+ // However, that's ok since the shortcut operator ~X.Y.Z+0
+ // translates into [X.Y.Z+0 X.Y+1.0-) which covers the same versions
+ // set as [X.Y.Z X.Y+1.0-).
+ //
*this = dependency_constraint (
version (vc.min_version->string ()),
vc.min_open,
@@ -789,7 +803,7 @@ namespace bpkg
// version.
//
if (vs != "$")
- v = version (vs);
+ v = version (vs, false /* fold_zero_revision */);
switch (operation)
{
@@ -844,7 +858,19 @@ namespace bpkg
// max version.
//
if (*min_version > *max_version && !mxe)
- throw invalid_argument ("min version is greater than max version");
+ {
+ // Handle the (X+Y X] and [X+Y X] corner cases (any revision of
+ // version X greater (or equal) than X+Y). Note that technically
+ // X+Y > X (see version::compare() for details).
+ //
+ // Also note that we reasonably fail for (X+Y X) and [X+Y X).
+ //
+ if (!(!max_open &&
+ !max_version->revision &&
+ max_version->compare (*min_version,
+ true /* ignore_revision */) == 0))
+ throw invalid_argument ("min version is greater than max version");
+ }
if (*min_version == *max_version)
{
@@ -884,7 +910,7 @@ namespace bpkg
v = version (v.epoch,
move (v.upstream),
move (v.release),
- 0 /* revision */,
+ nullopt /* revision */,
0 /* iteration */);
// Calculate effective constraint for a shortcut operator.
@@ -1601,7 +1627,7 @@ namespace bpkg
return email (move (v), move (c));
}
- const version stub_version (0, "0", nullopt, 0, 0);
+ const version stub_version (0, "0", nullopt, nullopt, 0);
static void
parse_package_manifest (
@@ -1747,7 +1773,7 @@ namespace bpkg
try
{
- m.version = version (move (v));
+ m.version = version (v);
}
catch (const invalid_argument& e)
{
@@ -2104,7 +2130,7 @@ namespace bpkg
//
nv = move (*upstream_version);
- if (m.version.compare (stub_version, true) == 0)
+ if (m.version.compare (stub_version, true /* ignore_revision */) == 0)
bad_name ("upstream package version specified for a stub");
m.upstream_version = move (nv.value);
diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx
index c0901e9..3d02e50 100644
--- a/libbpkg/manifest.hxx
+++ b/libbpkg/manifest.hxx
@@ -42,7 +42,13 @@ namespace bpkg
const std::uint16_t epoch;
const std::string upstream;
const butl::optional<std::string> release;
- const std::uint16_t revision;
+
+ // The absent revision semantics depends on the context the version object
+ // is used in. Normally, it is equivalent to zero revision but may have a
+ // special meaning, for example, denoting any package revision.
+ //
+ const butl::optional<std::uint16_t> revision;
+
const std::uint32_t iteration;
// Upstream part canonical representation.
@@ -56,29 +62,37 @@ namespace bpkg
// Create a special empty version. It is less than any other valid
// version (and is conceptually equivalent to +0-0-).
//
- version (): epoch (0), release (""), revision (0), iteration (0) {}
+ version (): epoch (0), release (""), iteration (0) {}
- // Throw std::invalid_argument if the passed string is not a valid
- // version representation.
+ // By default, treat the zero revision as no revision. Throw
+ // std::invalid_argument if the passed string is not a valid version
+ // representation.
//
explicit
- version (const std::string& v): version (v.c_str ()) {}
+ version (const std::string& v, bool fold_zero_revision = true)
+ : version (v.c_str (), fold_zero_revision) {}
explicit
- version (const char* v): version (data_type (v, data_type::parse::full)) {}
+ version (const char* v, bool fold_zero_revision = true)
+ : version (data_type (v, data_type::parse::full, fold_zero_revision))
+ {
+ }
// Create the version object from separate epoch, upstream, release,
// revision, and iteration parts.
//
// Note that it is possible (and legal) to create the special empty
- // version via this interface as version(0, string(), string(), 0, 0).
+ // version via this interface as version(0, string(), string(), nullopt, 0).
//
version (std::uint16_t epoch,
std::string upstream,
butl::optional<std::string> release,
- std::uint16_t revision,
+ butl::optional<std::uint16_t> revision,
std::uint32_t iteration);
+ std::uint16_t
+ effective_revision () const noexcept {return revision ? *revision : 0;}
+
version (version&&) = default;
version (const version&) = default;
version& operator= (version&&);
@@ -145,7 +159,7 @@ namespace bpkg
assert (!e ||
(epoch == 0 &&
release && release->empty () &&
- revision == 0 && iteration == 0));
+ !revision && iteration == 0));
return e;
}
@@ -155,7 +169,7 @@ namespace bpkg
{
enum class parse {full, upstream, release};
- data_type (const char*, parse);
+ data_type (const char*, parse, bool fold_zero_revision);
// Note that there is no iteration component as it can't be present in
// the string representation passed to the ctor.
@@ -163,7 +177,7 @@ namespace bpkg
std::uint16_t epoch;
std::string upstream;
butl::optional<std::string> release;
- std::uint16_t revision;
+ butl::optional<std::uint16_t> revision;
std::string canonical_upstream;
std::string canonical_release;
};
@@ -305,6 +319,13 @@ namespace bpkg
// `~$` (min endpoint is open) or `^$` (max endpoint is open). Note that
// equal endpoints can never be both open.
//
+ // An absent endpoint version revision has the 'any revision' meaning and
+ // so translates into the effective revision differently, depending on the
+ // range endpoint side and openness:
+ //
+ // [X Y) == [X+0 Y+0)
+ // (X Y] == (X+max Y+max]
+ //
class LIBBPKG_EXPORT dependency_constraint
{
public:
@@ -313,11 +334,15 @@ namespace bpkg
bool min_open;
bool max_open;
+ // Preserve the zero endpoint version revisions (see above for details).
+ //
+ explicit
dependency_constraint (const std::string&);
dependency_constraint (butl::optional<version> min_version, bool min_open,
butl::optional<version> max_version, bool max_open);
+ explicit
dependency_constraint (const version& v)
: dependency_constraint (v, false, v, false) {}
diff --git a/tests/manifest/testscript b/tests/manifest/testscript
index 9406a2a..2af195d 100644
--- a/tests/manifest/testscript
+++ b/tests/manifest/testscript
@@ -2,294 +2,385 @@
# copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
# license : MIT; see accompanying LICENSE file
-: packages
+: package
:
{
+ test.options += -p
+
: name
:
{
: valid
:
- $* -pp <<EOF >>EOF
+ $* <<EOF >>EOF
: 1
- sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
- :
name: libfoo.c++-2
version: 2.0.0
summary: Modern C++ parser
license: LGPLv2
url: http://www.example.org/projects/libfoo/
email: libfoo-users@example.org
- location: libfoo.c++-2-2.0.0.tar.bz2
- sha256sum: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
EOF
- : invalid
+ : short
:
- {
- : short
- :
- $* -pp <<EOI 2>'stdin:4:7: error: invalid package name: length is less than two characters' != 0
- : 1
- sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
- :
- name: b
- EOI
+ $* <<EOI 2>'stdin:2:7: error: invalid package name: length is less than two characters' != 0
+ : 1
+ name: b
+ EOI
- : illegal
- :
- $* -pp <<EOI 2>'stdin:4:7: error: invalid package name: illegal name' != 0
- : 1
- sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
- :
- name: com3
- EOI
+ : illegal
+ :
+ $* <<EOI 2>'stdin:2:7: error: invalid package name: illegal name' != 0
+ : 1
+ name: com3
+ EOI
+
+ : illegal-first-char
+ :
+ $* <<EOI 2>'stdin:2:7: error: invalid package name: illegal first character (must be alphabetic)' != 0
+ : 1
+ name: 2b
+ EOI
+
+ : illegal-last-char
+ :
+ $* <<EOI 2>'stdin:2:7: error: invalid package name: illegal last character (must be alphabetic, digit, or plus)' != 0
+ : 1
+ name: foo_
+ EOI
+
+ : illegal-char
+ :
+ $* <<EOI 2>'stdin:2:7: error: invalid package name: illegal character' != 0
+ : 1
+ name: foo'bar
+ EOI
+ }
+
+ : upstream-version
+ :
+ {
+ : valid
+ :
+ $* <<EOF >>EOF
+ : 1
+ name: libfoo
+ version: 2.0.0
+ upstream-version: 0.28.0.abc.15
+ summary: Modern C++ parser
+ license: LGPLv2
+ description: libfoo is a very modern C++ XML parser.
+ EOF
+
+ : duplicate
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ name: libfoo
+ version: 2.0.0
+ upstream-version: 0.28.0.abc.15
+ summary: Modern C++ parser
+ license: LGPLv2
+ description: libfoo is a very modern C++ XML parser.
+ upstream-version: 0.28.0.abc.15
+ EOI
+ stdin:8:1: error: upstream package version redefinition
+ EOE
+
+ : stub
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ name: libfoo
+ version: 0+1
+ upstream-version: 0.28.0.abc.15
+ summary: Modern C++ parser
+ license: LGPLv2
+ description: libfoo is a very modern C++ XML parser.
+ EOI
+ stdin:4:1: error: upstream package version specified for a stub
+ EOE
+ }
+
+ : topics
+ :
+ {
+ : valid
+ :
+ $* <<EOF >>EOF
+ : 1
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ topics: c++ library, foo library, libfoo
+ EOF
+
+ : too-many
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ topics: c++, library, lib, foo, libfoo, libbar
+ EOI
+ stdin:2:9: error: up to five topics allowed
+ EOE
+ }
+
+ : keywords
+ :
+ {
+ : valid
+ :
+ $* <<EOF >>EOF
+ : 1
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ keywords: c++ library lib foo libfoo
+ EOF
+
+ : redefinition
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ keywords: c++ library lib foo libfoo
+ keywords: c++ library lib foo libfoo
+ EOI
+ stdin:3:1: error: package keywords redefinition
+ EOE
+
+ : too-many
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ keywords: c++ library lib foo libfoo libbar
+ EOI
+ stdin:2:11: error: up to five keywords allowed
+ EOE
+
+ : empty
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ keywords:
+ EOI
+ stdin:2:10: error: empty package keywords specification
+ EOE
+ }
+
+ : tags
+ :
+ {
+ : truncate
+ :
+ $* <<EOI >>EOO
+ : 1
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ tags: c++, library, lib, foo, libfoo, libbar
+ EOI
+ : 1
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ keywords: c++ library lib foo libfoo
+ EOO
+
+ : with-space
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ tags: c++ library, lib, foo, libfoo
+ EOI
+ stdin:2:7: error: only single-word tags allowed
+ EOE
+ }
- : first-char
+ : description-file
+ :
+ {
+ : absolute-path
+ :
+ $* <<EOI 2>>~%EOE% != 0
+ : 1
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ description-file: /README
+ EOI
+ %(
+ stdin:6:19: error: package description-file path is absolute
+ %|
+ stdin:6:19: error: invalid package description file: invalid filesystem path
+ %)
+ EOE
+ }
+
+ : description-type
+ :
+ {
+ : absent
+ :
+ $* <<EOF >>EOF
+ : 1
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ description: libfoo is a very modern C++ XML parser.
+ EOF
+
+ : not-text
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ description: libfoo is a very modern C++ XML parser.
+ description-type: image/gif
+ EOI
+ stdin:7:19: error: invalid package description type: text type expected
+ EOE
+
+ : deducing
+ :
+ {
+ : fail
:
- $* -pp <<EOI 2>'stdin:4:7: error: invalid package name: illegal first character (must be alphabetic)' != 0
+ $* <<EOI 2>>EOE != 0
: 1
- sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
- :
- name: 2b
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ description-file: README.rtf
EOI
+ stdin:6:19: error: invalid package description file: unknown text type
+ EOE
- : last-char
+ : ignore-unknown
:
- $* -pp <<EOI 2>'stdin:4:7: error: invalid package name: illegal last character (must be alphabetic, digit, or plus)' != 0
+ $* -i <<EOF >>EOF
: 1
- sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
- :
- name: foo_
- EOI
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ description-file: README.rtf
+ EOF
+ }
- : char
+ : unknown
+ :
+ {
+ : fail
:
- $* -pp <<EOI 2>'stdin:4:7: error: invalid package name: illegal character' != 0
+ $* <<EOI 2>>EOE != 0
: 1
- sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
- :
- name: foo'bar
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ description: libfoo is a very modern C++ XML parser.
+ description-type: text/markdowns
EOI
+ stdin:7:19: error: invalid package description type: unknown text type
+ EOE
- : dependency
+ : ignore
:
- $* -pp <<EOI 2>'stdin:8:10: error: invalid prerequisite package name: length is less than two characters' != 0
+ $* -i <<EOF >>EOF
: 1
- sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
- :
- name: foo
+ name: libfoo
version: 2.0.0
summary: Modern C++ parser
license: LGPLv2
- depends: b
- EOI
+ description: libfoo is a very modern C++ XML parser.
+ description-type: text/markdowns
+ EOF
+ }
- : dependency-constraint
+ : plain
+ :
+ {
+ : valid
:
- $* -pp <<EOI 2>'stdin:8:10: error: $ not allowed' != 0
+ $* <<EOF >>EOF
: 1
- sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
- :
- name: foo
+ name: libfoo
version: 2.0.0
summary: Modern C++ parser
license: LGPLv2
- depends: bar == $
- EOI
+ description: libfoo is a very modern C++ XML parser.
+ description-type: text/plain
+ EOF
- : dependency-constraint-version
+ : invalid
:
- $* -p -c <<EOI 2>'stdin:6:10: error: invalid dependency constraint: min version is greater than max version' != 0
+ $* <<EOI 2>>EOE != 0
: 1
- name: foo
+ name: libfoo
version: 2.0.0
summary: Modern C++ parser
license: LGPLv2
- depends: bar [$ 1.0.0]
+ description: libfoo is a very modern C++ XML parser.
+ description-type: text/plain;
EOI
+ stdin:7:19: error: invalid package description type: missing '='
+ EOE
}
- }
- : pkg
- :
- {
- : manifest
+ : markdown
:
{
- test.options += -p
-
- : invalid
+ : default
:
- {
- : description-file
- :
- $* <<EOI 2>>~%EOE% != 0
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- description-file: /README
- EOI
- %(
- stdin:6:19: error: package description-file path is absolute
- %|
- stdin:6:19: error: invalid package description file: invalid filesystem path
- %)
- EOE
-
- : url
- :
- {
- : no-scheme
- :
- $* <<EOI 2>>EOE != 0
- : 1
- src-url: libfoo
- EOI
- stdin:2:10: error: invalid src url: no scheme
- EOE
-
- : rootless
- :
- $* <<EOI 2>>EOE != 0
- : 1
- src-url: pkcs11:libfoo
- EOI
- stdin:2:10: error: invalid src url: rootless URL
- EOE
-
- : local
- :
- $* <<EOI 2>>EOE != 0
- : 1
- src-url: file:/libfoo/bar
- EOI
- stdin:2:10: error: invalid src url: local URL
- EOE
-
- : authority-absent
- :
- $* <<EOI 2>>EOE != 0
- : 1
- src-url: http:/libfoo/bar
- EOI
- stdin:2:10: error: invalid src url: no authority
- EOE
-
- : authority-empty
- :
- $* <<EOI 2>>EOE != 0
- : 1
- src-url: http:///libfoo/bar
- EOI
- stdin:2:10: error: invalid src url: no authority
- EOE
- }
- }
+ $* <<EOF >>EOF
+ : 1
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ description: libfoo is a very modern C++ XML parser.
+ description-type: text/markdown
+ EOF
- : complete
+ : gfm
:
- {
- test.options += -c
-
- : final
- :
- $* <<EOI >>EOO
- : 1
- name: foo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- depends: bar == $ | libbaz ~$ | libbox ^$ | libfox [1.0 $)
- EOI
- : 1
- name: foo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- depends: bar == 2.0.0 | libbaz ~2.0.0 | libbox ^2.0.0 | libfox [1.0 2.0.0)
- EOO
-
- : non-standard
- :
- $* <<EOI >>EOO
- : 1
- name: foo
- version: 2.0.0-x
- summary: Modern C++ parser
- license: LGPLv2
- depends: bar == $ | libfox [1.0 $)
- EOI
- : 1
- name: foo
- version: 2.0.0-x
- summary: Modern C++ parser
- license: LGPLv2
- depends: bar == 2.0.0-x | libfox [1.0 2.0.0-x)
- EOO
-
- : non-standard-shortcut
- :
- $* <<EOI 2>>EOE != 0
- : 1
- name: foo
- version: 2.0.0-x
- summary: Modern C++ parser
- license: LGPLv2
- depends: bar ~$
- EOI
- stdin:6:10: error: invalid dependency constraint: dependent version is not standard
- EOE
-
- : latest-snapshot
- :
- $* <<EOI >>EOO
- : 1
- name: foo
- version: 2.0.0-a.0.z
- summary: Modern C++ parser
- license: LGPLv2
- depends: bar == $ | libbaz ~$ | libbox ^$ | libfox [1.0 $)
- EOI
- : 1
- name: foo
- version: 2.0.0-a.0.123
- summary: Modern C++ parser
- license: LGPLv2
- depends: bar == 2.0.0-a.0.123 | libbaz [2.0.0-a.0.1 2.0.0-a.1) | libbox\
- [2.0.0-a.0.1 2.0.0-a.1) | libfox [1.0 2.0.0-a.0.123)
- EOO
-
- }
+ $* <<EOF >>EOF
+ : 1
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ description: libfoo is a very modern C++ XML parser.
+ description-type: text/markdown; variant=GFM
+ EOF
- : incomplete
+ : common-mark
:
$* <<EOF >>EOF
: 1
- name: foo
+ name: libfoo
version: 2.0.0
summary: Modern C++ parser
license: LGPLv2
- depends: bar == $ | libbaz ~$ | libbox ^$ | libfox [1.0 $)
+ description: libfoo is a very modern C++ XML parser.
+ description-type: text/markdown; variant=CommonMark
EOF
- : description-type
+ : invalid-variant
:
{
- : absent
- :
- $* <<EOF >>EOF
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- description: libfoo is a very modern C++ XML parser.
- EOF
-
- : not-text
+ : fail
:
$* <<EOI 2>>EOE != 0
: 1
@@ -298,364 +389,251 @@
summary: Modern C++ parser
license: LGPLv2
description: libfoo is a very modern C++ XML parser.
- description-type: image/gif
+ description-type: text/markdown; variant=Original
EOI
- stdin:7:19: error: invalid package description type: text type expected
+ stdin:7:19: error: invalid package description type: unknown text type
EOE
- : deducing
- :
- {
- : fail
- :
- $* <<EOI 2>>EOE != 0
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- description-file: README.rtf
- EOI
- stdin:6:19: error: invalid package description file: unknown text type
- EOE
-
- : ignore-unknown
- :
- $* -i <<EOF >>EOF
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- description-file: README.rtf
- EOF
- }
-
- : unknown
- :
- {
- : fail
- :
- $* <<EOI 2>>EOE != 0
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- description: libfoo is a very modern C++ XML parser.
- description-type: text/markdowns
- EOI
- stdin:7:19: error: invalid package description type: unknown text type
- EOE
-
- : ignore
- :
- $* -i <<EOF >>EOF
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- description: libfoo is a very modern C++ XML parser.
- description-type: text/markdowns
- EOF
- }
-
- : plain
+ : ignore
:
- {
- : valid
- :
- $* <<EOF >>EOF
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- description: libfoo is a very modern C++ XML parser.
- description-type: text/plain
- EOF
-
- : invalid
- :
- $* <<EOI 2>>EOE != 0
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- description: libfoo is a very modern C++ XML parser.
- description-type: text/plain;
- EOI
- stdin:7:19: error: invalid package description type: missing '='
- EOE
- }
-
- : markdown
- :
- {
- : default
- :
- $* <<EOF >>EOF
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- description: libfoo is a very modern C++ XML parser.
- description-type: text/markdown
- EOF
-
- : gfm
- :
- $* <<EOF >>EOF
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- description: libfoo is a very modern C++ XML parser.
- description-type: text/markdown; variant=GFM
- EOF
-
- : common-mark
- :
- $* <<EOF >>EOF
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- description: libfoo is a very modern C++ XML parser.
- description-type: text/markdown; variant=CommonMark
- EOF
-
- : invalid-variant
- :
- {
- : fail
- :
- $* <<EOI 2>>EOE != 0
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- description: libfoo is a very modern C++ XML parser.
- description-type: text/markdown; variant=Original
- EOI
- stdin:7:19: error: invalid package description type: unknown text type
- EOE
-
- : ignore
- :
- $* -i <<EOF >>EOF
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- description: libfoo is a very modern C++ XML parser.
- description-type: text/markdown; variant=Original
- EOF
- }
-
- : invalid-parameter
- :
- {
- : fail
- :
- $* <<EOI 2>>EOE != 0
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- description: libfoo is a very modern C++ XML parser.
- description-type: text/markdown; variants=GFM
- EOI
- stdin:7:19: error: invalid package description type: unknown text type
- EOE
-
- : ignore
- :
- $* -i <<EOF >>EOF
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- description: libfoo is a very modern C++ XML parser.
- description-type: text/markdown; variants=GFM
- EOF
- }
- }
- }
-
- : builds
- :
- {
- : invalid
- :
- {
- : empty
- :
- $* <<EOI 2>"stdin:2:9: error: invalid package builds: class expression separator ':' expected" != 0
- : 1
- builds: default -gcc
- EOI
- }
- }
-
- : upstream-version
- :
- {
- : valid
- :
- $* <<EOF >>EOF
+ $* -i <<EOF >>EOF
: 1
name: libfoo
version: 2.0.0
- upstream-version: 0.28.0.abc.15
summary: Modern C++ parser
license: LGPLv2
description: libfoo is a very modern C++ XML parser.
+ description-type: text/markdown; variant=Original
EOF
+ }
- : duplicate
+ : invalid-parameter
+ :
+ {
+ : fail
:
$* <<EOI 2>>EOE != 0
: 1
name: libfoo
version: 2.0.0
- upstream-version: 0.28.0.abc.15
summary: Modern C++ parser
license: LGPLv2
description: libfoo is a very modern C++ XML parser.
- upstream-version: 0.28.0.abc.15
+ description-type: text/markdown; variants=GFM
EOI
- stdin:8:1: error: upstream package version redefinition
+ stdin:7:19: error: invalid package description type: unknown text type
EOE
- : stub
+ : ignore
:
- $* <<EOI 2>>EOE != 0
+ $* -i <<EOF >>EOF
: 1
name: libfoo
- version: 0+1
- upstream-version: 0.28.0.abc.15
+ version: 2.0.0
summary: Modern C++ parser
license: LGPLv2
description: libfoo is a very modern C++ XML parser.
- EOI
- stdin:4:1: error: upstream package version specified for a stub
- EOE
+ description-type: text/markdown; variants=GFM
+ EOF
}
+ }
+ }
- : keywords
- :
- {
- : valid
- :
- $* <<EOF >>EOF
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- keywords: c++ library lib foo libfoo
- EOF
+ : src-url
+ :
+ {
+ : no-scheme
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ src-url: libfoo
+ EOI
+ stdin:2:10: error: invalid src url: no scheme
+ EOE
- : redefinition
- :
- $* <<EOI 2>>EOE != 0
- : 1
- keywords: c++ library lib foo libfoo
- keywords: c++ library lib foo libfoo
- EOI
- stdin:3:1: error: package keywords redefinition
- EOE
+ : rootless
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ src-url: pkcs11:libfoo
+ EOI
+ stdin:2:10: error: invalid src url: rootless URL
+ EOE
- : too-many
- :
- $* <<EOI 2>>EOE != 0
- : 1
- keywords: c++ library lib foo libfoo libbar
- EOI
- stdin:2:11: error: up to five keywords allowed
- EOE
+ : local
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ src-url: file:/libfoo/bar
+ EOI
+ stdin:2:10: error: invalid src url: local URL
+ EOE
- : empty
- :
- $* <<EOI 2>>EOE != 0
- : 1
- keywords:
- EOI
- stdin:2:10: error: empty package keywords specification
- EOE
- }
+ : authority-absent
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ src-url: http:/libfoo/bar
+ EOI
+ stdin:2:10: error: invalid src url: no authority
+ EOE
- : tags
+ : authority-empty
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ src-url: http:///libfoo/bar
+ EOI
+ stdin:2:10: error: invalid src url: no authority
+ EOE
+ }
+
+ : builds
+ :
+ {
+ : empty
+ :
+ $* <<EOI 2>"stdin:2:9: error: invalid package builds: class expression separator ':' expected" != 0
+ : 1
+ builds: default -gcc
+ EOI
+ }
+
+ : dependency
+ :
+ {
+ : short-name
+ :
+ $* <<EOI 2>'stdin:6:10: error: invalid prerequisite package name: length is less than two characters' != 0
+ : 1
+ name: foo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ depends: b
+ EOI
+
+ : invalid-version-range
+ :
+ $* -c <<EOI 2>'stdin:6:10: error: invalid dependency constraint: min version is greater than max version' != 0
+ : 1
+ name: foo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ depends: bar [$ 1.0.0]
+ EOI
+
+ : corner-case
+ :
+ $* <<EOF >>EOF
+ : 1
+ name: foo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ depends: bar [1.0.0+2 1.0.0]
+ EOF
+
+ : complete
+ :
+ {
+ test.options += -c
+
+ : final
:
- {
- : truncate
- :
- $* <<EOI >>EOO
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- tags: c++, library, lib, foo, libfoo, libbar
- EOI
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- keywords: c++ library lib foo libfoo
- EOO
+ $* <<EOI >>EOO
+ : 1
+ name: foo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ depends: bar == $ | libbaz ~$ | libbox ^$ | libfox [1.0 $)
+ EOI
+ : 1
+ name: foo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ depends: bar == 2.0.0 | libbaz ~2.0.0 | libbox ^2.0.0 | libfox [1.0 2.0.0)
+ EOO
- : with-space
- :
- $* <<EOI 2>>EOE != 0
- : 1
- tags: c++ library, lib, foo, libfoo
- EOI
- stdin:2:7: error: only single-word tags allowed
- EOE
- }
+ : non-standard
+ :
+ $* <<EOI >>EOO
+ : 1
+ name: foo
+ version: 2.0.0-x
+ summary: Modern C++ parser
+ license: LGPLv2
+ depends: bar == $ | libfox [1.0 $)
+ EOI
+ : 1
+ name: foo
+ version: 2.0.0-x
+ summary: Modern C++ parser
+ license: LGPLv2
+ depends: bar == 2.0.0-x | libfox [1.0 2.0.0-x)
+ EOO
- : topics
+ : non-standard-shortcut
:
- {
- : valid
- :
- $* <<EOF >>EOF
- : 1
- name: libfoo
- version: 2.0.0
- summary: Modern C++ parser
- license: LGPLv2
- topics: c++ library, foo library, libfoo
- EOF
+ $* <<EOI 2>>EOE != 0
+ : 1
+ name: foo
+ version: 2.0.0-x
+ summary: Modern C++ parser
+ license: LGPLv2
+ depends: bar ~$
+ EOI
+ stdin:6:10: error: invalid dependency constraint: dependent version is not standard
+ EOE
+
+ : latest-snapshot
+ :
+ $* <<EOI >>EOO
+ : 1
+ name: foo
+ version: 2.0.0-a.0.z
+ summary: Modern C++ parser
+ license: LGPLv2
+ depends: bar == $ | libbaz ~$ | libbox ^$ | libfox [1.0 $)
+ EOI
+ : 1
+ name: foo
+ version: 2.0.0-a.0.123
+ summary: Modern C++ parser
+ license: LGPLv2
+ depends: bar == 2.0.0-a.0.123 | libbaz [2.0.0-a.0.1 2.0.0-a.1) | libbox\
+ [2.0.0-a.0.1 2.0.0-a.1) | libfox [1.0 2.0.0-a.0.123)
+ EOO
- : too-many
- :
- $* <<EOI 2>>EOE != 0
- : 1
- topics: c++, library, lib, foo, libfoo, libbar
- EOI
- stdin:2:9: error: up to five topics allowed
- EOE
- }
}
- : manifest-list
+ : incomplete
:
- : Roundtrip the pkg package manifest list.
+ $* <<EOF >>EOF
+ : 1
+ name: foo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ depends: bar == $ | libbaz ~$ | libbox ^$ | libfox [1.0 $)
+ EOF
+ }
+}
+
+: package-list
+:
+{
+ : pkg
+ :
+ {
+ test.options += -pp
+
+ : roundtrip
:
- $* -pp <<EOF >>EOF
+ $* <<EOF >>EOF
: 1
sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
:
@@ -725,22 +703,37 @@
location: libbaz/libbaz-+2-3.4A.5+3.tar.gz
sha256sum: b5b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
EOF
+
+ : dependency
+ :
+ {
+ : incomplete
+ :
+ $* <<EOI 2>'stdin:8:10: error: $ not allowed' != 0
+ : 1
+ sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ :
+ name: foo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ depends: bar == $
+ EOI
+ }
}
: dir
:
{
+ test.options += -dp
+
: empty
:
- : Roundtrip an empty dir package manifest list.
- :
- $* -gp <"" >:""
+ $* <"" >:""
: non-empty
:
- : Roundtrip the dir package manifest list.
- :
- $* -gp <<EOF >>EOF
+ $* <<EOF >>EOF
: 1
location: hello/
:
@@ -749,7 +742,7 @@
: duplicate
:
- $* -gp <<EOI 2>'stdin:5:1: error: duplicate package manifest' != 0
+ $* <<EOI 2>'stdin:5:1: error: duplicate package manifest' != 0
: 1
location: hello/
:
@@ -762,9 +755,11 @@
: git
:
{
+ test.options += -gp
+
: fragment
:
- $* -gp <<EOF >>EOF
+ $* <<EOF >>EOF
: 1
location: hello/
fragment: ca602c2d46b0dca7a9ebc856871767b0ba6b74f3
@@ -775,39 +770,17 @@
}
}
-: repositories
+: repository-list
:
{
- : base-manifest-redefinition
- :
- $* -pr <<EOI 2>'stdin:3:1: error: base repository manifest redefinition' != 0
- : 1
- url: http://cppget.org
- :
- url: http://cppget.org
- EOI
-
- : no-base
- :
- $* -pr <<EOO >>EOO
- : 1
- location: http://pkg.example.org/1/math
- type: pkg
- role: prerequisite
- :
- location: ../stable
- type: pkg
- role: complement
- EOO
-
: pkg
:
{
- : manifest
- :
- : Roundtrip the pkg repository manifest list.
+ test.options += -pr
+
+ : roundtrip
:
- $* -pr <<EOF >>EOF
+ $* <<EOF >>EOF
: 1
location: http://pkg.example.org/1/math
type: pkg
@@ -858,7 +831,7 @@
: prerequisite-type
:
- $* -pr <<EOI >>EOO
+ $* <<EOI >>EOO
: 1
url: http://cppget.org
:
@@ -904,16 +877,38 @@
trust: 37:CE:2C:A5:1D:CF:93:81:D7:07:46:AD:66:B3:C3:90:83:B8:96:9E:34:F0:E7:B\
3:A2:B0:6C:EF:66:A4:BE:65
EOO
+
+ : no-base
+ :
+ $* <<EOO >>EOO
+ : 1
+ location: http://pkg.example.org/1/math
+ type: pkg
+ role: prerequisite
+ :
+ location: ../stable
+ type: pkg
+ role: complement
+ EOO
+
+ : base-manifest-redefinition
+ :
+ $* <<EOI 2>'stdin:3:1: error: base repository manifest redefinition' != 0
+ : 1
+ url: http://cppget.org
+ :
+ url: http://cppget.org
+ EOI
}
: git
:
{
- : manifest
- :
- : Roundtrip the git repository manifest list.
+ test.options += -gr
+
+ : roundtrip
:
- $* -gr <<EOF >>EOF
+ $* <<EOF >>EOF
: 1
location: http://example.org/math.git#master
type: git
@@ -936,7 +931,7 @@
: fragment
:
- $* -gr <<EOF >>EOF
+ $* <<EOF >>EOF
: 1
location: http://example.org/math.git#master
type: git
@@ -972,7 +967,7 @@
: prerequisite-type
:
- $* -gr <<EOI >>EOO
+ $* <<EOI >>EOO
: 1
location: http://example.org/math.git#master
role: prerequisite
@@ -1013,11 +1008,11 @@
: dir
:
{
- : manifest
- :
- : Roundtrip the dir repository manifest list.
+ test.options += -dr
+
+ : roundtrip
:
- $* -dr <<EOF >>EOF
+ $* <<EOF >>EOF
: 1
location: ../stable
type: dir
@@ -1027,7 +1022,7 @@
: prerequisite-with-fragment
:
- $* -dr <<EOI 2>>EOE != 0
+ $* <<EOI 2>>EOE != 0
: 1
location: ../stable.git#stable
type: dir
@@ -1039,13 +1034,10 @@
}
}
-
: signature
:
-: Roundtrip the signature manifest.
-:
{
- : manifest
+ : roundtrip
:
$* -s <<EOF >>EOF
: 1
diff --git a/tests/package-version/driver.cxx b/tests/package-version/driver.cxx
index e81115a..5cf7e09 100644
--- a/tests/package-version/driver.cxx
+++ b/tests/package-version/driver.cxx
@@ -123,6 +123,7 @@ namespace bpkg
assert (bad_version ("1-a.00000000000000000")); // Same.
assert (bad_version (0, "1", "", 1)); // Revision for empty release.
+ assert (bad_version (0, "1", "", 0)); // Same.
assert (bad_version (1, "+1-1.1", "", 2)); // Epoch in upstream.
assert (bad_version (1, "1.1-1", "", 2)); // Release in upstream.
assert (bad_version (1, "1.1+1", "", 2)); // Revision in upstream.
@@ -133,6 +134,7 @@ namespace bpkg
assert (bad_version (1, "", "", 0)); // Unexpected epoch.
assert (bad_version (0, "", "1", 0)); // Unexpected release.
assert (bad_version (0, "", "", 1)); // Unexpected revision.
+ assert (bad_version (0, "", "", 0)); // Same.
assert (bad_version (0, "", "", 0, 1)); // Unexpected iteration.
{
@@ -243,12 +245,24 @@ namespace bpkg
assert (test_constructor (v));
}
{
+ version v ("+10-B");
+ assert (v.string () == "+10-B");
+ assert (v.canonical_upstream == "b");
+ assert (test_constructor (v));
+ }
+ {
version v ("+10-B+0");
assert (v.string () == "+10-B");
assert (v.canonical_upstream == "b");
assert (test_constructor (v));
}
{
+ version v ("+10-B+0", false /* fold_zero_revision */);
+ assert (v.string () == "+10-B+0");
+ assert (v.canonical_upstream == "b");
+ assert (test_constructor (v));
+ }
+ {
version v ("+3-1A.31.0.4.0+7");
assert (v.string () == "+3-1A.31.0.4.0+7");
assert (v.canonical_upstream ==
@@ -298,7 +312,7 @@ namespace bpkg
assert (test_constructor (v));
}
{
- version v (2, "1", string (), 0, 0);
+ version v (2, "1", string (), nullopt, 0);
assert (v.string () == "+2-1-");
assert (v.release && v.release->empty ());
assert (v.canonical_release.empty ());
@@ -311,7 +325,8 @@ namespace bpkg
assert (v.string (true, false) == "+3-2.0");
assert (v.string (false, true) == "+3-2.0+3");
- assert (version (3, "2.0", nullopt, 0, 1).string () == "+3-2.0#1");
+ assert (version (3, "2.0", nullopt, nullopt, 1).string () == "+3-2.0#1");
+ assert (version (3, "2.0", nullopt, 0, 1).string () == "+3-2.0+0#1");
assert (version (3, "2.0", nullopt, 1, 0).string () == "+3-2.0+1");
}
@@ -363,8 +378,8 @@ namespace bpkg
assert (version ("1.1.1a+1") < version ("1.1.1b"));
assert (version (1, "2.0", nullopt, 3, 0) == version ("+1-2+3"));
- assert (version (1, "2.0", string (), 0, 0) == version ("+1-2-"));
- assert (version (0, "", string (), 0, 0) == version ());
+ assert (version (1, "2.0", string (), nullopt, 0) == version ("+1-2-"));
+ assert (version (0, "", string (), nullopt, 0) == version ());
assert (version (1, "2.0", nullopt, 3, 4).compare (
version (1, "2.0", nullopt, 3, 4)) == 0);