From 2b31e5cb109e2b009529e97f4fdb4a707cae14f2 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 13 Jun 2017 17:52:42 +0300 Subject: Add builds to package version details page --- mod/mod-builds.cxx | 99 ++++++++---------------------------- mod/mod-package-version-details.cxx | 57 +++++++++++++++++++++ mod/options.cli | 5 +- mod/page.cxx | 67 ++++++++++++++++++++++++ mod/page.hxx | 18 +++++++ www/builds-body.css | 2 +- www/package-version-details-body.css | 36 +++++++++++++ 7 files changed, 204 insertions(+), 80 deletions(-) diff --git a/mod/mod-builds.cxx b/mod/mod-builds.cxx index e90e68f..354e5f5 100644 --- a/mod/mod-builds.cxx +++ b/mod/mod-builds.cxx @@ -328,9 +328,9 @@ handle (request& rq, response& rs) if (params.page () == 0) { // Populate the toolchains list with the distinct list of toolchain - // name/version pairs from all the existing package builds. Make sure the - // selected toolchain still present in the database. Otherwise fallback - // to the * wildcard selection. + // name/version pairs from all the existing package builds. Make sure + // the selected toolchain is still present in the database. Otherwise + // fallback to the * wildcard selection. // string ctc ("*"); vector> toolchain_opts ({{"*", "*"}}); @@ -408,12 +408,11 @@ handle (request& rq, response& rs) { transaction t (build_db_->begin ()); - // Having packages and packages configurations builds in different - // databases, we unable to filter out builds for non-existent packages at - // the query level. Doing that in the C++ code would complicate it + // Having packages and package configuration builds in different + // databases, we are unable to filter out builds for non-existent packages + // at the query level. Doing that in the C++ code would complicate it // significantly. So we will print all the builds, relying on the sorting - // algorithm, that will likely to place expired ones at the end of the - // query result. + // algorithm which will place expired ones at the end of the query result. // count = build_db_->query_value ( build_query (*build_conf_names_, params)); @@ -442,6 +441,9 @@ handle (request& rq, response& rs) true) + " (" + butl::to_string (now - b.timestamp, false) + " ago)"); + if (b.state == build_state::built) + build_db_->load (b, b.results_section); + s << TABLE(CLASS="proplist build") << TBODY << TR_NAME (b.package_name, string (), root) @@ -454,66 +456,7 @@ handle (request& rq, response& rs) << TR_VALUE ("target", b.target ? b.target->string () : "") << TR_VALUE ("timestamp", ts) - << TR(CLASS="result") - << TH << "result" << ~TH - << TD - << SPAN(CLASS="value"); - - if (b.state == build_state::building) - s << "building | "; - else - { - build_db_->load (b, b.results_section); - - // If no unsuccessful operations results available, then print the - // overall build status. If there are any operations results available, - // then also print unsuccessful operations statuses with the links to - // the respective logs, followed with a link to the operations combined - // log. Print the forced package rebuild link afterwards, unless the - // package build is already pending. - // - if (b.results.empty () || *b.status == result_status::success) - { - assert (b.status); - s << SPAN_BUILD_RESULT_STATUS (*b.status) << " | "; - } - - if (!b.results.empty ()) - { - for (const auto& r: b.results) - { - if (r.status != result_status::success) - s << SPAN_BUILD_RESULT_STATUS (r.status) << " (" - << A - << HREF - << build_log_url (host, root, b, &r.operation) - << ~HREF - << r.operation - << ~A - << ") | "; - } - - s << A - << HREF << build_log_url (host, root, b) << ~HREF - << "log" - << ~A - << " | "; - } - } - - if (b.force == (b.state == build_state::building - ? force_state::forcing - : force_state::forced)) - s << "pending"; - else - s << A - << HREF << force_rebuild_url (host, root, b) << ~HREF - << "rebuild" - << ~A; - - s << ~SPAN - << ~TD - << ~TR + << TR_BUILD_RESULT (b, host, root) << ~TBODY << ~TABLE; } @@ -618,10 +561,10 @@ handle (request& rq, response& rs) } } - // Calculate the number of unbuilt package configuration as a difference - // between the maximum possible number of unbuilt configurations and the - // number of configurations being in the built or building state (see - // above). + // Calculate the number of unbuilt package configurations as a + // difference between the maximum possible number of unbuilt + // configurations and the number of configurations being in the built or + // building state (see above). // transaction t (package_db_->begin ()); @@ -652,12 +595,12 @@ handle (request& rq, response& rs) // from the very beginning and skip the appropriate number of them while // iterating through the query result. // - // Note that such an approach has a security implication. HTTP request + // Note that such an approach has a security implication. An HTTP request // with a large page number will be quite expensive to process, as it - // effectively results in traversing all package versions and all the built - // configurations. To address this problem we may consider to reduce the - // pager to just '' links, and pass the offset as a URL - // query parameter. Alternatively, we may invent the page number cap. + // effectively results in traversing all the package versions and all the + // built configurations. To address this problem we may consider to reduce + // the pager to just '' links, and pass the offset as a + // URL query parameter. Alternatively, we can invent the page number cap. // using pkg_query = query; using prep_pkg_query = prepared_query; @@ -743,7 +686,7 @@ handle (request& rq, response& rs) { id = move (pv.id); - // Iterate through the package configurations builds and erase them + // Iterate through the package configuration builds and erase them // from the unbuilt configurations set. // // Make a copy for this package. diff --git a/mod/mod-package-version-details.cxx b/mod/mod-package-version-details.cxx index a359104..7dc02d2 100644 --- a/mod/mod-package-version-details.cxx +++ b/mod/mod-package-version-details.cxx @@ -14,6 +14,8 @@ #include #include +#include +#include #include #include @@ -45,6 +47,11 @@ init (scanner& s) database_module::init (*options_, options_->package_db_retry ()); + if (options_->build_config_specified ()) + database_module::init (static_cast (*options_), + static_cast (*options_), + options_->build_db_retry ()); + if (options_->root ().empty ()) options_->root (dir_path ("/")); } @@ -58,6 +65,7 @@ handle (request& rq, response& rs) MODULE_DIAG; + const string& host (options_->host ()); const dir_path& root (options_->root ()); auto i (rq.path ().rbegin ()); @@ -317,6 +325,55 @@ handle (request& rq, response& rs) << ~TABLE; } + // Don't display the section for stub packages. + // + if (build_db_ != nullptr && ver.compare (wildcard_version, true) != 0) + { + s << H3 << "Built" << ~H3 + << DIV(ID="built"); + + timestamp now (timestamp::clock::now ()); + transaction t (build_db_->begin ()); + + using query = query; + + for (auto& b: build_db_->query ( + (query::id.package.name == name && + compare_version_eq (query::id.package.version, ver, true) && + + query::id.configuration.in_range (build_conf_names_->begin (), + build_conf_names_->end ())) + + + "ORDER BY" + query::timestamp + "DESC")) + { + string ts (butl::to_string (b.timestamp, + "%Y-%m-%d %H:%M:%S %Z", + true, + true) + + " (" + butl::to_string (now - b.timestamp, false) + " ago)"); + + if (b.state == build_state::built) + build_db_->load (b, b.results_section); + + s << TABLE(CLASS="proplist build") + << TBODY + << TR_VALUE ("toolchain", + b.toolchain_name + '-' + + b.toolchain_version.string ()) + << TR_VALUE ("config", + b.configuration + " / " + b.machine + " / " + + (b.target ? b.target->string () : "")) + << TR_VALUE ("timestamp", ts) + << TR_BUILD_RESULT (b, host, root) + << ~TBODY + << ~TABLE; + } + + t.commit (); + + s << ~DIV; + } + const auto& ch (pkg->changes); if (!ch.empty ()) s << H3 << "Changes" << ~H3 diff --git a/mod/options.cli b/mod/options.cli index 7460ef7..05578bf 100644 --- a/mod/options.cli +++ b/mod/options.cli @@ -307,7 +307,10 @@ namespace brep { }; - class package_version_details: package, package_db, page, module + class package_version_details: package, package_db, + build, build_db, + page, + module { }; diff --git a/mod/page.cxx b/mod/page.cxx index 73c56be..291dfb4 100644 --- a/mod/page.cxx +++ b/mod/page.cxx @@ -18,6 +18,8 @@ #include #include +#include // build_log_url() + using namespace std; using namespace xml; using namespace web; @@ -584,6 +586,71 @@ namespace brep << ~TR; } + // BUILD_RESULT + // + void TR_BUILD_RESULT:: + operator() (serializer& s) const + { + s << TR(CLASS="result") + << TH << "result" << ~TH + << TD + << SPAN(CLASS="value"); + + if (build_.state == build_state::building) + s << "building | "; + else + { + // If no unsuccessful operation results available, then print the + // overall build status. If there are any operation results available, + // then also print unsuccessful operation statuses with the links to the + // respective logs, followed with a link to the operation's combined + // log. Print the forced package rebuild link afterwards, unless the + // package build is already pending. + // + if (build_.results.empty () || *build_.status == result_status::success) + { + assert (build_.status); + s << SPAN_BUILD_RESULT_STATUS (*build_.status) << " | "; + } + + if (!build_.results.empty ()) + { + for (const auto& r: build_.results) + { + if (r.status != result_status::success) + s << SPAN_BUILD_RESULT_STATUS (r.status) << " (" + << A + << HREF + << build_log_url (host_, root_, build_, &r.operation) + << ~HREF + << r.operation + << ~A + << ") | "; + } + + s << A + << HREF << build_log_url (host_, root_, build_) << ~HREF + << "log" + << ~A + << " | "; + } + } + + if (build_.force == (build_.state == build_state::building + ? force_state::forcing + : force_state::forced)) + s << "pending"; + else + s << A + << HREF << force_rebuild_url (host_, root_, build_) << ~HREF + << "rebuild" + << ~A; + + s << ~SPAN + << ~TD + << ~TR; + } + // SPAN_COMMENT // void SPAN_COMMENT:: diff --git a/mod/page.hxx b/mod/page.hxx index d7c44d6..dea2733 100644 --- a/mod/page.hxx +++ b/mod/page.hxx @@ -14,6 +14,7 @@ #include #include +#include #include #include // page_menu @@ -400,6 +401,23 @@ namespace brep const string& sha256sum_; }; + // Generates build results element. + // + class TR_BUILD_RESULT + { + public: + TR_BUILD_RESULT (const build& b, const string& h, const dir_path& r): + build_ (b), host_ (h), root_ (r) {} + + void + operator() (xml::serializer&) const; + + private: + const build& build_; + const string& host_; + const dir_path& root_; + }; + // Generates comment element. // class SPAN_COMMENT diff --git a/www/builds-body.css b/www/builds-body.css index a4b72fc..292a804 100644 --- a/www/builds-body.css +++ b/www/builds-body.css @@ -42,8 +42,8 @@ .build tr.name td .value, .build tr.version td .value, -.build tr.config td .value, .build tr.toolchain td .value, +.build tr.config td .value, .build tr.machine td .value, .build tr.target td .value, .build tr.timestamp td .value, diff --git a/www/package-version-details-body.css b/www/package-version-details-body.css index fffe9c2..e571206 100644 --- a/www/package-version-details-body.css +++ b/www/package-version-details-body.css @@ -161,6 +161,42 @@ h1, h2, h3 } /* + * Builds. + */ +#built {margin-bottom: 1em;} + +.build +{ + margin-top: .4em; + margin-bottom: .4em; + + padding-top: .4em; + padding-bottom: .4em; +} +.build:nth-child(even) {background-color: rgba(0, 0, 0, 0.07);} + +.build th +{ + width: 7.0em; +} + +.build tr.toolchain td .value, +.build tr.config td .value, +.build tr.timestamp td .value, +.build tr.result td .value +{ + /* style. */ + font-family: monospace; + font-size: 0.94em; +} + +.build .success {color: #00bb00;} +.build .warning {color: #ffa500;} +.build .error {color: #ff0000;} +.build .abort {color: #ff0000;} +.build .abnormal {color: #ff0000;} + +/* * Changes. * * This is a
 block that fits lines up to 80 characters long and
-- 
cgit v1.1