From fa2704b826f95bc40651da39c3210bf76aeceda4 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 6 Oct 2021 19:07:54 +0300 Subject: Add support for backward compatibility workarounds during package manifest serialization --- libbpkg/manifest.cxx | 46 +++++++++++++++++++++++++++++++++++++--------- libbpkg/manifest.hxx | 29 ++++++++++++++++++++++++----- 2 files changed, 61 insertions(+), 14 deletions(-) diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx index 5638d1b..ef91381 100644 --- a/libbpkg/manifest.cxx +++ b/libbpkg/manifest.cxx @@ -2173,8 +2173,18 @@ namespace bpkg { dependencies.push_back (move (nv)); } - else if (n == "tests" || n == "examples" || n == "benchmarks") + // @@ TMP time to drop *-0.14.0? + // + else if (n == "tests" || n == "tests-0.14.0" || + n == "examples" || n == "examples-0.14.0" || + n == "benchmarks" || n == "benchmarks-0.14.0") { + // Strip the '-0.14.0' suffix from the value name, if present. + // + size_t p (n.find ('-')); + if (p != string::npos) + n.resize (p); + tests.push_back (move (nv)); } else if (n == "location") @@ -2664,9 +2674,11 @@ namespace bpkg } static void - serialize_package_manifest (manifest_serializer& s, - const package_manifest& m, - bool header_only) + serialize_package_manifest ( + manifest_serializer& s, + const package_manifest& m, + bool header_only, + const optional& min_ver = nullopt) { // @@ Should we check that all non-optional values are specified ? // @@ Should we check that values are valid: version release is not empty, @@ -2793,7 +2805,23 @@ namespace bpkg s.next ("requires", r.string ()); for (const test_dependency& t: m.tests) - s.next (to_string (t.type), t.string ()); + { + string n (to_string (t.type)); + + // If we generate the manifest for parsing by clients of libbpkg + // versions less than 0.14.0-, then replace the introduced in 0.14.0 + // build-time tests, examples, and benchmarks values with + // tests-0.14.0, examples-0.14.0, and benchmarks-0.14.0, + // respectively. This way such clients will still be able to parse it, + // ignoring unknown values. + // + // @@ TMP time to drop? + // 0.14.0- + if (t.buildtime && min_ver && min_ver->version < 13999990001ULL) + n += "-0.14.0"; + + s.next (n, t.string ()); + } for (const build_class_expr& e: m.builds) s.next ("builds", serializer::merge_comment (e.string (), e.comment)); @@ -2819,9 +2847,9 @@ namespace bpkg } void package_manifest:: - serialize (serializer& s) const + serialize (serializer& s, const optional& min_ver) const { - serialize_package_manifest (s, *this, false); + serialize_package_manifest (s, *this, false, min_ver); } void package_manifest:: @@ -3035,7 +3063,7 @@ namespace bpkg } void pkg_package_manifests:: - serialize (serializer& s) const + serialize (serializer& s, const optional& min_ver) const { // Serialize the package list manifest. // @@ -3075,7 +3103,7 @@ namespace bpkg if (!p.sha256sum) bad_value ("no valid sha256sum"); - pkg_package_manifest (s, p); + pkg_package_manifest (s, p, min_ver); } s.next ("", ""); // End of stream. diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx index 77043b0..4aa9b73 100644 --- a/libbpkg/manifest.hxx +++ b/libbpkg/manifest.hxx @@ -883,8 +883,19 @@ namespace bpkg validate_overrides (const std::vector&, const std::string& source_name); + // If the minimum libbpkg version is specified, then also apply the + // required backward compatibility workarounds to the serialized manifest + // so that clients of all libbpkg versions greater or equal to the + // specified version can parse it, ignoring unknown values. + // + // Note that clients of the latest major libbpkg version can fully + // recognize the produced manifest and thus can parse it without ignoring + // unknown values. + // void - serialize (butl::manifest_serializer&) const; + serialize ( + butl::manifest_serializer&, + const butl::optional& = butl::nullopt) const; // Serialize only package manifest header values. // @@ -946,10 +957,12 @@ namespace bpkg // Serialize. // inline void - pkg_package_manifest (butl::manifest_serializer& s, - const package_manifest& m) + pkg_package_manifest ( + butl::manifest_serializer& s, + const package_manifest& m, + const butl::optional& min_ver = butl::nullopt) { - m.serialize (s); + m.serialize (s, min_ver); } // Normally there is no need to serialize dir and git package manifests, @@ -978,8 +991,14 @@ namespace bpkg pkg_package_manifests (butl::manifest_parser&, bool ignore_unknown = false); + // If the minimum libbpkg version is specified, then also apply the + // required backward compatibility workarounds to the serialized package + // manifests list (see package_manifest::serialize() for details). + // void - serialize (butl::manifest_serializer&) const; + serialize ( + butl::manifest_serializer&, + const butl::optional& = butl::nullopt) const; }; class LIBBPKG_EXPORT dir_package_manifests: -- cgit v1.1