diff options
Diffstat (limited to 'libbrep')
-rw-r--r-- | libbrep/build-extra.sql | 3 | ||||
-rw-r--r-- | libbrep/build-package.hxx | 17 | ||||
-rw-r--r-- | libbrep/build.hxx | 4 | ||||
-rw-r--r-- | libbrep/build.xml | 129 | ||||
-rw-r--r-- | libbrep/common.hxx | 14 | ||||
-rwxr-xr-x | libbrep/odb.sh | 12 | ||||
-rw-r--r-- | libbrep/package.cxx | 2 | ||||
-rw-r--r-- | libbrep/package.hxx | 105 | ||||
-rw-r--r-- | libbrep/package.xml | 521 | ||||
-rw-r--r-- | libbrep/review-manifest.cxx | 220 | ||||
-rw-r--r-- | libbrep/review-manifest.hxx | 80 |
11 files changed, 739 insertions, 368 deletions
diff --git a/libbrep/build-extra.sql b/libbrep/build-extra.sql index 9e51a51..0c0f010 100644 --- a/libbrep/build-extra.sql +++ b/libbrep/build-extra.sql @@ -46,10 +46,13 @@ CREATE FOREIGN TABLE build_tenant ( id TEXT NOT NULL, private BOOLEAN NOT NULL, interactive TEXT NULL, + creation_timestamp BIGINT NOT NULL, archived BOOLEAN NOT NULL, service_id TEXT NULL, service_type TEXT NULL, service_data TEXT NULL, + unloaded_timestamp BIGINT NULL, + unloaded_notify_interval BIGINT NULL, queued_timestamp BIGINT NULL, toolchain_name TEXT OPTIONS (column_name 'build_toolchain_name') NULL, toolchain_version_epoch INTEGER OPTIONS (column_name 'build_toolchain_version_epoch') NULL, diff --git a/libbrep/build-package.hxx b/libbrep/build-package.hxx index 9a9c277..13645eb 100644 --- a/libbrep/build-package.hxx +++ b/libbrep/build-package.hxx @@ -32,12 +32,25 @@ namespace brep class build_tenant { public: + // Create tenant for an unloaded CI request (see the build_unloaded() + // tenant services notification for details). + // + build_tenant (string i, tenant_service s, timestamp t, duration n) + : id (move (i)), + creation_timestamp (timestamp::clock::now ()), + service (move (s)), + unloaded_timestamp (t), + unloaded_notify_interval (n) {} + string id; - bool private_; + bool private_ = false; optional<string> interactive; - bool archived; + timestamp creation_timestamp; + bool archived = false; optional<tenant_service> service; + optional<timestamp> unloaded_timestamp; + optional<duration> unloaded_notify_interval; optional<timestamp> queued_timestamp; optional<build_toolchain> toolchain; diff --git a/libbrep/build.hxx b/libbrep/build.hxx index af49c03..b485636 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 20 +#define LIBBREP_BUILD_SCHEMA_VERSION_BASE 28 -#pragma db model version(LIBBREP_BUILD_SCHEMA_VERSION_BASE, 27, closed) +#pragma db model version(LIBBREP_BUILD_SCHEMA_VERSION_BASE, 28, 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 diff --git a/libbrep/build.xml b/libbrep/build.xml index 1eba85a..d58e5f4 100644 --- a/libbrep/build.xml +++ b/libbrep/build.xml @@ -1,10 +1,61 @@ <changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="pgsql" schema-name="build" version="1"> - <changeset version="27"/> - - <changeset version="26"/> - - <changeset version="25"> - <add-table name="build_auxiliary_machines" kind="container"> + <model version="28"> + <table name="build" kind="object"> + <column name="package_tenant" type="TEXT" null="false"/> + <column name="package_name" type="CITEXT" null="false"/> + <column name="package_version_epoch" type="INTEGER" null="false"/> + <column name="package_version_canonical_upstream" type="TEXT" null="false"/> + <column name="package_version_canonical_release" type="TEXT" null="false" options="COLLATE "C""/> + <column name="package_version_revision" type="INTEGER" null="false"/> + <column name="target" type="TEXT" null="false"/> + <column name="target_config_name" type="TEXT" null="false"/> + <column name="package_config_name" type="TEXT" null="false"/> + <column name="toolchain_name" type="TEXT" null="false"/> + <column name="toolchain_version_epoch" type="INTEGER" null="false"/> + <column name="toolchain_version_canonical_upstream" type="TEXT" null="false"/> + <column name="toolchain_version_canonical_release" type="TEXT" null="false" options="COLLATE "C""/> + <column name="toolchain_version_revision" type="INTEGER" null="false"/> + <column name="package_version_upstream" type="TEXT" null="false"/> + <column name="package_version_release" type="TEXT" null="true"/> + <column name="toolchain_version_upstream" type="TEXT" null="false"/> + <column name="toolchain_version_release" type="TEXT" null="true"/> + <column name="state" type="TEXT" null="false"/> + <column name="interactive" type="TEXT" null="true"/> + <column name="timestamp" type="BIGINT" null="false"/> + <column name="force" type="TEXT" null="false"/> + <column name="status" type="TEXT" null="true"/> + <column name="soft_timestamp" type="BIGINT" null="false"/> + <column name="hard_timestamp" type="BIGINT" null="false"/> + <column name="agent_fingerprint" type="TEXT" null="true"/> + <column name="agent_challenge" type="TEXT" null="true"/> + <column name="controller_checksum" type="TEXT" null="false"/> + <column name="machine_checksum" type="TEXT" null="false"/> + <column name="agent_checksum" type="TEXT" null="true"/> + <column name="worker_checksum" type="TEXT" null="true"/> + <column name="dependency_checksum" type="TEXT" null="true"/> + <column name="machine" type="TEXT" null="false"/> + <column name="machine_summary" type="TEXT" null="false"/> + <primary-key> + <column name="package_tenant"/> + <column name="package_name"/> + <column name="package_version_epoch"/> + <column name="package_version_canonical_upstream"/> + <column name="package_version_canonical_release"/> + <column name="package_version_revision"/> + <column name="target"/> + <column name="target_config_name"/> + <column name="package_config_name"/> + <column name="toolchain_name"/> + <column name="toolchain_version_epoch"/> + <column name="toolchain_version_canonical_upstream"/> + <column name="toolchain_version_canonical_release"/> + <column name="toolchain_version_revision"/> + </primary-key> + <index name="build_timestamp_i"> + <column name="timestamp"/> + </index> + </table> + <table name="build_auxiliary_machines" kind="container"> <column name="package_tenant" type="TEXT" null="false"/> <column name="package_name" type="CITEXT" null="false"/> <column name="package_version_epoch" type="INTEGER" null="false"/> @@ -73,72 +124,6 @@ <index name="build_auxiliary_machines_index_i"> <column name="index"/> </index> - </add-table> - </changeset> - - <changeset version="24"/> - - <changeset version="23"/> - - <changeset version="22"/> - - <changeset version="21"/> - - <model version="20"> - <table name="build" kind="object"> - <column name="package_tenant" type="TEXT" null="false"/> - <column name="package_name" type="CITEXT" null="false"/> - <column name="package_version_epoch" type="INTEGER" null="false"/> - <column name="package_version_canonical_upstream" type="TEXT" null="false"/> - <column name="package_version_canonical_release" type="TEXT" null="false" options="COLLATE "C""/> - <column name="package_version_revision" type="INTEGER" null="false"/> - <column name="target" type="TEXT" null="false"/> - <column name="target_config_name" type="TEXT" null="false"/> - <column name="package_config_name" type="TEXT" null="false"/> - <column name="toolchain_name" type="TEXT" null="false"/> - <column name="toolchain_version_epoch" type="INTEGER" null="false"/> - <column name="toolchain_version_canonical_upstream" type="TEXT" null="false"/> - <column name="toolchain_version_canonical_release" type="TEXT" null="false" options="COLLATE "C""/> - <column name="toolchain_version_revision" type="INTEGER" null="false"/> - <column name="package_version_upstream" type="TEXT" null="false"/> - <column name="package_version_release" type="TEXT" null="true"/> - <column name="toolchain_version_upstream" type="TEXT" null="false"/> - <column name="toolchain_version_release" type="TEXT" null="true"/> - <column name="state" type="TEXT" null="false"/> - <column name="interactive" type="TEXT" null="true"/> - <column name="timestamp" type="BIGINT" null="false"/> - <column name="force" type="TEXT" null="false"/> - <column name="status" type="TEXT" null="true"/> - <column name="soft_timestamp" type="BIGINT" null="false"/> - <column name="hard_timestamp" type="BIGINT" null="false"/> - <column name="agent_fingerprint" type="TEXT" null="true"/> - <column name="agent_challenge" type="TEXT" null="true"/> - <column name="machine" type="TEXT" null="false"/> - <column name="machine_summary" type="TEXT" null="false"/> - <column name="controller_checksum" type="TEXT" null="false"/> - <column name="machine_checksum" type="TEXT" null="false"/> - <column name="agent_checksum" type="TEXT" null="true"/> - <column name="worker_checksum" type="TEXT" null="true"/> - <column name="dependency_checksum" type="TEXT" null="true"/> - <primary-key> - <column name="package_tenant"/> - <column name="package_name"/> - <column name="package_version_epoch"/> - <column name="package_version_canonical_upstream"/> - <column name="package_version_canonical_release"/> - <column name="package_version_revision"/> - <column name="target"/> - <column name="target_config_name"/> - <column name="package_config_name"/> - <column name="toolchain_name"/> - <column name="toolchain_version_epoch"/> - <column name="toolchain_version_canonical_upstream"/> - <column name="toolchain_version_canonical_release"/> - <column name="toolchain_version_revision"/> - </primary-key> - <index name="build_timestamp_i"> - <column name="timestamp"/> - </index> </table> <table name="build_results" kind="container"> <column name="package_tenant" type="TEXT" null="false"/> diff --git a/libbrep/common.hxx b/libbrep/common.hxx index 1433c8c..4be9ce9 100644 --- a/libbrep/common.hxx +++ b/libbrep/common.hxx @@ -141,6 +141,20 @@ namespace brep std::chrono::nanoseconds (*(?)))) \ : brep::optional_timestamp ()) + #pragma db map type(duration) as(uint64_t) \ + to(std::chrono::duration_cast<std::chrono::nanoseconds> (?).count ()) \ + from(brep::duration (std::chrono::nanoseconds (?))) + + using optional_duration = optional<duration>; + + #pragma db map type(optional_duration) as(brep::optional_uint64) \ + to((?) \ + ? std::chrono::duration_cast<std::chrono::nanoseconds> (*(?)).count () \ + : brep::optional_uint64 ()) \ + from((?) \ + ? brep::duration (std::chrono::nanoseconds (*(?))) \ + : brep::optional_duration ()) + // version // using bpkg::version; diff --git a/libbrep/odb.sh b/libbrep/odb.sh index 89dc5be..7c62acb 100755 --- a/libbrep/odb.sh +++ b/libbrep/odb.sh @@ -35,16 +35,8 @@ sed -r -ne 's#^(@[^ ]+ )?([^ ]+)/ .*default.*$#\2#p')" else - # Feels like this case should not be necessary (unlike in bpkg/bdep). - # - echo "not bdep-initialized" 1>&2 - exit 1 - - inc+=("-I$HOME/work/odb/builds/default/libodb-pgsql-default") - inc+=("-I$HOME/work/odb/libodb-pgsql") - - inc+=("-I$HOME/work/odb/builds/default/libodb-default") - inc+=("-I$HOME/work/odb/libodb") + inc+=("-I$HOME/work/odb/odb/libodb-pgsql") + inc+=("-I$HOME/work/odb/odb/libodb") inc+=(-I.. -I../../libbbot -I../../libbpkg -I../../libbutl) diff --git a/libbrep/package.cxx b/libbrep/package.cxx index 4eb6fe8..391a583 100644 --- a/libbrep/package.cxx +++ b/libbrep/package.cxx @@ -84,6 +84,7 @@ namespace brep build_auxiliaries_type ac, package_build_bot_keys bk, package_build_configs bcs, + optional<reviews_summary> rvs, optional<path> lc, optional<string> fr, optional<string> sh, @@ -119,6 +120,7 @@ namespace brep build_auxiliaries (move (ac)), build_bot_keys (move (bk)), build_configs (move (bcs)), + reviews (move (rvs)), internal_repository (move (rp)), location (move (lc)), fragment (move (fr)), diff --git a/libbrep/package.hxx b/libbrep/package.hxx index 45008d4..e2d2da5 100644 --- a/libbrep/package.hxx +++ b/libbrep/package.hxx @@ -18,9 +18,9 @@ // Used by the data migration entries. // -#define LIBBREP_PACKAGE_SCHEMA_VERSION_BASE 27 +#define LIBBREP_PACKAGE_SCHEMA_VERSION_BASE 34 -#pragma db model version(LIBBREP_PACKAGE_SCHEMA_VERSION_BASE, 33, closed) +#pragma db model version(LIBBREP_PACKAGE_SCHEMA_VERSION_BASE, 35, closed) namespace brep { @@ -133,7 +133,7 @@ namespace brep optional<version_constraint> constraint; // Resolved dependency package. Can be NULL if the repository load was - // shallow and the package dependency could not be resolved. + // shallow or the package dependency could not be resolved. // lazy_shared_ptr<package_type> package; @@ -224,9 +224,8 @@ namespace brep // certificate // #pragma db value - class certificate + struct certificate { - public: string fingerprint; // SHA256 fingerprint. Note: foreign-mapped in build. string name; // CN component of Subject. string organization; // O component of Subject. @@ -251,19 +250,29 @@ namespace brep // If this flag is true, then display the packages in the web interface // only in the tenant view mode. // - bool private_; // Note: foreign-mapped in build. + bool private_; // Note: foreign-mapped in build. // Interactive package build breakpoint. // // If present, then packages from this tenant will only be built // interactively and only non-interactively otherwise. // - optional<string> interactive; // Note: foreign-mapped in build. + optional<string> interactive; // Note: foreign-mapped in build. + + timestamp creation_timestamp; // Note: foreign-mapped in build. + bool archived = false; // Note: foreign-mapped in build. + + optional<tenant_service> service; // Note: foreign-mapped in build. - timestamp creation_timestamp; - bool archived = false; // Note: foreign-mapped in build. + // If the tenant is loaded, this value is absent. Otherwise it is the time + // of the last attempt to load the tenant (see the build_unloaded() tenant + // services notification for details). + // + optional<timestamp> unloaded_timestamp; // Note: foreign-mapped in build. - optional<tenant_service> service; // Note: foreign-mapped in build. + // The time interval between attempts to load the tenant, if unloaded. + // + optional<duration> unloaded_notify_interval; // Note: foreign-mapped in build. // Note that due to the implementation complexity and performance // considerations, the service notifications are not synchronized. This @@ -284,7 +293,7 @@ namespace brep // natural reasons (non-zero build task execution time, etc) and thus we // just ignore them. // - optional<timestamp> queued_timestamp; // Note: foreign-mapped in build. + optional<timestamp> queued_timestamp; // Note: foreign-mapped in build. // Note that after the package tenant is created but before the first // build object is created, there is no easy way to produce a list of @@ -318,6 +327,10 @@ namespace brep #pragma db index member(service.id) + // Speed-up queries with ordering the result by unloaded_timestamp. + // + #pragma db member(unloaded_timestamp) index + private: friend class odb::access; tenant () = default; @@ -427,6 +440,20 @@ namespace brep repository (): tenant (id.tenant), canonical_name (id.canonical_name) {} }; + // Repositories count. + // + #pragma db view object(repository) + struct repository_count + { + size_t result; + + operator size_t () const {return result;} + + // Database mapping. + // + #pragma db member(result) column("count(" + repository::id.tenant + ")") + }; + // The 'to' expression calls the PostgreSQL to_tsvector(weighted_text) // function overload (package-extra.sql). Since we are only interested // in "write-only" members of this type, make the 'from' expression @@ -508,6 +535,35 @@ namespace brep #pragma db member(package_build_bot_key_key::outer) column("config_index") #pragma db member(package_build_bot_key_key::inner) column("index") + // Number of the passed and failed reviews and the path to the + // reviews.manifest file this information comes form. The path is relative + // to the root of the package metadata directory. + // + #pragma db value + struct reviews_summary + { + // May not be both zero. + // + size_t pass; + size_t fail; + + path manifest_file; + }; + + inline bool + operator== (const reviews_summary& x, const reviews_summary& y) + { + return x.pass == y.pass && + x.fail == y.fail && + x.manifest_file == y.manifest_file; + } + + inline bool + operator!= (const reviews_summary& x, const reviews_summary& y) + { + return !(x == y); + } + // Tweak package_id mapping to include a constraint (this only affects the // database schema). // @@ -561,6 +617,7 @@ namespace brep build_auxiliaries_type, package_build_bot_keys, package_build_configs, + optional<reviews_summary>, optional<path> location, optional<string> fragment, optional<string> sha256sum, @@ -663,6 +720,9 @@ namespace brep // odb::section build_section; + optional<reviews_summary> reviews; + odb::section reviews_section; + // Note that it is foreign-mapped in build. // lazy_shared_ptr<repository_type> internal_repository; @@ -888,8 +948,11 @@ namespace brep id_column("") key_column("") value_column("key_") value_not_null \ section(unused_section) - #pragma db member(build_section) load(lazy) update(always) - #pragma db member(unused_section) load(lazy) update(manual) + #pragma db member(reviews) section(reviews_section) + + #pragma db member(build_section) load(lazy) update(always) + #pragma db member(reviews_section) load(lazy) update(always) + #pragma db member(unused_section) load(lazy) update(manual) // other_repositories // @@ -920,6 +983,20 @@ namespace brep search_text (const weighted_text&) {} }; + // Packages count. + // + #pragma db view object(package) + struct package_count + { + size_t result; + + operator size_t () const {return result;} + + // Database mapping. + // + #pragma db member(result) column("count(" + package::id.tenant + ")") + }; + // Package search query matching rank. // #pragma db view query("/*CALL*/ SELECT * FROM search_latest_packages(?)") @@ -946,7 +1023,7 @@ namespace brep }; #pragma db view query("/*CALL*/ SELECT count(*) FROM search_packages(?)") - struct package_count + struct package_search_count { size_t result; diff --git a/libbrep/package.xml b/libbrep/package.xml index 96e93a7..8b6c706 100644 --- a/libbrep/package.xml +++ b/libbrep/package.xml @@ -1,285 +1,45 @@ <changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="pgsql" schema-name="package" version="1"> - <changeset version="33"> - <add-table name="public_key" kind="object"> - <column name="tenant" type="TEXT" null="false"/> - <column name="fingerprint" type="TEXT" null="false"/> - <column name="data" type="TEXT" null="false"/> - <primary-key> - <column name="tenant"/> - <column name="fingerprint"/> - </primary-key> - <foreign-key name="tenant_fk" deferrable="DEFERRED"> - <column name="tenant"/> - <references table="tenant"> - <column name="id"/> - </references> - </foreign-key> - </add-table> + <changeset version="35"> <alter-table name="package"> - <add-column name="custom_bot" type="BOOLEAN" null="true"/> - </alter-table> - <add-table name="package_build_bot_keys" kind="container"> - <column name="tenant" type="TEXT" null="false"/> - <column name="name" type="CITEXT" null="false"/> - <column name="version_epoch" type="INTEGER" null="false"/> - <column name="version_canonical_upstream" type="TEXT" null="false"/> - <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE "C""/> - <column name="version_revision" type="INTEGER" null="false"/> - <column name="index" type="BIGINT" null="false"/> - <column name="key_tenant" type="TEXT" null="false"/> - <column name="key_fingerprint" type="TEXT" null="false"/> - <foreign-key name="tenant_fk" deferrable="DEFERRED"> - <column name="tenant"/> - <references table="tenant"> - <column name="id"/> - </references> - </foreign-key> - <foreign-key name="object_id_fk" on-delete="CASCADE"> - <column name="tenant"/> - <column name="name"/> - <column name="version_epoch"/> - <column name="version_canonical_upstream"/> - <column name="version_canonical_release"/> - <column name="version_revision"/> - <references table="package"> - <column name="tenant"/> - <column name="name"/> - <column name="version_epoch"/> - <column name="version_canonical_upstream"/> - <column name="version_canonical_release"/> - <column name="version_revision"/> - </references> - </foreign-key> - <index name="package_build_bot_keys_object_id_i"> - <column name="tenant"/> - <column name="name"/> - <column name="version_epoch"/> - <column name="version_canonical_upstream"/> - <column name="version_canonical_release"/> - <column name="version_revision"/> - </index> - <index name="package_build_bot_keys_index_i"> - <column name="index"/> - </index> - <foreign-key name="key_tenant_fk" deferrable="DEFERRED"> - <column name="key_tenant"/> - <references table="tenant"> - <column name="id"/> - </references> - </foreign-key> - <foreign-key name="key_fk" deferrable="DEFERRED"> - <column name="key_tenant"/> - <column name="key_fingerprint"/> - <references table="public_key"> - <column name="tenant"/> - <column name="fingerprint"/> - </references> - </foreign-key> - </add-table> - <add-table name="package_build_config_bot_keys" kind="container"> - <column name="tenant" type="TEXT" null="false"/> - <column name="name" type="CITEXT" null="false"/> - <column name="version_epoch" type="INTEGER" null="false"/> - <column name="version_canonical_upstream" type="TEXT" null="false"/> - <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE "C""/> - <column name="version_revision" type="INTEGER" null="false"/> - <column name="config_index" type="BIGINT" null="false"/> - <column name="index" type="BIGINT" null="false"/> - <column name="key_tenant" type="TEXT" null="false"/> - <column name="key_fingerprint" type="TEXT" null="false"/> - <foreign-key name="tenant_fk" deferrable="DEFERRED"> - <column name="tenant"/> - <references table="tenant"> - <column name="id"/> - </references> - </foreign-key> - <foreign-key name="object_id_fk" on-delete="CASCADE"> - <column name="tenant"/> - <column name="name"/> - <column name="version_epoch"/> - <column name="version_canonical_upstream"/> - <column name="version_canonical_release"/> - <column name="version_revision"/> - <references table="package"> - <column name="tenant"/> - <column name="name"/> - <column name="version_epoch"/> - <column name="version_canonical_upstream"/> - <column name="version_canonical_release"/> - <column name="version_revision"/> - </references> - </foreign-key> - <index name="package_build_config_bot_keys_object_id_i"> - <column name="tenant"/> - <column name="name"/> - <column name="version_epoch"/> - <column name="version_canonical_upstream"/> - <column name="version_canonical_release"/> - <column name="version_revision"/> - </index> - <foreign-key name="key_tenant_fk" deferrable="DEFERRED"> - <column name="key_tenant"/> - <references table="tenant"> - <column name="id"/> - </references> - </foreign-key> - <foreign-key name="key_fk" deferrable="DEFERRED"> - <column name="key_tenant"/> - <column name="key_fingerprint"/> - <references table="public_key"> - <column name="tenant"/> - <column name="fingerprint"/> - </references> - </foreign-key> - </add-table> - </changeset> - - <changeset version="32"> - <alter-table name="tenant"> - <add-column name="build_toolchain_name" type="TEXT" null="true"/> - <add-column name="build_toolchain_version_epoch" type="INTEGER" null="true"/> - <add-column name="build_toolchain_version_canonical_upstream" type="TEXT" null="true"/> - <add-column name="build_toolchain_version_canonical_release" type="TEXT" null="true"/> - <add-column name="build_toolchain_version_revision" type="INTEGER" null="true"/> - <add-column name="build_toolchain_version_upstream" type="TEXT" null="true"/> - <add-column name="build_toolchain_version_release" type="TEXT" null="true"/> - </alter-table> - </changeset> - - <changeset version="31"> - <add-table name="package_build_auxiliaries" kind="container"> - <column name="tenant" type="TEXT" null="false"/> - <column name="name" type="CITEXT" null="false"/> - <column name="version_epoch" type="INTEGER" null="false"/> - <column name="version_canonical_upstream" type="TEXT" null="false"/> - <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE "C""/> - <column name="version_revision" type="INTEGER" null="false"/> - <column name="index" type="BIGINT" null="false"/> - <column name="environment_name" type="TEXT" null="false"/> - <column name="config" type="TEXT" null="false"/> - <column name="comment" type="TEXT" null="false"/> - <foreign-key name="tenant_fk" deferrable="DEFERRED"> - <column name="tenant"/> - <references table="tenant"> - <column name="id"/> - </references> - </foreign-key> - <foreign-key name="object_id_fk" on-delete="CASCADE"> - <column name="tenant"/> - <column name="name"/> - <column name="version_epoch"/> - <column name="version_canonical_upstream"/> - <column name="version_canonical_release"/> - <column name="version_revision"/> - <references table="package"> - <column name="tenant"/> - <column name="name"/> - <column name="version_epoch"/> - <column name="version_canonical_upstream"/> - <column name="version_canonical_release"/> - <column name="version_revision"/> - </references> - </foreign-key> - <index name="package_build_auxiliaries_object_id_i"> - <column name="tenant"/> - <column name="name"/> - <column name="version_epoch"/> - <column name="version_canonical_upstream"/> - <column name="version_canonical_release"/> - <column name="version_revision"/> - </index> - <index name="package_build_auxiliaries_index_i"> - <column name="index"/> - </index> - </add-table> - <add-table name="package_build_config_auxiliaries" kind="container"> - <column name="tenant" type="TEXT" null="false"/> - <column name="name" type="CITEXT" null="false"/> - <column name="version_epoch" type="INTEGER" null="false"/> - <column name="version_canonical_upstream" type="TEXT" null="false"/> - <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE "C""/> - <column name="version_revision" type="INTEGER" null="false"/> - <column name="config_index" type="BIGINT" null="false"/> - <column name="index" type="BIGINT" null="false"/> - <column name="environment_name" type="TEXT" null="false"/> - <column name="config" type="TEXT" null="false"/> - <column name="comment" type="TEXT" null="false"/> - <foreign-key name="tenant_fk" deferrable="DEFERRED"> - <column name="tenant"/> - <references table="tenant"> - <column name="id"/> - </references> - </foreign-key> - <foreign-key name="object_id_fk" on-delete="CASCADE"> - <column name="tenant"/> - <column name="name"/> - <column name="version_epoch"/> - <column name="version_canonical_upstream"/> - <column name="version_canonical_release"/> - <column name="version_revision"/> - <references table="package"> - <column name="tenant"/> - <column name="name"/> - <column name="version_epoch"/> - <column name="version_canonical_upstream"/> - <column name="version_canonical_release"/> - <column name="version_revision"/> - </references> - </foreign-key> - <index name="package_build_config_auxiliaries_object_id_i"> - <column name="tenant"/> - <column name="name"/> - <column name="version_epoch"/> - <column name="version_canonical_upstream"/> - <column name="version_canonical_release"/> - <column name="version_revision"/> - </index> - </add-table> - </changeset> - - <changeset version="30"> - <alter-table name="tenant"> - <add-column name="service_id" type="TEXT" null="true"/> - <add-column name="service_type" type="TEXT" null="true"/> - <add-column name="service_data" type="TEXT" null="true"/> - <add-column name="queued_timestamp" type="BIGINT" null="true"/> - <add-index name="tenant_service_i" type="UNIQUE"> - <column name="service_id"/> - <column name="service_type"/> - </add-index> - <add-index name="tenant_service_id_i"> - <column name="service_id"/> - </add-index> - </alter-table> - </changeset> - - <changeset version="29"> - <alter-table name="package_tests"> - <add-column name="test_enable" type="TEXT" null="true"/> + <add-column name="reviews_pass" type="BIGINT" null="true"/> + <add-column name="reviews_fail" type="BIGINT" null="true"/> + <add-column name="reviews_manifest_file" type="TEXT" null="true"/> </alter-table> </changeset> - <changeset version="28"> - <alter-table name="package_build_configs"> - <add-column name="config_email" type="TEXT" null="true"/> - <add-column name="config_email_comment" type="TEXT" null="true"/> - <add-column name="config_warning_email" type="TEXT" null="true"/> - <add-column name="config_warning_email_comment" type="TEXT" null="true"/> - <add-column name="config_error_email" type="TEXT" null="true"/> - <add-column name="config_error_email_comment" type="TEXT" null="true"/> - </alter-table> - </changeset> - - <model version="27"> + <model version="34"> <table name="tenant" kind="object"> <column name="id" type="TEXT" null="false"/> <column name="private" type="BOOLEAN" null="false"/> <column name="interactive" type="TEXT" null="true"/> <column name="creation_timestamp" type="BIGINT" null="false"/> <column name="archived" type="BOOLEAN" null="false"/> + <column name="service_id" type="TEXT" null="true"/> + <column name="service_type" type="TEXT" null="true"/> + <column name="service_data" type="TEXT" null="true"/> + <column name="unloaded_timestamp" type="BIGINT" null="true"/> + <column name="unloaded_notify_interval" type="BIGINT" null="true"/> + <column name="queued_timestamp" type="BIGINT" null="true"/> + <column name="build_toolchain_name" type="TEXT" null="true"/> + <column name="build_toolchain_version_epoch" type="INTEGER" null="true"/> + <column name="build_toolchain_version_canonical_upstream" type="TEXT" null="true"/> + <column name="build_toolchain_version_canonical_release" type="TEXT" null="true"/> + <column name="build_toolchain_version_revision" type="INTEGER" null="true"/> + <column name="build_toolchain_version_upstream" type="TEXT" null="true"/> + <column name="build_toolchain_version_release" type="TEXT" null="true"/> <primary-key> <column name="id"/> </primary-key> + <index name="tenant_service_i" type="UNIQUE"> + <column name="service_id"/> + <column name="service_type"/> + </index> + <index name="tenant_service_id_i"> + <column name="service_id"/> + </index> + <index name="tenant_unloaded_timestamp_i"> + <column name="unloaded_timestamp"/> + </index> </table> <table name="repository" kind="object"> <column name="tenant" type="TEXT" null="false"/> @@ -399,6 +159,21 @@ </references> </foreign-key> </table> + <table name="public_key" kind="object"> + <column name="tenant" type="TEXT" null="false"/> + <column name="fingerprint" type="TEXT" null="false"/> + <column name="data" type="TEXT" null="false"/> + <primary-key> + <column name="tenant"/> + <column name="fingerprint"/> + </primary-key> + <foreign-key name="tenant_fk" deferrable="DEFERRED"> + <column name="tenant"/> + <references table="tenant"> + <column name="id"/> + </references> + </foreign-key> + </table> <table name="package" kind="object"> <column name="tenant" type="TEXT" null="false"/> <column name="name" type="CITEXT" null="false"/> @@ -444,6 +219,7 @@ <column name="sha256sum" type="TEXT" null="true"/> <column name="buildable" type="BOOLEAN" null="false"/> <column name="unbuildable_reason" type="TEXT" null="true"/> + <column name="custom_bot" type="BOOLEAN" null="true"/> <column name="search_index" type="tsvector" null="true"/> <primary-key> <column name="tenant"/> @@ -979,6 +755,7 @@ <column name="test_package_version_revision" type="INTEGER" null="true"/> <column name="test_type" type="TEXT" null="false"/> <column name="test_buildtime" type="BOOLEAN" null="false"/> + <column name="test_enable" type="TEXT" null="true"/> <column name="test_reflect" type="TEXT" null="true"/> <foreign-key name="tenant_fk" deferrable="DEFERRED"> <column name="tenant"/> @@ -1126,6 +903,109 @@ <column name="index"/> </index> </table> + <table name="package_build_auxiliaries" kind="container"> + <column name="tenant" type="TEXT" null="false"/> + <column name="name" type="CITEXT" null="false"/> + <column name="version_epoch" type="INTEGER" null="false"/> + <column name="version_canonical_upstream" type="TEXT" null="false"/> + <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE "C""/> + <column name="version_revision" type="INTEGER" null="false"/> + <column name="index" type="BIGINT" null="false"/> + <column name="environment_name" type="TEXT" null="false"/> + <column name="config" type="TEXT" null="false"/> + <column name="comment" type="TEXT" null="false"/> + <foreign-key name="tenant_fk" deferrable="DEFERRED"> + <column name="tenant"/> + <references table="tenant"> + <column name="id"/> + </references> + </foreign-key> + <foreign-key name="object_id_fk" on-delete="CASCADE"> + <column name="tenant"/> + <column name="name"/> + <column name="version_epoch"/> + <column name="version_canonical_upstream"/> + <column name="version_canonical_release"/> + <column name="version_revision"/> + <references table="package"> + <column name="tenant"/> + <column name="name"/> + <column name="version_epoch"/> + <column name="version_canonical_upstream"/> + <column name="version_canonical_release"/> + <column name="version_revision"/> + </references> + </foreign-key> + <index name="package_build_auxiliaries_object_id_i"> + <column name="tenant"/> + <column name="name"/> + <column name="version_epoch"/> + <column name="version_canonical_upstream"/> + <column name="version_canonical_release"/> + <column name="version_revision"/> + </index> + <index name="package_build_auxiliaries_index_i"> + <column name="index"/> + </index> + </table> + <table name="package_build_bot_keys" kind="container"> + <column name="tenant" type="TEXT" null="false"/> + <column name="name" type="CITEXT" null="false"/> + <column name="version_epoch" type="INTEGER" null="false"/> + <column name="version_canonical_upstream" type="TEXT" null="false"/> + <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE "C""/> + <column name="version_revision" type="INTEGER" null="false"/> + <column name="index" type="BIGINT" null="false"/> + <column name="key_tenant" type="TEXT" null="false"/> + <column name="key_fingerprint" type="TEXT" null="false"/> + <foreign-key name="tenant_fk" deferrable="DEFERRED"> + <column name="tenant"/> + <references table="tenant"> + <column name="id"/> + </references> + </foreign-key> + <foreign-key name="object_id_fk" on-delete="CASCADE"> + <column name="tenant"/> + <column name="name"/> + <column name="version_epoch"/> + <column name="version_canonical_upstream"/> + <column name="version_canonical_release"/> + <column name="version_revision"/> + <references table="package"> + <column name="tenant"/> + <column name="name"/> + <column name="version_epoch"/> + <column name="version_canonical_upstream"/> + <column name="version_canonical_release"/> + <column name="version_revision"/> + </references> + </foreign-key> + <index name="package_build_bot_keys_object_id_i"> + <column name="tenant"/> + <column name="name"/> + <column name="version_epoch"/> + <column name="version_canonical_upstream"/> + <column name="version_canonical_release"/> + <column name="version_revision"/> + </index> + <index name="package_build_bot_keys_index_i"> + <column name="index"/> + </index> + <foreign-key name="key_tenant_fk" deferrable="DEFERRED"> + <column name="key_tenant"/> + <references table="tenant"> + <column name="id"/> + </references> + </foreign-key> + <foreign-key name="key_fk" deferrable="DEFERRED"> + <column name="key_tenant"/> + <column name="key_fingerprint"/> + <references table="public_key"> + <column name="tenant"/> + <column name="fingerprint"/> + </references> + </foreign-key> + </table> <table name="package_build_configs" kind="container"> <column name="tenant" type="TEXT" null="false"/> <column name="name" type="CITEXT" null="false"/> @@ -1137,6 +1017,12 @@ <column name="config_name" type="TEXT" null="false"/> <column name="config_arguments" type="TEXT" null="false"/> <column name="config_comment" type="TEXT" null="false"/> + <column name="config_email" type="TEXT" null="true"/> + <column name="config_email_comment" type="TEXT" null="true"/> + <column name="config_warning_email" type="TEXT" null="true"/> + <column name="config_warning_email_comment" type="TEXT" null="true"/> + <column name="config_error_email" type="TEXT" null="true"/> + <column name="config_error_email_comment" type="TEXT" null="true"/> <foreign-key name="tenant_fk" deferrable="DEFERRED"> <column name="tenant"/> <references table="tenant"> @@ -1257,6 +1143,105 @@ <column name="version_revision"/> </index> </table> + <table name="package_build_config_auxiliaries" kind="container"> + <column name="tenant" type="TEXT" null="false"/> + <column name="name" type="CITEXT" null="false"/> + <column name="version_epoch" type="INTEGER" null="false"/> + <column name="version_canonical_upstream" type="TEXT" null="false"/> + <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE "C""/> + <column name="version_revision" type="INTEGER" null="false"/> + <column name="config_index" type="BIGINT" null="false"/> + <column name="index" type="BIGINT" null="false"/> + <column name="environment_name" type="TEXT" null="false"/> + <column name="config" type="TEXT" null="false"/> + <column name="comment" type="TEXT" null="false"/> + <foreign-key name="tenant_fk" deferrable="DEFERRED"> + <column name="tenant"/> + <references table="tenant"> + <column name="id"/> + </references> + </foreign-key> + <foreign-key name="object_id_fk" on-delete="CASCADE"> + <column name="tenant"/> + <column name="name"/> + <column name="version_epoch"/> + <column name="version_canonical_upstream"/> + <column name="version_canonical_release"/> + <column name="version_revision"/> + <references table="package"> + <column name="tenant"/> + <column name="name"/> + <column name="version_epoch"/> + <column name="version_canonical_upstream"/> + <column name="version_canonical_release"/> + <column name="version_revision"/> + </references> + </foreign-key> + <index name="package_build_config_auxiliaries_object_id_i"> + <column name="tenant"/> + <column name="name"/> + <column name="version_epoch"/> + <column name="version_canonical_upstream"/> + <column name="version_canonical_release"/> + <column name="version_revision"/> + </index> + </table> + <table name="package_build_config_bot_keys" kind="container"> + <column name="tenant" type="TEXT" null="false"/> + <column name="name" type="CITEXT" null="false"/> + <column name="version_epoch" type="INTEGER" null="false"/> + <column name="version_canonical_upstream" type="TEXT" null="false"/> + <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE "C""/> + <column name="version_revision" type="INTEGER" null="false"/> + <column name="config_index" type="BIGINT" null="false"/> + <column name="index" type="BIGINT" null="false"/> + <column name="key_tenant" type="TEXT" null="false"/> + <column name="key_fingerprint" type="TEXT" null="false"/> + <foreign-key name="tenant_fk" deferrable="DEFERRED"> + <column name="tenant"/> + <references table="tenant"> + <column name="id"/> + </references> + </foreign-key> + <foreign-key name="object_id_fk" on-delete="CASCADE"> + <column name="tenant"/> + <column name="name"/> + <column name="version_epoch"/> + <column name="version_canonical_upstream"/> + <column name="version_canonical_release"/> + <column name="version_revision"/> + <references table="package"> + <column name="tenant"/> + <column name="name"/> + <column name="version_epoch"/> + <column name="version_canonical_upstream"/> + <column name="version_canonical_release"/> + <column name="version_revision"/> + </references> + </foreign-key> + <index name="package_build_config_bot_keys_object_id_i"> + <column name="tenant"/> + <column name="name"/> + <column name="version_epoch"/> + <column name="version_canonical_upstream"/> + <column name="version_canonical_release"/> + <column name="version_revision"/> + </index> + <foreign-key name="key_tenant_fk" deferrable="DEFERRED"> + <column name="key_tenant"/> + <references table="tenant"> + <column name="id"/> + </references> + </foreign-key> + <foreign-key name="key_fk" deferrable="DEFERRED"> + <column name="key_tenant"/> + <column name="key_fingerprint"/> + <references table="public_key"> + <column name="tenant"/> + <column name="fingerprint"/> + </references> + </foreign-key> + </table> <table name="package_other_repositories" kind="container"> <column name="tenant" type="TEXT" null="false"/> <column name="name" type="CITEXT" null="false"/> diff --git a/libbrep/review-manifest.cxx b/libbrep/review-manifest.cxx new file mode 100644 index 0000000..3592e69 --- /dev/null +++ b/libbrep/review-manifest.cxx @@ -0,0 +1,220 @@ +// file : libbrep/review-manifest.cxx -*- C++ -*- +// license : MIT; see accompanying LICENSE file + +#include <libbrep/review-manifest.hxx> + +#include <libbutl/manifest-parser.hxx> +#include <libbutl/manifest-serializer.hxx> + +using namespace std; +using namespace butl; + +namespace brep +{ + using parser = manifest_parser; + using parsing = manifest_parsing; + using serializer = manifest_serializer; + using serialization = manifest_serialization; + using name_value = manifest_name_value; + + // review_result + // + string + to_string (review_result r) + { + switch (r) + { + case review_result::pass: return "pass"; + case review_result::fail: return "fail"; + case review_result::unchanged: return "unchanged"; + } + + assert (false); + return string (); + } + + review_result + to_review_result (const string& r) + { + if (r == "pass") return review_result::pass; + else if (r == "fail") return review_result::fail; + else if (r == "unchanged") return review_result::unchanged; + else throw invalid_argument ("invalid review result '" + r + '\''); + } + + // review_manifest + // + review_manifest:: + review_manifest (parser& p, bool iu) + : review_manifest (p, p.next (), iu) + { + // Make sure this is the end. + // + name_value nv (p.next ()); + if (!nv.empty ()) + throw parsing (p.name (), nv.name_line, nv.name_column, + "single review manifest expected"); + } + + review_manifest:: + review_manifest (parser& p, name_value nv, bool iu) + { + auto bad_name ([&p, &nv](const string& d) { + throw parsing (p.name (), nv.name_line, nv.name_column, d);}); + + auto bad_value ([&p, &nv](const string& d) { + throw parsing (p.name (), nv.value_line, nv.value_column, d);}); + + // Make sure this is the start and we support the version. + // + if (!nv.name.empty ()) + throw parsing (p.name (), nv.name_line, nv.name_column, + "start of review manifest expected"); + + if (nv.value != "1") + throw parsing (p.name (), nv.value_line, nv.value_column, + "unsupported format version"); + + bool need_base (false); + bool need_details (false); + + for (nv = p.next (); !nv.empty (); nv = p.next ()) + { + string& n (nv.name); + string& v (nv.value); + + if (n == "reviewed-by") + { + if (!reviewed_by.empty ()) + bad_name ("reviewer redefinition"); + + if (v.empty ()) + bad_value ("empty reviewer"); + + reviewed_by = move (v); + } + else if (n.size () > 7 && n.compare (0, 7, "result-") == 0) + { + string name (n, 7, n.size () - 7); + + if (find_if (results.begin (), results.end (), + [&name] (const review_aspect& r) + { + return name == r.name; + }) != results.end ()) + bad_name (name + " review result redefinition"); + + try + { + review_result r (to_review_result (v)); + + if (r == review_result::fail) + need_details = true; + + if (r == review_result::unchanged) + need_base = true; + + results.push_back (review_aspect {move (name), r}); + } + catch (const invalid_argument& e) + { + bad_value (e.what ()); + } + } + else if (n == "base-version") + { + if (base_version) + bad_name ("base version redefinition"); + + try + { + base_version = bpkg::version (v); + } + catch (const invalid_argument& e) + { + bad_value (e.what ()); + } + } + else if (n == "details-url") + { + if (details_url) + bad_name ("details url redefinition"); + + try + { + details_url = url (v); + } + catch (const invalid_argument& e) + { + bad_value (e.what ()); + } + } + else if (!iu) + bad_name ("unknown name '" + n + "' in review manifest"); + } + + // Verify all non-optional values were specified. + // + if (reviewed_by.empty ()) + bad_value ("no reviewer specified"); + + if (results.empty ()) + bad_value ("no result specified"); + + if (!base_version && need_base) + bad_value ("no base version specified"); + + if (!details_url && need_details) + bad_value ("no details url specified"); + } + + void review_manifest:: + serialize (serializer& s) const + { + // @@ Should we check that all non-optional values are specified and all + // values are valid? + // + s.next ("", "1"); // Start of manifest. + + auto bad_value ([&s](const string& d) { + throw serialization (s.name (), d);}); + + if (reviewed_by.empty ()) + bad_value ("empty reviewer"); + + s.next ("reviewed-by", reviewed_by); + + for (const review_aspect& r: results) + s.next ("result-" + r.name, to_string (r.result)); + + if (base_version) + s.next ("base-version", base_version->string ()); + + if (details_url) + s.next ("details-url", details_url->string ()); + + s.next ("", ""); // End of manifest. + } + + // review_manifests + // + review_manifests:: + review_manifests (parser& p, bool iu) + { + // Parse review manifests. + // + for (name_value nv (p.next ()); !nv.empty (); nv = p.next ()) + emplace_back (p, move (nv), iu); + } + + void review_manifests:: + serialize (serializer& s) const + { + // Serialize review manifests. + // + for (const review_manifest& m: *this) + m.serialize (s); + + s.next ("", ""); // End of stream. + } +} diff --git a/libbrep/review-manifest.hxx b/libbrep/review-manifest.hxx new file mode 100644 index 0000000..260fdec --- /dev/null +++ b/libbrep/review-manifest.hxx @@ -0,0 +1,80 @@ +// file : libbrep/review-manifest.hxx -*- C++ -*- +// license : MIT; see accompanying LICENSE file + +#ifndef LIBBREP_REVIEW_MANIFEST_HXX +#define LIBBREP_REVIEW_MANIFEST_HXX + +#include <libbutl/manifest-forward.hxx> + +#include <libbpkg/manifest.hxx> + +#include <libbrep/types.hxx> +#include <libbrep/utility.hxx> + +namespace brep +{ + enum class review_result: uint8_t + { + pass, + fail, + unchanged + }; + + string + to_string (review_result); + + review_result + to_review_result (const string&); // May throw invalid_argument. + + inline ostream& + operator<< (ostream& os, review_result r) + { + return os << to_string (r); + } + + struct review_aspect + { + string name; // code, build, test, doc, etc + review_result result; + }; + + class review_manifest + { + public: + string reviewed_by; + vector<review_aspect> results; + optional<bpkg::version> base_version; + optional<url> details_url; + + review_manifest (string r, + vector<review_aspect> rs, + optional<bpkg::version> bv, + optional<url> u) + : reviewed_by (move (r)), + results (move (rs)), + base_version (move (bv)), + details_url (move (u)) {} + + public: + review_manifest () = default; + review_manifest (butl::manifest_parser&, bool ignore_unknown = false); + review_manifest (butl::manifest_parser&, + butl::manifest_name_value start, + bool ignore_unknown = false); + + void + serialize (butl::manifest_serializer&) const; + }; + + class review_manifests: public vector<review_manifest> + { + public: + review_manifests () = default; + review_manifests (butl::manifest_parser&, bool ignore_unknown = false); + + void + serialize (butl::manifest_serializer&) const; + }; +} + +#endif // LIBBREP_REVIEW_MANIFEST_HXX |