aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2018-03-08 15:24:30 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2018-03-09 14:52:31 +0300
commit6018f3c1eadd5c60902aa5cf4f926ff17cbaf8ab (patch)
tree129e1c23e97bc7f86858a85cbc431449f799b5d6
parentb2bd3dc5f992b1898061e6836ea2b8b04ec243f1 (diff)
Check parsed package manifests for duplicates
-rw-r--r--libbpkg/manifest.cxx65
-rw-r--r--tests/manifest/driver.cxx42
-rw-r--r--tests/manifest/testscript23
3 files changed, 86 insertions, 44 deletions
diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx
index d6a7a14..89374ff 100644
--- a/libbpkg/manifest.cxx
+++ b/libbpkg/manifest.cxx
@@ -1515,7 +1515,7 @@ namespace bpkg
// Parse package manifests.
//
for (nv = p.next (); !nv.empty (); nv = p.next ())
- push_back (pkg_package_manifest (p, nv, iu));
+ push_back (pkg_package_manifest (p, move (nv), iu));
}
void pkg_package_manifests::
@@ -1558,26 +1558,55 @@ namespace bpkg
s.next ("", ""); // End of stream.
}
+ // Parse package directory manifests.
+ //
+ static void
+ parse_directory_manifests (parser& p, bool iu, vector<package_manifest>& ms)
+ {
+ // Normally, such manifests are created manually, so let's check for
+ // duplicates.
+ //
+ for (name_value nv (p.next ()); !nv.empty (); )
+ {
+ package_manifest pm (dir_package_manifest (p, move (nv), iu));
+ nv = p.next ();
+
+ for (const auto& m: ms)
+ {
+ if (m.location == pm.location)
+ throw parsing (p.name (),
+ nv.name_line, nv.name_column,
+ "duplicate package manifest");
+ }
+
+ ms.push_back (move (pm));
+ }
+ }
+
+ // Serialize package directory manifests.
+ //
+ static void
+ serialize_directory_manifests (serializer& s,
+ const vector<package_manifest>& ms)
+ {
+ for (const package_manifest& m: ms)
+ serialize_directory_manifest (s, m);
+
+ s.next ("", ""); // End of stream.
+ }
+
// dir_package_manifests
//
dir_package_manifests::
dir_package_manifests (parser& p, bool iu)
{
- // Parse package manifests.
- //
- for (name_value nv (p.next ()); !nv.empty (); nv = p.next ())
- push_back (dir_package_manifest (p, nv, iu));
+ parse_directory_manifests (p, iu, *this);
}
void dir_package_manifests::
serialize (serializer& s) const
{
- // Serialize package manifests.
- //
- for (const package_manifest& p: *this)
- dir_package_manifest (s, p);
-
- s.next ("", ""); // End of stream.
+ serialize_directory_manifests (s, *this);
}
// git_package_manifests
@@ -1585,21 +1614,13 @@ namespace bpkg
git_package_manifests::
git_package_manifests (parser& p, bool iu)
{
- // Parse package manifests.
- //
- for (name_value nv (p.next ()); !nv.empty (); nv = p.next ())
- push_back (git_package_manifest (p, nv, iu));
+ parse_directory_manifests (p, iu, *this);
}
void git_package_manifests::
serialize (serializer& s) const
{
- // Serialize package manifests.
- //
- for (const package_manifest& p: *this)
- git_package_manifest (s, p);
-
- s.next ("", ""); // End of stream.
+ serialize_directory_manifests (s, *this);
}
// repository_url_traits
@@ -2705,7 +2726,7 @@ namespace bpkg
name_value nv (p.next ());
while (!nv.empty ())
{
- ms.push_back (parse_repository_manifest (p, nv, base_type, iu));
+ ms.push_back (parse_repository_manifest (p, move (nv), base_type, iu));
nv = p.next ();
// Make sure there is location in all except the last entry.
diff --git a/tests/manifest/driver.cxx b/tests/manifest/driver.cxx
index 5e028bf..62f9d8f 100644
--- a/tests/manifest/driver.cxx
+++ b/tests/manifest/driver.cxx
@@ -41,20 +41,30 @@ main (int argc, char* argv[])
manifest_parser p (cin, "stdin");
manifest_serializer s (cout, "stdout");
- if (opt == "-pp")
- pkg_package_manifests (p).serialize (s);
- else if (opt == "-dp")
- dir_package_manifests (p).serialize (s);
- else if (opt == "-gp")
- git_package_manifests (p).serialize (s);
- else if (opt == "-pr")
- pkg_repository_manifests (p).serialize (s);
- else if (opt == "-dr")
- dir_repository_manifests (p).serialize (s);
- else if (opt == "-gr")
- git_repository_manifests (p).serialize (s);
- else if (opt == "-s")
- signature_manifest (p).serialize (s);
- else
- assert (false);
+ try
+ {
+ if (opt == "-pp")
+ pkg_package_manifests (p).serialize (s);
+ else if (opt == "-dp")
+ dir_package_manifests (p).serialize (s);
+ else if (opt == "-gp")
+ git_package_manifests (p).serialize (s);
+ else if (opt == "-pr")
+ pkg_repository_manifests (p).serialize (s);
+ else if (opt == "-dr")
+ dir_repository_manifests (p).serialize (s);
+ else if (opt == "-gr")
+ git_repository_manifests (p).serialize (s);
+ else if (opt == "-s")
+ signature_manifest (p).serialize (s);
+ else
+ assert (false);
+ }
+ catch (const manifest_parsing& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+
+ return 0;
}
diff --git a/tests/manifest/testscript b/tests/manifest/testscript
index b72f492..59f4db0 100644
--- a/tests/manifest/testscript
+++ b/tests/manifest/testscript
@@ -76,12 +76,18 @@
EOF
}
- : git
+ : dir
:
{
- : manifest
+ : empty
+ :
+ : Roundtrip an empty dir package manifest list.
+ :
+ $* -gp <"" >:""
+
+ : non-empty
:
- : Roundtrip the git package manifest list.
+ : Roundtrip the dir package manifest list.
:
$* -gp <<EOF >>EOF
: 1
@@ -90,11 +96,16 @@
location: mhello/
EOF
- : empty
+ : duplicate
:
- : Roundtrip an empty git package manifest list.
+ $* -gp <<EOI 2>'stdin:5:1: error: duplicate package manifest' != 0
+ : 1
+ location: hello/
:
- $* -gp <"" >:""
+ location: hello/
+ :
+ location: mhello/
+ EOI
}
}