diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2022-10-27 19:11:12 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2022-11-23 19:41:21 +0300 |
commit | 112916e8d7e40af118e58a3ded2825a37d7e8a93 (patch) | |
tree | 764fe6f233f6bafc7f47f8d9417559a4a3c8753d | |
parent | b67a3e4eaa09201a8e22ccfba8fe510568a60e7f (diff) |
Add *-build-config, *-builds, *-build-{include,exclude} package manifest values
-rw-r--r-- | libbpkg/manifest.cxx | 92 | ||||
-rw-r--r-- | libbpkg/manifest.hxx | 70 | ||||
-rw-r--r-- | tests/manifest/testscript | 69 |
3 files changed, 222 insertions, 9 deletions
diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx index 732b689..c362379 100644 --- a/libbpkg/manifest.cxx +++ b/libbpkg/manifest.cxx @@ -3542,6 +3542,27 @@ namespace bpkg } }; + // Return the package build configuration with the specified name, if + // already exists, or the newly created configuration otherwise. + // + auto build_conf = [&m] (string&& nm) -> build_package_config& + { + vector<build_package_config>& cs (m.build_configs); + + auto i (find_if (cs.begin (), cs.end (), + [&nm] (const build_package_config& c) + {return c.name == nm;})); + + if (i != cs.end ()) + return *i; + + // Add the new build configuration (arguments, builds, etc will come + // later). + // + cs.emplace_back (move (nm)); + return cs.back (); + }; + // Cache the upstream version manifest value and validate whether it's // allowed later, after the version value is parsed. // @@ -3862,6 +3883,50 @@ namespace bpkg m.build_constraints.push_back ( parse_build_constraint (nv, true /* exclusion */, name)); } + else if ((n.size () > 13 && + n.compare (n.size () - 13, 13, "-build-config") == 0)) + { + auto vc (parser::split_comment (v)); + + n.resize (n.size () - 13); + + build_package_config& bc (build_conf (move (n))); + + if (!bc.arguments.empty () || !bc.comment.empty ()) + bad_name ("build configuration redefinition"); + + bc.arguments = move (vc.first); + bc.comment = move (vc.second); + } + else if ((n.size () > 7 && n.compare (n.size () - 7, 7, "-builds") == 0)) + { + n.resize (n.size () - 7); + + build_package_config& bc (build_conf (move (n))); + + bc.builds.push_back ( + parse_build_class_expr (nv, bc.builds.empty (), name)); + } + else if ((n.size () > 14 && + n.compare (n.size () - 14, 14, "-build-include") == 0)) + { + n.resize (n.size () - 14); + + build_package_config& bc (build_conf (move (n))); + + bc.constraints.push_back ( + parse_build_constraint (nv, false /* exclusion */, name)); + } + else if ((n.size () > 14 && + n.compare (n.size () - 14, 14, "-build-exclude") == 0)) + { + n.resize (n.size () - 14); + + build_package_config& bc (build_conf (move (n))); + + bc.constraints.push_back ( + parse_build_constraint (nv, true /* exclusion */, name)); + } // @@ TMP time to drop *-0.14.0? // else if (n == "tests" || n == "tests-0.14.0" || @@ -4699,6 +4764,33 @@ namespace bpkg : c.config + '/' + *c.target, c.comment)); + for (const build_package_config& bc: m.build_configs) + { + if (!bc.arguments.empty () || !bc.comment.empty ()) + s.next (bc.name + "-build-config", + serializer::merge_comment (bc.arguments, bc.comment)); + + if (!bc.builds.empty ()) + { + string n (bc.name + "-builds"); + for (const build_class_expr& e: bc.builds) + s.next (n, serializer::merge_comment (e.string (), e.comment)); + } + + if (!bc.constraints.empty ()) + { + string in (bc.name + "-build-include"); + string en (bc.name + "-build-exclude"); + + for (const build_constraint& c: bc.constraints) + s.next (c.exclusion ? en : in, + serializer::merge_comment (!c.target + ? c.config + : c.config + '/' + *c.target, + c.comment)); + } + } + bool an (m.alt_naming && *m.alt_naming); if (m.bootstrap_build) diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx index cad3c1e..ae2051e 100644 --- a/libbpkg/manifest.hxx +++ b/libbpkg/manifest.hxx @@ -776,7 +776,7 @@ namespace bpkg class build_constraint { public: - // If true, then the package should not be built for matching + // If true, then the package should not be built for matching target // configurations by automated build bots. // bool exclusion; @@ -853,7 +853,7 @@ namespace bpkg return x |= y; } - // Build configuration class term. + // Target build configuration class term. // class LIBBPKG_EXPORT build_class_term { @@ -903,8 +903,8 @@ namespace bpkg // using build_class_inheritance_map = std::map<std::string, std::string>; - // Build configuration class expression. Includes comment and optional - // underlying set. + // Target build configuration class expression. Includes comment and + // optional underlying set. // class LIBBPKG_EXPORT build_class_expr { @@ -953,10 +953,10 @@ namespace bpkg std::string string () const; - // Match a build configuration that belongs to the specified list of - // classes (and recursively to their bases) against the expression. Either - // return or update the result (the latter allows to sequentially matching - // against a list of expressions). + // Match a target build configuration that belongs to the specified list + // of classes (and recursively to their bases) against the expression. + // Either return or update the result (the latter allows to sequentially + // matching against a list of expressions). // // Notes: // @@ -964,7 +964,8 @@ namespace bpkg // inheritance cycles, etc.). // // - The underlying class set doesn't affect the match in any way (it - // should have been used to pre-filter the set of build configurations). + // should have been used to pre-filter the set of target build + // configurations). // void match (const strings&, @@ -986,6 +987,52 @@ namespace bpkg return os << bce.string (); } + // Package build configuration. Includes comment and optional target build + // configuration class expressions/constraints overrides. + // + class build_package_config + { + public: + std::string name; + + // Whitespace separated list of potentially double/single-quoted package + // configuration arguments for bpkg-pkg-build command executed by + // automated build bots. + // + std::string arguments; + + std::string comment; + + butl::small_vector<build_class_expr, 1> builds; + std::vector<build_constraint> constraints; + + build_package_config () = default; + + // Built incrementally. + // + explicit + build_package_config (std::string n): name (move (n)) {} + + // Return the configuration's build class expressions/constraints if they + // override the specified common expressions/constraints and return the + // latter otherwise (see package_manifest::override() for the override + // semantics details). + // + const butl::small_vector<build_class_expr, 1>& + effective_builds (const butl::small_vector<build_class_expr, 1>& common) + const noexcept + { + return !builds.empty () ? builds : common; + } + + const std::vector<build_constraint>& + effective_constraints (const std::vector<build_constraint>& common) const + noexcept + { + return !builds.empty () || !constraints.empty () ? constraints : common; + } + }; + enum class text_type { plain, @@ -1116,9 +1163,14 @@ namespace bpkg std::vector<requirement_alternatives> requirements; butl::small_vector<test_dependency, 1> tests; + // Common build classes/constraints that apply to all configurations + // unless overridden. + // butl::small_vector<build_class_expr, 1> builds; std::vector<build_constraint> build_constraints; + std::vector<build_package_config> build_configs; + // If true, then this package use the alternative buildfile naming scheme // (build2/, .build2). In the manifest serialization this is encoded as // either *-build or *-build2 value names. diff --git a/tests/manifest/testscript b/tests/manifest/testscript index 440e61f..336b288 100644 --- a/tests/manifest/testscript +++ b/tests/manifest/testscript @@ -541,6 +541,71 @@ EOI } + : build-config + : + { + : multiple + : + { + $* <<EOF >>EOF + : 1 + name: foo + version: 2.0.0 + summary: Modern C++ parser + license: LGPLv2 + bar-build-config: config.foo.bar = true; Bar. + bar-builds: all + baz-build-config: config.foo.baz = true; Baz. + EOF + } + + : empty + : + $* <<EOF >>EOF + : 1 + name: foo + version: 2.0.0 + summary: Modern C++ parser + license: LGPLv2 + network-build-config: ; None. + EOF + + : undefined + : + { + $* <<EOF >>EOF + : 1 + name: foo + version: 2.0.0 + summary: Modern C++ parser + license: LGPLv2 + bar-builds: default + baz-build-config: config.foo.bar = true + EOF + } + + : redefinition + : + { + $* <<EOI 2>"stdin:3:1: error: build configuration redefinition" != 0 + : 1 + bar-build-config: config.foo.bar = true + bar-build-config: config.foo.bar = true + EOI + } + + : unexpected-underlying-class-set + : + { + $* <<EOI 2>"stdin:4:13: error: invalid package builds: unexpected underlying class set" != 0 + : 1 + bar-build-config: config.foo.bar = true + bar-builds: all + bar-builds: all + EOI + } + } + : depends : { @@ -3773,6 +3838,10 @@ build-include: linux* build-include: freebsd* build-exclude: *; Only supports Linux and FreeBSD. + network-build-config: config.libfoo.network=true; Enable networking API. + network-builds: default + network-build-include: linux* + network-build-exclude: *; Only supports Linux. bootstrap-build:\ project = libfoo |