diff options
Diffstat (limited to 'bpkg')
-rw-r--r-- | bpkg/manifest | 25 | ||||
-rw-r--r-- | bpkg/manifest.cxx | 102 |
2 files changed, 111 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. } |