aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/manifest25
-rw-r--r--bpkg/manifest.cxx102
-rw-r--r--tests/manifest/manifest3
3 files changed, 114 insertions, 16 deletions
diff --git a/bpkg/manifest b/bpkg/manifest
index a02a4a0..c920cd6 100644
--- a/bpkg/manifest
+++ b/bpkg/manifest
@@ -105,7 +105,7 @@ namespace bpkg
std::string comment;
};
- class manifest
+ class package_manifest
{
public:
using priority_type = bpkg::priority;
@@ -128,16 +128,33 @@ namespace bpkg
std::vector<requirement_alternatives> requirements;
public:
- manifest (manifest_parser&);
- manifest (manifest_parser&, const manifest_name_value& start);
+ package_manifest (manifest_parser&);
+ package_manifest (manifest_parser&, const manifest_name_value& start);
void
serialize (manifest_serializer&) const;
};
- class manifests: public std::vector<manifest>
+ class repository_manifest
{
public:
+ std::string location;
+
+ public:
+ repository_manifest (manifest_parser&);
+ repository_manifest (manifest_parser&, const manifest_name_value& start);
+
+ void
+ serialize (manifest_serializer&) const;
+ };
+
+ class manifests
+ {
+ public:
+ std::vector<repository_manifest> repositories;
+ std::vector<package_manifest> packages;
+
+ public:
manifests (manifest_parser&);
void
diff --git a/bpkg/manifest.cxx b/bpkg/manifest.cxx
index befd3c0..85e4296 100644
--- a/bpkg/manifest.cxx
+++ b/bpkg/manifest.cxx
@@ -16,29 +16,31 @@ namespace bpkg
using parser = manifest_parser;
using parsing = manifest_parsing;
using serializer = manifest_serializer;
+ using serialization = manifest_serialization;
using name_value = manifest_name_value;
- // manifest
+ // package_manifest
//
- manifest::
- manifest (parser& p): manifest (p, p.next ()) // Delegate.
+ package_manifest::
+ package_manifest (parser& p)
+ : package_manifest (p, p.next ()) // Delegate
{
// Make sure this is the end.
//
name_value nv (p.next ());
if (!nv.empty ())
throw parsing (p.name (), nv.name_line, nv.name_column,
- "single manifest expected");
+ "single package manifest expected");
}
- manifest::
- manifest (parser& p, const name_value& s)
+ package_manifest::
+ package_manifest (parser& p, const name_value& s)
{
// Make sure this is the start and we support the version.
//
if (!s.name.empty ())
throw parsing (p.name (), s.name_line, s.name_column,
- "start of manifest expected");
+ "start of package manifest expected");
if (s.value != "1")
throw parsing (p.name (), s.value_line, s.value_column,
@@ -54,14 +56,14 @@ namespace bpkg
// ...
else
throw parsing (p.name (), nv.value_line, nv.value_column,
- "unknown name " + n);
+ "unknown name '" + n + "' in package manifest");
}
// Verify all non-optional values were specified.
//
}
- void manifest::
+ void package_manifest::
serialize (serializer& s) const
{
s.next ("", "1"); // Start of manifest.
@@ -70,20 +72,96 @@ namespace bpkg
s.next ("", ""); // End of manifest.
}
+ // repository_manifest
+ //
+ repository_manifest::
+ repository_manifest (parser& p)
+ : repository_manifest (p, p.next ()) // Delegate
+ {
+ // Make sure this is the end.
+ //
+ name_value nv (p.next ());
+ if (!nv.empty ())
+ throw parsing (p.name (), nv.name_line, nv.name_column,
+ "single repository manifest expected");
+ }
+
+ repository_manifest::
+ repository_manifest (parser& p, const name_value& s)
+ {
+ // Make sure this is the start and we support the version.
+ //
+ if (!s.name.empty ())
+ throw parsing (p.name (), s.name_line, s.name_column,
+ "start of repository manifest expected");
+
+ if (s.value != "1")
+ throw parsing (p.name (), s.value_line, s.value_column,
+ "unsupported format version");
+
+ for (name_value nv (p.next ()); !nv.empty (); nv = p.next ())
+ {
+ string& n (nv.name);
+ string& v (nv.value);
+
+ if (n == "location")
+ location = move (v);
+ else
+ throw parsing (p.name (), nv.value_line, nv.value_column,
+ "unknown name '" + n + "' in repository manifest");
+ }
+
+ // Verify all non-optional values were specified.
+ //
+ // - location can be omitted
+ }
+
+ void repository_manifest::
+ serialize (serializer& s) const
+ {
+ s.next ("", "1"); // Start of manifest.
+
+ if (!location.empty ())
+ s.next ("location", location);
+
+ s.next ("", ""); // End of manifest.
+ }
+
// manifests
//
manifests::
manifests (parser& p)
{
+ bool rep (true); // Parsing repository list.
+
for (name_value nv (p.next ()); !nv.empty (); nv = p.next ())
- push_back (manifest (p, nv));
+ {
+ if (rep)
+ {
+ repositories.push_back (repository_manifest (p, nv));
+
+ // Manifest for local repository signals the end of the
+ // repository list.
+ //
+ if (repositories.back ().location.empty ())
+ rep = false;
+ }
+ else
+ packages.push_back (package_manifest (p, nv));
+ }
}
void manifests::
serialize (serializer& s) const
{
- for (const manifest& m: *this)
- m.serialize (s);
+ if (repositories.empty () || !repositories.back ().location.empty ())
+ throw serialization (s.name (), "local repository manifest expected");
+
+ for (const repository_manifest& r: repositories)
+ r.serialize (s);
+
+ for (const package_manifest& p: packages)
+ p.serialize (s);
s.next ("", ""); // End of stream.
}
diff --git a/tests/manifest/manifest b/tests/manifest/manifest
index 25491ef..a295dd7 100644
--- a/tests/manifest/manifest
+++ b/tests/manifest/manifest
@@ -1,4 +1,7 @@
: 1
+location: http://pkg.example.org/1/math
+:
+:
name: libfoo
:
name: libbar