diff options
-rw-r--r-- | libbpkg/manifest.cxx | 84 | ||||
-rw-r--r-- | libbpkg/manifest.hxx | 3 | ||||
-rw-r--r-- | tests/manifest/testscript | 102 |
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: |