From 4c6c50047e085e256a19a91ee84398a3b7c8846f Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 3 May 2018 14:50:05 +0300 Subject: Make base repository manifest optional --- libbpkg/manifest.cxx | 82 +++++++++++++++++++++++++--------------------------- libbpkg/manifest.hxx | 20 ++++++++----- 2 files changed, 51 insertions(+), 51 deletions(-) (limited to 'libbpkg') diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx index d14437b..35df21d 100644 --- a/libbpkg/manifest.cxx +++ b/libbpkg/manifest.cxx @@ -55,7 +55,7 @@ namespace bpkg if (s.size () != 64) return false; - for (const char& c: s) + for (char c: s) { if ((c < 'a' || c > 'f' ) && !digit (c)) return false; @@ -2410,22 +2410,6 @@ namespace bpkg // repository_manifest // - repository_role repository_manifest:: - effective_role () const - { - if (role) - { - if (location.empty () != (*role == repository_role::base)) - throw logic_error ("invalid role"); - - return *role; - } - else - return location.empty () - ? repository_role::base - : repository_role::prerequisite; - } - optional repository_manifest:: effective_url (const repository_location& l) const { @@ -2701,11 +2685,13 @@ namespace bpkg // - role can be omitted // - trust, url, email, summary, description and certificate are allowed // - if (r.role && r.location.empty () != (*r.role == repository_role::base)) - bad_value ("invalid role"); - bool base (r.effective_role () == repository_role::base); + if (r.location.empty () != base) + throw logic_error (r.location.empty () + ? "no location specified" + : "location not allowed"); + if (r.trust && (base || r.location.type () != repository_type::pkg)) bad_value ("trust not allowed"); @@ -2752,6 +2738,12 @@ namespace bpkg auto bad_value ([&s](const string& d) { throw serialization (s.name (), d);}); + bool b (effective_role () == repository_role::base); + + if (location.empty () != b) + throw logic_error ( + location.empty () ? "no location specified" : "location not allowed"); + s.next ("", "1"); // Start of manifest. if (!location.empty ()) @@ -2762,16 +2754,11 @@ namespace bpkg if (role) { - if (location.empty () != (*role == repository_role::base)) - bad_value ("invalid role"); - auto r (static_cast (*role)); assert (r < repository_role_names.size ()); s.next ("role", repository_role_names[r]); } - bool b (effective_role () == repository_role::base); - if (url) { if (!b) @@ -2828,6 +2815,20 @@ namespace bpkg s.next ("", ""); // End of manifest. } + static repository_manifest empty_base; + + const repository_manifest& + find_base_repository (const vector& ms) noexcept + { + for (const repository_manifest& m: ms) + { + if (m.effective_role () == repository_role::base) + return m; + } + + return empty_base; + } + // pkg_repository_manifest // repository_manifest @@ -2878,22 +2879,23 @@ namespace bpkg bool iu, vector& ms) { - name_value nv (p.next ()); - while (!nv.empty ()) + bool base (false); + + for (name_value nv (p.next ()); !nv.empty (); nv = p.next ()) { - ms.push_back (parse_repository_manifest (p, move (nv), base_type, iu)); - nv = p.next (); + ms.push_back (parse_repository_manifest (p, nv, base_type, iu)); - // Make sure there is location in all except the last entry. + // Make sure that there is a single base repository manifest in the + // list. // - if (ms.back ().location.empty () && !nv.empty ()) - throw parsing (p.name (), nv.name_line, nv.name_column, - "repository location expected"); + if (ms.back ().effective_role () == repository_role::base) + { + if (base) + throw parsing (p.name (), nv.name_line, nv.name_column, + "base repository manifest redefinition"); + base = true; + } } - - if (ms.empty () || !ms.back ().location.empty ()) - throw parsing (p.name (), nv.name_line, nv.name_column, - "base repository manifest expected"); } // Serialize the repository manifest list. @@ -2902,12 +2904,6 @@ namespace bpkg serialize_repository_manifests (serializer& s, const vector& ms) { - if (ms.empty () || !ms.back ().location.empty ()) - throw serialization (s.name (), "base repository manifest expected"); - - // @@ Should we check that there is location in all except the last - // entry? - // for (const repository_manifest& r: ms) r.serialize (s); diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx index 15d19fc..81dd5f0 100644 --- a/libbpkg/manifest.hxx +++ b/libbpkg/manifest.hxx @@ -917,16 +917,13 @@ namespace bpkg butl::optional fragment; // Return the effective role of the repository. If the role is not - // explicitly specified (see the role member above), then calculate - // the role based on the location. Specifically, if the location is - // empty, then the effective role is base. Otherwise -- prerequisite. - // If the role is specified, then verify that it is consistent with - // the location value (that is, base if the location is empty and - // prerequisite or complement if not) and return that. Otherwise, - // throw std::logic_error. + // explicitly specified, then the base role is assumed. // repository_role - effective_role () const; + effective_role () const noexcept + { + return role ? *role : repository_role::base; + } // Return the effective web interface URL based on the specified remote // repository location. If url is not present, doesn't start with '.', or @@ -1024,6 +1021,13 @@ namespace bpkg serialize (butl::manifest_serializer&) const; }; + // Search a repository manifest list for the base repository and return its + // reference, if found. Otherwise, return a reference to an empty manifest + // instance (which is the representation of the default base). + // + LIBBPKG_EXPORT const repository_manifest& + find_base_repository (const std::vector&) noexcept; + class LIBBPKG_EXPORT signature_manifest { public: -- cgit v1.1