aboutsummaryrefslogtreecommitdiff
path: root/mod
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2017-06-13 17:52:42 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2017-06-14 17:51:00 +0300
commit2b31e5cb109e2b009529e97f4fdb4a707cae14f2 (patch)
treeffa46e5d3eaddf151d795d1db6640f6f3cf94838 /mod
parentae4eb4360376a52866b4737ba8f0fc76255821a0 (diff)
Add builds to package version details page
Diffstat (limited to 'mod')
-rw-r--r--mod/mod-builds.cxx99
-rw-r--r--mod/mod-package-version-details.cxx57
-rw-r--r--mod/options.cli5
-rw-r--r--mod/page.cxx67
-rw-r--r--mod/page.hxx18
5 files changed, 167 insertions, 79 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<pair<string, string>> 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_count> (
build_query<build_count> (*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 () : "<default>")
<< 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 '<Prev' '1' 'Next>' 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 '<Prev' '1' 'Next>' links, and pass the offset as a
+ // URL query parameter. Alternatively, we can invent the page number cap.
//
using pkg_query = query<package_version>;
using prep_pkg_query = prepared_query<package_version>;
@@ -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 <web/module.hxx>
#include <web/mime-url-encoding.hxx>
+#include <libbrep/build.hxx>
+#include <libbrep/build-odb.hxx>
#include <libbrep/package.hxx>
#include <libbrep/package-odb.hxx>
@@ -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::build> (*options_),
+ static_cast<options::build_db> (*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<build>;
+
+ for (auto& b: build_db_->query<build> (
+ (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 () : "<default>"))
+ << 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 <libbrep/package.hxx>
#include <libbrep/package-odb.hxx>
+#include <mod/build-config.hxx> // 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 <libbrep/types.hxx>
#include <libbrep/utility.hxx>
+#include <libbrep/build.hxx>
#include <libbrep/package.hxx>
#include <mod/options-types.hxx> // 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