diff options
Diffstat (limited to 'libbpkg/manifest.cxx')
-rw-r--r-- | libbpkg/manifest.cxx | 205 |
1 files changed, 191 insertions, 14 deletions
diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx index 923b113..065f055 100644 --- a/libbpkg/manifest.cxx +++ b/libbpkg/manifest.cxx @@ -3069,6 +3069,44 @@ namespace bpkg match_classes (cs, im, expr, r); } + // build_auxiliary + // + optional<pair<string, string>> build_auxiliary:: + parse_value_name (const string& n) + { + // Check if the value name matches exactly. + // + if (n == "build-auxiliary") + return make_pair (string (), string ()); + + // Check if this is a *-build-auxiliary name. + // + if (n.size () > 16 && + n.compare (n.size () - 16, 16, "-build-auxiliary") == 0) + { + return make_pair (string (n, 0, n.size () - 16), string ()); + } + + // Check if this is a build-auxiliary-* name. + // + if (n.size () > 16 && n.compare (0, 16, "build-auxiliary-") == 0) + return make_pair (string (), string (n, 16)); + + // Check if this is a *-build-auxiliary-* name. + // + size_t p (n.find ("-build-auxiliary-")); + + if (p != string::npos && + p != 0 && // Not '-build-auxiliary-*'? + p + 17 != n.size () && // Not '*-build-auxiliary-'? + n.find ("-build-auxiliary-", p + 17) == string::npos) // Unambiguous? + { + return make_pair (string (n, 0, p), string (n, p + 17)); + } + + return nullopt; + } + // test_dependency_type // string @@ -3318,6 +3356,33 @@ namespace bpkg return email (move (v), move (c)); } + // Parse the [*-]build-auxiliary[-*] manifest value. + // + // Note that the environment name is expected to already be retrieved using + // build_auxiliary::parse_value_name(). + // + static build_auxiliary + parse_build_auxiliary (const name_value& nv, + string&& env_name, + const string& source_name) + { + auto bad_value = [&nv, &source_name] (const string& d) + { + throw !source_name.empty () + ? parsing (source_name, nv.value_line, nv.value_column, d) + : parsing (d); + }; + + pair<string, string> vc (parser::split_comment (nv.value)); + string& v (vc.first); + string& c (vc.second); + + if (v.empty ()) + bad_value ("empty build auxiliary configuration name pattern"); + + return build_auxiliary (move (env_name), move (v), move (c)); + } + const version stub_version (0, "0", nullopt, nullopt, 0); // Parse until next() returns end-of-manifest value. @@ -3340,16 +3405,37 @@ namespace bpkg auto bad_value ([&name, &nv](const string& d) { throw parsing (name, nv.value_line, nv.value_column, d);}); - auto parse_email = [&bad_name] (const name_value& nv, - optional<email>& r, - const char* what, - const string& source_name, - bool empty = false) + auto parse_email = [&bad_name, &name] (const name_value& nv, + optional<email>& r, + const char* what, + bool empty = false) { if (r) bad_name (what + string (" email redefinition")); - r = bpkg::parse_email (nv, what, source_name, empty); + r = bpkg::parse_email (nv, what, name, empty); + }; + + // Parse the [*-]build-auxiliary[-*] manifest value and append it to the + // specified build auxiliary list. Make sure that the list contains not + // more than one entry with unspecified environment name and throw parsing + // if that's not the case. Also make sure that there are no entry + // redefinitions (multiple entries with the same environment name). + // + auto parse_build_auxiliary = [&bad_name, &name] (const name_value& nv, + string&& en, + vector<build_auxiliary>& r) + { + build_auxiliary a (bpkg::parse_build_auxiliary (nv, move (en), name)); + + if (find_if (r.begin (), r.end (), + [&a] (const build_auxiliary& ba) + { + return ba.environment_name == a.environment_name; + }) != r.end ()) + bad_name ("build auxiliary environment redefinition"); + + r.push_back (move (a)); }; auto parse_url = [&bad_value] (const string& v, @@ -3908,7 +3994,7 @@ namespace bpkg } else if (n == "email") { - parse_email (nv, m.email, "project", name); + parse_email (nv, m.email, "project"); } else if (n == "doc-url") { @@ -3933,19 +4019,19 @@ namespace bpkg } else if (n == "package-email") { - parse_email (nv, m.package_email, "package", name); + parse_email (nv, m.package_email, "package"); } else if (n == "build-email") { - parse_email (nv, m.build_email, "build", name, true /* empty */); + parse_email (nv, m.build_email, "build", true /* empty */); } else if (n == "build-warning-email") { - parse_email (nv, m.build_warning_email, "build warning", name); + parse_email (nv, m.build_warning_email, "build warning"); } else if (n == "build-error-email") { - parse_email (nv, m.build_error_email, "build error", name); + parse_email (nv, m.build_error_email, "build error"); } else if (n == "priority") { @@ -4019,6 +4105,19 @@ namespace bpkg m.build_constraints.push_back ( parse_build_constraint (nv, true /* exclusion */, name)); } + else if (optional<pair<string, string>> ba = + build_auxiliary::parse_value_name (n)) + { + if (ba->first.empty ()) // build-auxiliary*? + { + parse_build_auxiliary (nv, move (ba->second), m.build_auxiliaries); + } + else // *-build-auxiliary* + { + build_package_config& bc (build_conf (move (ba->first))); + parse_build_auxiliary (nv, move (ba->second), bc.auxiliaries); + } + } else if (n.size () > 13 && n.compare (n.size () - 13, 13, "-build-config") == 0) { @@ -4440,8 +4539,7 @@ namespace bpkg // Note: the argument can only be one of the build_config_*emails // variables (see above) to distinguish between the email kinds. // - auto parse_build_config_emails = [&name, - &nv, + auto parse_build_config_emails = [&nv, &build_config_emails, &build_config_warning_emails, &build_config_error_emails, @@ -4479,7 +4577,6 @@ namespace bpkg (ek == email_kind::build ? "build configuration" : ek == email_kind::warning ? "build configuration warning" : "build configuration error"), - name, ek == email_kind::build /* empty */); } }; @@ -4829,6 +4926,15 @@ namespace bpkg // vector<size_t> obes; + // Return true if the specified package build configuration is newly + // created by the *-build-config override. + // + auto config_created = [&m, confs_num = m.build_configs.size ()] + (const build_package_config& c) + { + return &c >= m.build_configs.data () + confs_num; + }; + // Apply overrides. // for (const manifest_name_value& nv: nvs) @@ -5050,6 +5156,45 @@ namespace bpkg return r; }; + // Parse the [*-]build-auxiliary[-*] value override. If the mode is not + // validate-only, then override the matching value and throw + // manifest_parsing if no match. But throw only unless this is a + // configuration-specific override (build_config is not NULL) for a + // newly created configuration, in which case add the value instead. + // + auto override_build_auxiliary = + [&bad_name, + &name, + &config_created, + validate_only] (const name_value& nv, + string&& en, + vector<build_auxiliary>& r, + build_package_config* build_config = nullptr) + { + build_auxiliary a (bpkg::parse_build_auxiliary (nv, move (en), name)); + + if (!validate_only) + { + auto i (find_if (r.begin (), r.end (), + [&a] (const build_auxiliary& ba) + { + return ba.environment_name == a.environment_name; + })); + + if (i != r.end ()) + { + *i = move (a); + } + else + { + if (build_config != nullptr && config_created (*build_config)) + r.emplace_back (move (a)); + else + bad_name ("no match for '" + nv.name + "' value override"); + } + } + }; + const string& n (nv.name); if (n == "builds") @@ -5145,6 +5290,21 @@ namespace bpkg bc.error_email = parse_email (nv, "build configuration error", name); } + else if (optional<pair<string, string>> ba = + build_auxiliary::parse_value_name (n)) + { + if (ba->first.empty ()) // build-auxiliary*? + { + override_build_auxiliary (nv, move (ba->second), m.build_auxiliaries); + } + else // *-build-auxiliary* + { + build_package_config& bc ( + build_conf (ba->first.size (), validate_only)); + + override_build_auxiliary (nv, move (ba->second), bc.auxiliaries, &bc); + } + } else bad_name ("cannot override '" + n + "' value"); } @@ -5516,6 +5676,12 @@ namespace bpkg : c.config + '/' + *c.target, c.comment)); + for (const build_auxiliary& ba: m.build_auxiliaries) + s.next ((!ba.environment_name.empty () + ? "build-auxiliary-" + ba.environment_name + : "build-auxiliary"), + serializer::merge_comment (ba.config, ba.comment)); + for (const build_package_config& bc: m.build_configs) { if (!bc.builds.empty ()) @@ -5538,6 +5704,17 @@ namespace bpkg c.comment)); } + if (!bc.auxiliaries.empty ()) + { + string n (bc.name + "-build-auxiliary"); + + for (const build_auxiliary& ba: bc.auxiliaries) + s.next ((!ba.environment_name.empty () + ? n + '-' + ba.environment_name + : n), + serializer::merge_comment (ba.config, ba.comment)); + } + if (!bc.arguments.empty () || !bc.comment.empty ()) s.next (bc.name + "-build-config", serializer::merge_comment (bc.arguments, bc.comment)); |