From 03c931e54e618221b69cfcd3dfb462e50ecad780 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 28 Oct 2022 23:21:29 +0300 Subject: Add support for package build configurations --- libbrep/build-extra.sql | 52 +++++++++++++++++- libbrep/build-package.hxx | 44 +++++++++++---- libbrep/build.cxx | 18 ++++--- libbrep/build.hxx | 83 ++++++++++++++++------------ libbrep/build.xml | 26 +++++---- libbrep/common.cxx | 10 ++++ libbrep/common.hxx | 104 +++++++++++++++++++++++++++++++++++ libbrep/package.cxx | 19 +++++++ libbrep/package.hxx | 50 ++++++++++++++--- libbrep/package.xml | 134 ++++++++++++++++++++++++++++++++++++++++++++++ libbrep/utility.hxx | 11 ++-- 11 files changed, 478 insertions(+), 73 deletions(-) (limited to 'libbrep') diff --git a/libbrep/build-extra.sql b/libbrep/build-extra.sql index 2c204e6..7331ab1 100644 --- a/libbrep/build-extra.sql +++ b/libbrep/build-extra.sql @@ -6,6 +6,12 @@ -- package-extra.sql file for details. -- +DROP FOREIGN TABLE IF EXISTS build_package_config_constraints; + +DROP FOREIGN TABLE IF EXISTS build_package_config_builds; + +DROP FOREIGN TABLE IF EXISTS build_package_configs; + DROP FOREIGN TABLE IF EXISTS build_package_constraints; DROP FOREIGN TABLE IF EXISTS build_package_builds; @@ -60,7 +66,7 @@ CREATE FOREIGN TABLE build_package ( SERVER package_server OPTIONS (table_name 'package'); -- The foreign tables for the build_package object requirements member (that --- is of a 2-dimensional container type). +-- is of a 3-dimensional container type). -- CREATE FOREIGN TABLE build_package_requirements ( tenant TEXT NOT NULL, @@ -168,3 +174,47 @@ CREATE FOREIGN TABLE build_package_constraints ( target TEXT NULL, comment TEXT NOT NULL) SERVER package_server OPTIONS (table_name 'package_build_constraints'); + +-- The foreign tables for the build_package object configs member (that is a +-- container of values containing containers. +-- +CREATE FOREIGN TABLE build_package_configs ( + tenant TEXT NOT NULL, + name CITEXT NOT NULL, + version_epoch INTEGER NOT NULL, + version_canonical_upstream TEXT NOT NULL, + version_canonical_release TEXT NOT NULL COLLATE "C", + version_revision INTEGER NOT NULL, + index BIGINT NOT NULL, + config_name TEXT NOT NULL, + config_arguments TEXT NULL, + config_comment TEXT NOT NULL) +SERVER package_server OPTIONS (table_name 'package_build_configs'); + +CREATE FOREIGN TABLE build_package_config_builds ( + tenant TEXT NOT NULL, + name CITEXT NOT NULL, + version_epoch INTEGER NOT NULL, + version_canonical_upstream TEXT NOT NULL, + version_canonical_release TEXT NOT NULL COLLATE "C", + version_revision INTEGER NOT NULL, + config_index BIGINT NOT NULL, + index BIGINT NOT NULL, + expression TEXT NOT NULL, + comment TEXT NOT NULL) +SERVER package_server OPTIONS (table_name 'package_build_config_builds'); + +CREATE FOREIGN TABLE build_package_config_constraints ( + tenant TEXT NOT NULL, + name CITEXT NOT NULL, + version_epoch INTEGER NOT NULL, + version_canonical_upstream TEXT NOT NULL, + version_canonical_release TEXT NOT NULL COLLATE "C", + version_revision INTEGER NOT NULL, + config_index BIGINT NOT NULL, + index BIGINT NOT NULL, + exclusion BOOLEAN NOT NULL, + config TEXT NOT NULL, + target TEXT NULL, + comment TEXT NOT NULL) +SERVER package_server OPTIONS (table_name 'package_build_config_constraints'); diff --git a/libbrep/build-package.hxx b/libbrep/build-package.hxx index 54edc2b..79fb6a4 100644 --- a/libbrep/build-package.hxx +++ b/libbrep/build-package.hxx @@ -120,11 +120,12 @@ namespace brep lazy_shared_ptr internal_repository; bool buildable; - // Mapped to the package object builds and build_constraints members using - // the PostgreSQL foreign table mechanism. + // Mapped to the package object builds, build_constraints, and + // build_configs members using the PostgreSQL foreign table mechanism. // - build_class_exprs builds; - build_constraints constraints; + build_class_exprs builds; + build_constraints constraints; + build_package_configs configs; bool internal () const noexcept {return internal_repository != nullptr;} @@ -146,9 +147,6 @@ namespace brep // Container of the requirement_alternative values. // - #pragma db member(requirement_alternative_key::outer) column("requirement_index") - #pragma db member(requirement_alternative_key::inner) column("index") - #pragma db member(requirement_alternatives) \ virtual(requirement_alternatives_map) \ after(requirements) \ @@ -158,10 +156,6 @@ namespace brep // Container of the requirement (string) values. // - #pragma db member(requirement_key::outer) column("requirement_index") - #pragma db member(requirement_key::middle) column("alternative_index") - #pragma db member(requirement_key::inner) column("index") - #pragma db member(requirement_alternative_requirements) \ virtual(requirement_alternative_requirements_map) \ after(requirement_alternatives) \ @@ -175,6 +169,34 @@ namespace brep #pragma db member(builds) id_column("") value_column("") #pragma db member(constraints) id_column("") value_column("") + // configs + // + // Note that build_package_config::{builds,constraints} are + // persisted/loaded via the separate nested containers (see commons.hxx + // for details). + // + #pragma db member(configs) id_column("") value_column("config_") + + #pragma db member(config_builds) \ + virtual(build_class_exprs_map) \ + after(configs) \ + get(odb::nested_get ( \ + brep::build_package_config_builds (this.configs))) \ + set(brep::build_package_config_builds bs; \ + odb::nested_set (bs, std::move (?)); \ + move (bs).to_configs (this.configs)) \ + id_column("") key_column("") value_column("") + + #pragma db member(config_constraints) \ + virtual(build_constraints_map) \ + after(config_builds) \ + get(odb::nested_get ( \ + brep::build_package_config_constraints (this.configs))) \ + set(brep::build_package_config_constraints cs; \ + odb::nested_set (cs, std::move (?)); \ + move (cs).to_configs (this.configs)) \ + id_column("") key_column("") value_column("") + private: friend class odb::access; build_package () = default; diff --git a/libbrep/build.cxx b/libbrep/build.cxx index c095b32..c8a2cd1 100644 --- a/libbrep/build.cxx +++ b/libbrep/build.cxx @@ -57,8 +57,9 @@ namespace brep build (string tnt, package_name_type pnm, version pvr, - string cfg, target_triplet trg, + string tcf, + string pcf, string tnm, version tvr, optional inr, optional afp, optional ach, @@ -66,14 +67,16 @@ namespace brep string ccs, string mcs) : id (package_id (move (tnt), move (pnm), pvr), - move (cfg), move (trg), + move (tcf), + move (pcf), move (tnm), tvr), tenant (id.package.tenant), package_name (id.package.name), package_version (move (pvr)), - configuration (id.configuration), target (id.target), + target_config_name (id.target_config_name), + package_config_name (id.package_config_name), toolchain_name (id.toolchain_name), toolchain_version (move (tvr)), state (build_state::building), @@ -93,19 +96,22 @@ namespace brep build_delay:: build_delay (string tnt, package_name_type pnm, version pvr, - string cfg, target_triplet trg, + string tcf, + string pcf, string tnm, version tvr, timestamp ptm) : id (package_id (move (tnt), move (pnm), pvr), - move (cfg), move (trg), + move (tcf), + move (pcf), move (tnm), tvr), tenant (id.package.tenant), package_name (id.package.name), package_version (move (pvr)), - configuration (id.configuration), target (id.target), + target_config_name (id.target_config_name), + package_config_name (id.package_config_name), toolchain_name (id.toolchain_name), toolchain_version (move (tvr)), package_timestamp (ptm) diff --git a/libbrep/build.hxx b/libbrep/build.hxx index ceea81a..dfd0e55 100644 --- a/libbrep/build.hxx +++ b/libbrep/build.hxx @@ -26,9 +26,9 @@ // Used by the data migration entries. // -#define LIBBREP_BUILD_SCHEMA_VERSION_BASE 19 +#define LIBBREP_BUILD_SCHEMA_VERSION_BASE 20 -#pragma db model version(LIBBREP_BUILD_SCHEMA_VERSION_BASE, 19, closed) +#pragma db model version(LIBBREP_BUILD_SCHEMA_VERSION_BASE, 20, closed) // We have to keep these mappings at the global scope instead of inside the // brep namespace because they need to be also effective in the bbot namespace @@ -44,20 +44,23 @@ namespace brep struct build_id { package_id package; - string configuration; target_triplet target; + string target_config_name; + string package_config_name; string toolchain_name; canonical_version toolchain_version; build_id () = default; build_id (package_id p, - string c, target_triplet t, + string tc, + string pc, string n, const brep::version& v) : package (move (p)), - configuration (move (c)), target (move (t)), + target_config_name (move (tc)), + package_config_name (move (pc)), toolchain_name (move (n)), toolchain_version (v) {} }; @@ -68,10 +71,13 @@ namespace brep if (x.package != y.package) return x.package < y.package; - if (int r = x.configuration.compare (y.configuration)) + if (int r = x.target.compare (y.target)) return r < 0; - if (int r = x.target.compare (y.target)) + if (int r = x.target_config_name.compare (y.target_config_name)) + return r < 0; + + if (int r = x.package_config_name.compare (y.package_config_name)) return r < 0; if (int r = x.toolchain_name.compare (y.toolchain_name)) @@ -88,32 +94,36 @@ namespace brep template inline auto operator== (const T& x, const build_id& y) - -> decltype (x.package == y.package && - x.configuration == y.configuration && - x.target == y.target && - x.toolchain_name == y.toolchain_name && + -> decltype (x.package == y.package && + x.target == y.target && + x.target_config_name == y.target_config_name && + x.package_config_name == y.package_config_name && + x.toolchain_name == y.toolchain_name && x.toolchain_version.epoch == y.toolchain_version.epoch) { - return x.package == y.package && - x.configuration == y.configuration && - x.target == y.target && - x.toolchain_name == y.toolchain_name && + return x.package == y.package && + x.target == y.target && + x.target_config_name == y.target_config_name && + x.package_config_name == y.package_config_name && + x.toolchain_name == y.toolchain_name && compare_version_eq (x.toolchain_version, y.toolchain_version, true); } template inline auto operator!= (const T& x, const build_id& y) - -> decltype (x.package == y.package && - x.configuration == y.configuration && - x.target == y.target && - x.toolchain_name == y.toolchain_name && + -> decltype (x.package == y.package && + x.target == y.target && + x.target_config_name == y.target_config_name && + x.package_config_name == y.package_config_name && + x.toolchain_name == y.toolchain_name && x.toolchain_version.epoch == y.toolchain_version.epoch) { - return x.package != y.package || - x.configuration != y.configuration || - x.target == y.target || - x.toolchain_name != y.toolchain_name || + return x.package != y.package || + x.target != y.target || + x.target_config_name != y.target_config_name || + x.package_config_name != y.package_config_name || + x.toolchain_name != y.toolchain_name || compare_version_ne (x.toolchain_version, y.toolchain_version, true); } @@ -190,10 +200,10 @@ namespace brep // the timestamp set to now, and the force state set to unforced. // build (string tenant, - package_name_type, - version, - string configuration, + package_name_type, version, target_triplet, + string target_config_name, + string package_config_name, string toolchain_name, version toolchain_version, optional interactive, optional agent_fingerprint, @@ -207,8 +217,9 @@ namespace brep string& tenant; // Tracks id.package.tenant. package_name_type& package_name; // Tracks id.package.name. upstream_version package_version; // Original of id.package.version. - string& configuration; // Tracks id.configuration. target_triplet& target; // Tracks id.target. + string& target_config_name; // Tracks id.target_config_name. + string& package_config_name; // Tracks id.package_config_name. string& toolchain_name; // Tracks id.toolchain_name. upstream_version toolchain_version; // Original of id.toolchain_version. @@ -288,8 +299,9 @@ namespace brep #pragma db member(package_name) transient #pragma db member(package_version) \ set(this.package_version.init (this.id.package.version, (?))) - #pragma db member(configuration) transient #pragma db member(target) transient + #pragma db member(target_config_name) transient + #pragma db member(package_config_name) transient #pragma db member(toolchain_name) transient #pragma db member(toolchain_version) \ set(this.toolchain_version.init (this.id.toolchain_version, (?))) @@ -312,8 +324,9 @@ namespace brep build () : tenant (id.package.tenant), package_name (id.package.name), - configuration (id.configuration), target (id.target), + target_config_name (id.target_config_name), + package_config_name (id.package_config_name), toolchain_name (id.toolchain_name) {} }; @@ -408,8 +421,9 @@ namespace brep // build_delay (string tenant, package_name_type, version, - string configuration, target_triplet, + string target_config_name, + string package_config_name, string toolchain_name, version toolchain_version, timestamp package_timestamp); @@ -418,8 +432,9 @@ namespace brep string& tenant; // Tracks id.package.tenant. package_name_type& package_name; // Tracks id.package.name. upstream_version package_version; // Original of id.package.version. - string& configuration; // Tracks id.configuration. target_triplet& target; // Tracks id.target. + string& target_config_name; // Tracks id.target_config_name. + string& package_config_name; // Tracks id.package_config_name. string& toolchain_name; // Tracks id.toolchain_name. upstream_version toolchain_version; // Original of id.toolchain_version. @@ -447,8 +462,9 @@ namespace brep #pragma db member(package_name) transient #pragma db member(package_version) \ set(this.package_version.init (this.id.package.version, (?))) - #pragma db member(configuration) transient #pragma db member(target) transient + #pragma db member(target_config_name) transient + #pragma db member(package_config_name) transient #pragma db member(toolchain_name) transient #pragma db member(toolchain_version) \ set(this.toolchain_version.init (this.id.toolchain_version, (?))) @@ -459,8 +475,9 @@ namespace brep build_delay () : tenant (id.package.tenant), package_name (id.package.name), - configuration (id.configuration), target (id.target), + target_config_name (id.target_config_name), + package_config_name (id.package_config_name), toolchain_name (id.toolchain_name) {} }; } diff --git a/libbrep/build.xml b/libbrep/build.xml index 7fe936d..d1969f1 100644 --- a/libbrep/build.xml +++ b/libbrep/build.xml @@ -1,5 +1,5 @@ - + @@ -7,8 +7,9 @@ - + + @@ -41,8 +42,9 @@ - + + @@ -60,8 +62,9 @@ - + + @@ -78,8 +81,9 @@ - + + @@ -92,8 +96,9 @@ - + + @@ -108,8 +113,9 @@ - + + @@ -127,8 +133,9 @@ - + + @@ -148,8 +155,9 @@ - + + diff --git a/libbrep/common.cxx b/libbrep/common.cxx index 4f729a3..c97a346 100644 --- a/libbrep/common.cxx +++ b/libbrep/common.cxx @@ -32,4 +32,14 @@ namespace brep else if (r == "unbuildable") return unbuildable_reason::unbuildable; else throw invalid_argument ("invalid unbuildable reason '" + r + '\''); } + + build_package_config* + find (const string& name, build_package_configs& cs) + { + auto i (find_if (cs.begin (), cs.end (), + [&name] (const build_package_config& c) + {return c.name == name;})); + + return i != cs.end () ? &*i : nullptr; + } } diff --git a/libbrep/common.hxx b/libbrep/common.hxx index af34f6c..158690e 100644 --- a/libbrep/common.hxx +++ b/libbrep/common.hxx @@ -4,6 +4,7 @@ #ifndef LIBBREP_COMMON_HXX #define LIBBREP_COMMON_HXX +#include #include #include #include // static_assert @@ -332,6 +333,104 @@ namespace brep #pragma db value(build_constraint) definition + // build_package_config + // + using build_package_config = bpkg::build_package_config; + + #pragma db value(build_package_config) definition + + // 1 for the default configuration which is always present. + // + using build_package_configs = small_vector; + + // Return the address of the configuration object with the specified name, + // if present, and NULL otherwise. + // + build_package_config* + find (const string& name, build_package_configs&); + + // Note that ODB doesn't support containers of value types which contain + // containers. Thus, we will persist/load + // package_build_config::{builds,constraint} via the separate nested + // containers using the adapter classes. + // + #pragma db member(build_package_config::builds) transient + #pragma db member(build_package_config::constraints) transient + + using build_class_expr_key = odb::nested_key; + using build_class_exprs_map = std::map; + + #pragma db value(build_class_expr_key) + #pragma db member(build_class_expr_key::outer) column("config_index") + #pragma db member(build_class_expr_key::inner) column("index") + + // Adapter for build_package_config::builds. + // + class build_package_config_builds: + public small_vector // 1 as for build_package_configs. + { + public: + build_package_config_builds () = default; + + explicit + build_package_config_builds (const build_package_configs& cs) + { + reserve (cs.size ()); + for (const build_package_config& c: cs) + push_back (c.builds); + } + + void + to_configs (build_package_configs& cs) && + { + // Note that the empty trailing entries will be missing (see ODB's + // nested-container.hxx for details). + // + assert (size () <= cs.size ()); + + auto i (cs.begin ()); + for (build_class_exprs& ces: *this) + i++->builds = move (ces); + } + }; + + using build_constraint_key = odb::nested_key; + using build_constraints_map = std::map; + + #pragma db value(build_constraint_key) + #pragma db member(build_constraint_key::outer) column("config_index") + #pragma db member(build_constraint_key::inner) column("index") + + // Adapter for build_package_config::constraints. + // + class build_package_config_constraints: + public small_vector // 1 as for build_package_configs. + { + public: + build_package_config_constraints () = default; + + explicit + build_package_config_constraints (const build_package_configs& cs) + { + reserve (cs.size ()); + for (const build_package_config& c: cs) + push_back (c.constraints); + } + + void + to_configs (build_package_configs& cs) && + { + // Note that the empty trailing entries will be missing (see ODB's + // nested-container.hxx for details). + // + assert (size () <= cs.size ()); + + auto i (cs.begin ()); + for (build_constraints& bcs: *this) + i++->constraints = move (bcs); + } + }; + // The primary reason why a package is unbuildable by the build bot // controller service. // @@ -398,6 +497,8 @@ namespace brep std::map; #pragma db value(requirement_alternative_key) + #pragma db member(requirement_alternative_key::outer) column("requirement_index") + #pragma db member(requirement_alternative_key::inner) column("index") using requirement_key = odb::nested2_key; @@ -405,6 +506,9 @@ namespace brep std::map; #pragma db value(requirement_key) + #pragma db member(requirement_key::outer) column("requirement_index") + #pragma db member(requirement_key::middle) column("alternative_index") + #pragma db member(requirement_key::inner) column("index") // Version comparison operators. // diff --git a/libbrep/package.cxx b/libbrep/package.cxx index 5f99fbb..152d1d8 100644 --- a/libbrep/package.cxx +++ b/libbrep/package.cxx @@ -77,6 +77,7 @@ namespace brep small_vector ts, build_class_exprs bs, build_constraints_type bc, + build_package_configs bcs, optional lc, optional fr, optional sh, @@ -114,6 +115,24 @@ namespace brep fragment (move (fr)), sha256sum (move (sh)) { + // Add the default build configuration at the beginning, unless it is + // specified explicitly. + // + if (find_if (bcs.begin (), bcs.end (), + [] (const build_package_config& c) + {return c.name == "default";}) != bcs.end ()) + { + build_configs = move (bcs); + } + else + { + build_configs.reserve (bcs.size () + 1); + build_configs.emplace_back ("default"); + build_configs.insert (build_configs.end (), + make_move_iterator (bcs.begin ()), + make_move_iterator (bcs.end ())); + } + if (stub ()) unbuildable_reason = brep::unbuildable_reason::stub; else if (!internal_repository->buildable) diff --git a/libbrep/package.hxx b/libbrep/package.hxx index c586d74..4a68a07 100644 --- a/libbrep/package.hxx +++ b/libbrep/package.hxx @@ -20,7 +20,7 @@ // #define LIBBREP_PACKAGE_SCHEMA_VERSION_BASE 25 -#pragma db model version(LIBBREP_PACKAGE_SCHEMA_VERSION_BASE, 25, closed) +#pragma db model version(LIBBREP_PACKAGE_SCHEMA_VERSION_BASE, 26, closed) namespace brep { @@ -417,6 +417,9 @@ namespace brep // Create internal package object. // + // Note: adds the default build package config at the first position if it + // is not present yet. + // package (package_name, version_type, optional upstream_version, @@ -443,6 +446,7 @@ namespace brep small_vector tests, build_class_exprs, build_constraints_type, + build_package_configs, optional location, optional fragment, optional sha256sum, @@ -513,8 +517,14 @@ namespace brep requirements_type requirements; // Note: foreign-mapped in build. small_vector tests; // Note: foreign-mapped in build. + // Common build classes/constraints that apply to all configurations + // unless overridden. + // build_class_exprs builds; // Note: foreign-mapped in build. build_constraints_type build_constraints; // Note: foreign-mapped in build. + + build_package_configs build_configs; // Note: foreign-mapped in build. + odb::section build_section; // Note that it is foreign-mapped in build. @@ -634,9 +644,6 @@ namespace brep // Container of the requirement_alternative values. // - #pragma db member(requirement_alternative_key::outer) column("requirement_index") - #pragma db member(requirement_alternative_key::inner) column("index") - #pragma db member(requirement_alternatives) \ virtual(requirement_alternatives_map) \ after(requirements) \ @@ -646,10 +653,6 @@ namespace brep // Container of the requirement (string) values. // - #pragma db member(requirement_key::outer) column("requirement_index") - #pragma db member(requirement_key::middle) column("alternative_index") - #pragma db member(requirement_key::inner) column("index") - #pragma db member(requirement_alternative_requirements) \ virtual(requirement_alternative_requirements_map) \ after(requirement_alternatives) \ @@ -671,6 +674,37 @@ namespace brep #pragma db member(build_constraints) id_column("") value_column("") \ section(build_section) + // build_configs + // + // Note that build_package_config::{builds,constraints} are + // persisted/loaded via the separate nested containers (see commons.hxx + // for details). + // + #pragma db member(build_configs) id_column("") value_column("config_") \ + section(build_section) + + #pragma db member(build_config_builds) \ + virtual(build_class_exprs_map) \ + after(build_configs) \ + get(odb::nested_get ( \ + brep::build_package_config_builds (this.build_configs))) \ + set(brep::build_package_config_builds bs; \ + odb::nested_set (bs, std::move (?)); \ + move (bs).to_configs (this.build_configs)) \ + id_column("") key_column("") value_column("") \ + section(build_section) + + #pragma db member(build_config_constraints) \ + virtual(build_constraints_map) \ + after(build_config_builds) \ + get(odb::nested_get ( \ + brep::build_package_config_constraints (this.build_configs))) \ + set(brep::build_package_config_constraints cs; \ + odb::nested_set (cs, std::move (?)); \ + move (cs).to_configs (this.build_configs)) \ + id_column("") key_column("") value_column("") \ + section(build_section) + #pragma db member(build_section) load(lazy) update(always) // other_repositories diff --git a/libbrep/package.xml b/libbrep/package.xml index 2e7a613..4e5544a 100644 --- a/libbrep/package.xml +++ b/libbrep/package.xml @@ -1,4 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/libbrep/utility.hxx b/libbrep/utility.hxx index 7058c94..fce8fb5 100644 --- a/libbrep/utility.hxx +++ b/libbrep/utility.hxx @@ -4,11 +4,12 @@ #ifndef LIBBREP_UTILITY_HXX #define LIBBREP_UTILITY_HXX -#include // make_shared() -#include // to_string() -#include // move(), forward(), declval(), make_pair() -#include // assert() -#include // make_move_iterator() +#include // make_shared() +#include // to_string() +#include // move(), forward(), declval(), make_pair() +#include // assert() +#include // make_move_iterator() +#include // * #include // icasecmp(), reverse_iterate(), // operator<<(ostream, exception) -- cgit v1.1