aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2019-06-03 20:04:29 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2019-06-04 14:39:12 +0300
commita41a4869e74e5f7fc4ed9797661b1d450b1ce97a (patch)
tree73fc29cc05eafcd6e0b45c2339c3b77fad5f1b1f
parentffe601f862ce3267b933d9684d6a42fd232201ab (diff)
Add support for topics and keywords package manifest values
-rw-r--r--libbpkg/manifest.cxx84
-rw-r--r--libbpkg/manifest.hxx3
-rw-r--r--tests/manifest/testscript102
3 files changed, 170 insertions, 19 deletions
diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx
index 7e6e6d7..e27af54 100644
--- a/libbpkg/manifest.cxx
+++ b/libbpkg/manifest.cxx
@@ -1660,6 +1660,45 @@ namespace bpkg
return r;
};
+ // Parse a string list (topics, keywords, etc). If the list length exceeds
+ // five entries, then truncate it if the truncate flag is set and throw
+ // manifest_parsing otherwise.
+ //
+ auto parse_list = [&bad_name, &bad_value] (const string& v,
+ strings& r,
+ char delim,
+ bool single_word,
+ bool truncate,
+ const char* what)
+ {
+ if (!r.empty ())
+ bad_name (string ("package ") + what + " redefinition");
+
+ // Note that we parse the whole list to validate the entries.
+ //
+ list_parser lp (v.begin (), v.end (), delim);
+ for (string lv (lp.next ()); !lv.empty (); lv = lp.next ())
+ {
+ if (single_word && lv.find_first_of (spaces) != string::npos)
+ bad_value (string ("only single-word ") + what + " allowed");
+
+ r.push_back (move (lv));
+ }
+
+ if (r.empty ())
+ bad_value (string ("empty package ") + what + " specification");
+
+ // If the list length limit is exceeded then truncate it or throw.
+ //
+ if (r.size () > 5)
+ {
+ if (truncate)
+ r.resize (5);
+ else
+ bad_value (string ("up to five ") + what + " allowed");
+ }
+ };
+
auto flag = [fl] (package_manifest_flags f)
{
return (fl & f) != package_manifest_flags::none;
@@ -1773,22 +1812,32 @@ namespace bpkg
m.summary = move (v);
}
+ else if (n == "topics")
+ {
+ parse_list (v,
+ m.topics,
+ ',' /* delim */,
+ false /* single_word */,
+ false /* truncate */,
+ "topics");
+ }
+ else if (n == "keywords")
+ {
+ parse_list (v,
+ m.keywords,
+ ' ' /* delim */,
+ true /* single_word */,
+ false /* truncate */,
+ "keywords");
+ }
else if (n == "tags")
{
- if (!m.tags.empty ())
- bad_name ("package tags redefinition");
-
- list_parser lp (v.begin (), v.end ());
- for (string lv (lp.next ()); !lv.empty (); lv = lp.next ())
- {
- if (lv.find_first_of (spaces) != string::npos)
- bad_value ("only single-word tags allowed");
-
- m.tags.push_back (move (lv));
- }
-
- if (m.tags.empty ())
- bad_value ("empty package tags specification");
+ parse_list (v,
+ m.keywords,
+ ',' /* delim */,
+ true /* single_word */,
+ true /* truncate */,
+ "tags");
}
else if (n == "description")
{
@@ -2514,8 +2563,11 @@ namespace bpkg
if (!header_only)
{
- if (!m.tags.empty ())
- s.next ("tags", concatenate (m.tags));
+ if (!m.topics.empty ())
+ s.next ("topics", concatenate (m.topics));
+
+ if (!m.keywords.empty ())
+ s.next ("keywords", concatenate (m.keywords, " "));
if (m.description)
{
diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx
index 01ffa49..9493ee0 100644
--- a/libbpkg/manifest.hxx
+++ b/libbpkg/manifest.hxx
@@ -645,7 +645,8 @@ namespace bpkg
butl::optional<priority_type> priority;
std::string summary;
std::vector<licenses> license_alternatives;
- strings tags;
+ strings topics;
+ strings keywords;
butl::optional<text_file> description;
butl::optional<std::string> description_type;
std::vector<text_file> changes;
diff --git a/tests/manifest/testscript b/tests/manifest/testscript
index e7a6af6..9406a2a 100644
--- a/tests/manifest/testscript
+++ b/tests/manifest/testscript
@@ -551,6 +551,104 @@
stdin:4:1: error: upstream package version specified for a stub
EOE
}
+
+ : keywords
+ :
+ {
+ : valid
+ :
+ $* <<EOF >>EOF
+ : 1
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ keywords: c++ library lib foo libfoo
+ EOF
+
+ : redefinition
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ keywords: c++ library lib foo libfoo
+ keywords: c++ library lib foo libfoo
+ EOI
+ stdin:3:1: error: package keywords redefinition
+ EOE
+
+ : too-many
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ keywords: c++ library lib foo libfoo libbar
+ EOI
+ stdin:2:11: error: up to five keywords allowed
+ EOE
+
+ : empty
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ keywords:
+ EOI
+ stdin:2:10: error: empty package keywords specification
+ EOE
+ }
+
+ : tags
+ :
+ {
+ : truncate
+ :
+ $* <<EOI >>EOO
+ : 1
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ tags: c++, library, lib, foo, libfoo, libbar
+ EOI
+ : 1
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ keywords: c++ library lib foo libfoo
+ EOO
+
+ : with-space
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ tags: c++ library, lib, foo, libfoo
+ EOI
+ stdin:2:7: error: only single-word tags allowed
+ EOE
+ }
+
+ : topics
+ :
+ {
+ : valid
+ :
+ $* <<EOF >>EOF
+ : 1
+ name: libfoo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ topics: c++ library, foo library, libfoo
+ EOF
+
+ : too-many
+ :
+ $* <<EOI 2>>EOE != 0
+ : 1
+ topics: c++, library, lib, foo, libfoo, libbar
+ EOI
+ stdin:2:9: error: up to five topics allowed
+ EOE
+ }
}
: manifest-list
@@ -568,7 +666,7 @@
summary: Modern XML parser
license: LGPLv2, MIT; Both required.
license: BSD
- tags: c++, xml, parser, serializer, pull, streaming, modern
+ keywords: c++ xml parser serializer pull
description: libfoo is a very modern C++ XML parser.
description-type: text/plain
changes: 1.2.3+2: applied upstream patch for critical bug bar
@@ -605,7 +703,7 @@
version: 3.4A.5+6
summary: Modern bar management framework
license: LGPLv2
- tags: c++, xml, modern
+ keywords: c++, xml, modern
url: http://www.example.org/projects/libbar/
email: libbar-users@example.org
build-email: