aboutsummaryrefslogtreecommitdiff
path: root/libbpkg
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2018-05-03 14:50:05 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2018-05-03 15:31:20 +0300
commit4c6c50047e085e256a19a91ee84398a3b7c8846f (patch)
tree5a4c6a41fb62798292a66b6a624a63714b85de0e /libbpkg
parentd3e5ca3472472d1d6f218f6dc88371a79557880e (diff)
Make base repository manifest optional
Diffstat (limited to 'libbpkg')
-rw-r--r--libbpkg/manifest.cxx82
-rw-r--r--libbpkg/manifest.hxx20
2 files changed, 51 insertions, 51 deletions
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<string> 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<size_t> (*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<repository_manifest>& 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<repository_manifest>& 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<repository_manifest>& 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<std::string> 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<repository_manifest>&) noexcept;
+
class LIBBPKG_EXPORT signature_manifest
{
public: