Variety of fixes all over the place
authorSergey Sharybin <sergey.vfx@gmail.com>
Sat, 20 Jun 2015 19:15:24 +0000 (21:15 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Sat, 20 Jun 2015 19:23:19 +0000 (21:23 +0200)
Makes buildbot more usable, but still tweaks are needed.

templates/build.html
templates/build_line.html
templates/builder.html [new file with mode: 0644]
templates/buildslave.html
templates/forms.html
templates/grid.html [new file with mode: 0644]
templates/grid_transposed.html [new file with mode: 0644]
templates/waterfall.html [new file with mode: 0644]

index 684c1ba..38889d6 100644 (file)
@@ -5,7 +5,7 @@
 {% block content %}
 <div class="container">
 
-<h1>
+<h1 style="white-space: nowrap;">
 Builder <a href="{{ path_to_builder }}">{{ b.getBuilder().getName() }}</a>
 Build #{{ b.getNumber() }}
 </h1>
@@ -51,43 +51,42 @@ SourceStamps:
 <div class="col-md-4">
 <div class="box">
 <h3>{{ ss.codebase }}</h3>
-
     <table class="table table-striped table-hover box">
     {% set ss_class = cycler('alt','') %}
 
     {% if ss.project %}
-      <tr class="{{ ss_class.next() }}"><td class="left">Project</td><td>{{ ss.project|projectlink }}</td></tr>
+      <tr class="{{ ss_class.next() }}"><td>Project</td><td>{{ ss.project|projectlink }}</td></tr>
     {% endif %}
 
     {% if ss.repository %}
-      <tr class="{{ ss_class.next() }}"><td class="left">Repository</td><td>{{ ss.repository|repolink }}</td></tr>
+      <tr class="{{ ss_class.next() }}"><td>Repository</td><td>{{ ss.repository|repolink }}</td></tr>
     {% endif %}
 
     {% if ss.branch %}
-      <tr class="{{ ss_class.next() }}"><td class="left">Branch</td><td>{{ ss.branch|e }}</td></tr>
+      <tr class="{{ ss_class.next() }}"><td>Branch</td><td>{{ ss.branch|e }}</td></tr>
     {% endif %}
 
     {% if ss.revision %}
-      <tr class="{{ ss_class.next() }}"><td class="left">Revision</td><td>{{ ss.revision|revlink(ss.repository) }}</td></tr>
+      <tr class="{{ ss_class.next() }}"><td>Revision</td><td>{{ ss.revision|revlink(ss.repository) }}</td></tr>
     {% endif %}
 
     {% if got_revisions[ss.codebase] %}
-      <tr class="{{ ss_class.next() }}"><td class="left">Got Revision</td><td>{{ got_revisions[ss.codebase]|revlink(ss.repository) }}</td></tr>
+      <tr class="{{ ss_class.next() }}"><td>Got Revision</td><td>{{ got_revisions[ss.codebase]|revlink(ss.repository) }}</td></tr>
     {% endif %}
 
     {% if ss.patch %}
-      <tr class="{{ ss_class.next() }}"><td class="left">Patch</td><td>YES</td></tr>
+      <tr class="{{ ss_class.next() }}"><td>Patch</td><td>YES</td></tr>
     {% endif %}
 
     {% if ss.changes %}
-      <tr class="{{ ss_class.next() }}"><td class="left">Changes</td><td><a href="#changes-{{ ss.codebase }}">{{ ss.changes|count }} change{{ 's' if ss.changes|count > 1 else '' }}</a></td></tr>
+      <tr class="{{ ss_class.next() }}"><td>Changes</td><td><a href="#changes-{{ ss.codebase }}">{{ ss.changes|count }} change{{ 's' if ss.changes|count > 1 else '' }}</a></td></tr>
     {% endif %}
 
     {% if not ss.branch and not ss.revision and not ss.patch and not ss.changes %}
-      <tr class="{{ ss_class.next() }}"><td class="left" colspan="2">Build of most recent revision</td></tr>
+      <tr class="{{ ss_class.next() }}"><td colspan="2" align="center">Build of most recent revision</td></tr>
     {% endif %}
     </table>
-       </div></div>
+</div></div>
 {% endfor %}
 </div>
 {% endfor %}
@@ -121,27 +120,28 @@ SourceStamps:
  #                       (target, ex_url_class, html.escape(name)))
  #}
 
+{# TODO(sergey): Move hardcoded span with inline-block into a CSS class. #}
+
 <ol>
 {% for s in steps %}
   <li>
-    <div class="{{ s.css_class }} result">
-      <a href="{{ s.link }}">{{ s.name }}</a> 
-         <span class="pull-right label label-info">{{ s.text }} &nbsp;
-{{ '( ' + s.time_to_run + ' )' if s.time_to_run else '' }}</span>
-    </div>
-
+    <span style="display: inline-block; width: 40%;"><a href="{{ s.link }}">{{ s.name }}</a></span>
+    <span style="display: inline-block; width: 25%;">
+      <span class="label label-info">{{ s.text }} &nbsp; {{ '( ' + s.time_to_run + ' )' if s.time_to_run else '' }}</span>
+    </span>
+    <span style="display: inline-block; width: 30%; padding-left: 12pt;">
     <ol>
       {% set item_class = cycler('alt', '') %}
       {% for l in s.logs %}
-        <li class="{{ item_class.next() }}"><a class="btn btn-default" href="{{ l.link }}">{{ l.name }}</a></li>
+        <a class="btn btn-default" href="{{ l.link }}">{{ l.name }}</a>
       {% else %}
-        <li class="{{ item_class.next() }}"><a class="btn btn-default disabled" href="#" >- no logs -</a></li>
+        <a class="btn btn-default disabled" href="#" >- no logs -</a>
       {% endfor %}
-    
       {% for u in s.urls %}
-        <li class="{{ item_class.next() }}"><a class="btn btn-default" href="{{ u.url }}">{{ u.logname }}</a></li>
+        <a class="btn btn-default" href="{{ u.url }}">{{ u.logname }}</a>
       {% endfor %}
-    </ol>  
+    </ol>
+    </span>
   </li>
 {% endfor %}
 </ol>
@@ -151,13 +151,13 @@ SourceStamps:
 
 <h2>Build Properties:</h2>
 
-<table class="table">
+<table class="table table-striped table-hover box">
 <tr><th>Name</th><th>Value</th><th>Source</th></tr>
 
 {% for p in properties %}
 {% if p.source != "Force Build Form" %}
   <tr class="{{ loop.cycle('alt', '') }}">
-    <td class="left">{{ p.name|e }}</td>
+    <td>{{ p.name|e }}</td>
     {% if p.short_value %}
         <td>{{ p.short_value|e }} .. [property value too long]</td>
     {% else %}
@@ -165,7 +165,7 @@ SourceStamps:
             <td>{{ p.value|e }}</td>
         {% else %}
             <td>
-                <table class="table">
+                <table class="table table-striped table-hove">
                     {%- for key, value in p.value.items() recursive %}
                         <tr><td>{{ key|e }}</td><td>{{ value|e }}</td></tr>
                     {% endfor %}
@@ -179,14 +179,14 @@ SourceStamps:
 {% endfor %}
 </table>
 <h2>Forced Build Properties:</h2>
-<table class="table">
+<table class="table table-striped table-hover box">
 <tr><th>Name</th><th>Label</th><th>Value</th></tr>
 
 {% for p in properties %}
     {% if p.source == "Force Build Form" %}
   <tr class="{{ loop.cycle('alt', '') }}">
-    <td class="left">{{ p.name|e }}</td>
-    <td class="left">
+    <td>{{ p.name|e }}</td>
+    <td>
     {% if p.label %}
     {{ p.label }}
     {% endif %}    
@@ -215,12 +215,12 @@ SourceStamps:
 
 
 <h2>Timing:</h2>
-<table class="table">
-  <tr class="alt"><td class="left">Start</td><td>{{ start }}</td></tr>
+<table class="table table-striped table-hover box">
+  <tr class="alt"><td>Start</td><td>{{ start }}</td></tr>
 {% if end %}
-  <tr><td class="left">End</td><td>{{ end }}</td></tr>
+  <tr><td>End</td><td>{{ end }}</td></tr>
 {% endif %}
-  <tr {{ 'class="alt"' if end else '' }}><td class="left">Elapsed</td><td>{{ elapsed }}</td></tr>
+  <tr {{ 'class="alt"' if end else '' }}><td>Elapsed</td><td>{{ elapsed }}</td></tr>
 </table>
 
   {% if authz.advertiseAction('forceBuild', request) %}
index 71be846..63d2117 100644 (file)
 
 {% macro build_tr(b, include_builder=False, loop=None) %}
   <tr class="{{ loop.cycle('alt', '') if loop }}">
-    <td>{{ b.time }}</td>
+    <td><span style="white-space: nowrap;">{{ b.time }}</span></td>
     <td>{%- for rev in b.rev_list -%}
           {%- if not loop.first %}<br/>{% endif -%}
           {%- if rev.get('codebase', '') %}<span class='codebase'>{{ rev['codebase'] }}</span>:&nbsp;{% endif -%}
           {{ rev['rev']|shortrev(rev['repo']) }}
         {%- endfor -%}
     </td>
-    <td><span class="btn-{% if b.class ==  "success" %}{{ b.class }}{% else %}danger{% endif %} btn  btn-block btn-squishy disabled">{{ b.results }}</span></td>
+    <td style="padding: 0;"><span class="btn-{% if b.class ==  "success" %}{{ b.class }}{% else %}danger{% endif %} btn  btn-block btn-squishy disabled">{{ b.results }}</span></td>
   {%- if include_builder %}    
-    <td><a class="btn btn-block btn-squishy" href="{{ b.builderurl }}">{{ b.builder_name }}</a></td>
+    <td><a class="info" style="white-space: nowrap;" href="{{ b.builderurl }}">{{ b.builder_name }}</a></td>
   {% endif %}
-    <td><a class="btn btn-block btn-squishy" href="{{ b.buildurl }}">#{{ b.buildnum }}</a></td> 
+    <td><a class="info" style="white-space: nowrap;" href="{{ b.buildurl }}">#{{ b.buildnum }}</a></td> 
     <td><span class='reason'>{{ b.reason|e }}</span>
       {%- for user in (b.interested_users or []) -%}
         {%- if not loop.first %}, {% endif -%}
         <span class='interested_user'>{{ user|e }}</span>
       {%- endfor -%}
     </td> 
-    <td class="left">{{ b.text|capitalize }}</td>
+    <td><span style="white-space: nowrap;">{{ b.text|capitalize }}</span></td>
   </tr>
 {% endmacro %}
 
 {% macro build_table(builds, include_builder=False) %}
 {% if builds %}
-<table class="table"> 
+<table class="table table-striped table-hover box"> 
   <tr>
     <th>Time</th>
     <th>Revision</th>
@@ -47,7 +47,7 @@
      {%- if include_builder %}   
     <th>Builder</th>
      {% endif %}
-    <th>Build #</th>
+    <th style="white-space: nowrap;">Build #</th>
     <th>Reason</th>
     <th>Info</th>
   </tr>
diff --git a/templates/builder.html b/templates/builder.html
new file mode 100644 (file)
index 0000000..ec3ea7a
--- /dev/null
@@ -0,0 +1,124 @@
+{% from 'build_line.html' import build_table %}
+{% import 'forms.html' as forms %}
+
+{% extends "layout.html" %}
+{% block content %}
+
+<h1>Builder {{ name }}</h1>
+
+<p>(<a href="{{ path_to_root }}waterfall?show={{ name }}">view in waterfall</a>)</p>
+
+{% if description %}
+  <div class="BuilderDescription">{{ description }}</div>
+{% endif %}
+
+<div class="column">
+
+{% if current %}
+  <h2>Current Builds:</h2>
+  <ul>
+  {% for b in current %}
+    <li><a href="{{ b.link }}">{{ b.num }}</a>
+    {% if b.when %}
+      ETA: {{ b.when_time }} [{{ b.when }}]
+    {% endif %}
+
+    {{ b.current_step }}
+
+    {% if authz.advertiseAction('stopBuild', request) %}
+      {{ forms.stop_build(b.stop_url, authz, on_all=False, short=True, label='Build') }}
+    {% endif %}    
+    </li>
+  {% endfor %}
+  </ul>
+{% else %}
+  <h2>No current builds</h2>
+{% endif %}    
+{% if pending %}
+  <h2>Pending Build Requests:</h2>
+  <ul>
+  {% for b in pending %}
+    <li><small>({{ b.when }}, waiting {{ b.delay }})</small> 
+    
+    {% if authz.advertiseAction('cancelPendingBuild', request) %}
+      {{ forms.cancel_pending_build(builder_url+"/cancelbuild", authz, short=True, id=b.id) }}
+    {% endif %}    
+    
+    {% if b.num_changes < 4 %}
+        {% for c in b.changes %}{{ c.revision|shortrev(c.repo) }}
+        (<a href="{{ c.url }}">{{ c.who|email }}</a>){% if not loop.last %},{% endif %}
+        {% endfor %}
+    {% else %}
+        ({{ b.num_changes }} changes)
+    {% endif %}    
+
+      {% if 'owner' in b.properties %}
+        <b>Forced build</b>
+        by {{b.properties['owner'][0]}}
+        {% if 'reason' in b.properties %}
+          <small>{{b.properties['reason'][0]}}</small>
+        {% endif %}
+      {% endif %}
+    </li>
+  {% endfor %}
+  </ul>  
+  
+  {% if authz.advertiseAction('cancelPendingBuild', request) %}
+    {{ forms.cancel_pending_build(builder_url+"/cancelbuild", authz, short=False, id='all') }}
+  {% endif %}    
+     
+{% else %}
+  <h2>No Pending Build Requests</h2>
+{% endif %}
+
+<h2>Recent Builds:</h2>
+
+{{ build_table(recent) }}
+
+<a href="?numbuilds={{numbuilds + 5}}">Show more</a>
+
+</div>
+<div class="column">
+
+<h2>Buildslaves:</h2>
+<table class="table table-striped table-hover box">
+{% if slaves %}
+<tr>
+  <th>Name</th>
+  <th>Status</th>
+  <th>Admin</th>
+</tr>
+{% endif %}
+{% for s in slaves %}
+  <tr class="{{ loop.cycle('alt', '') }}">
+  <td><b><a href="{{ s.link|e }}">{{ s.name|e }}</a></b></td>
+  {% if s.connected %}
+    {% if s.paused %}
+      <td class="paused">paused</td>
+    {% else %}
+      <td class="idle">connected</td>
+    {% endif %}
+  {% else %}
+    <td class="offline">offline</td> 
+  {% endif %}
+  <td>{{ s.admin|email if s.admin else ""}}</td>
+  </tr>
+{% else %}
+  <td>no slaves attached</td>
+{% endfor %}
+</table>
+
+{% if authz.advertiseAction('pingBuilder', request) %}
+  <h2>Ping slaves</h2>
+  {{ forms.ping_builder(builder_url+"/ping", authz) }}
+{% endif %}
+
+{% if authz.advertiseAction('forceBuild', request) and force_schedulers != {} %}
+  <h2>Force build</h2>
+  {{ forms.force_build(builder_url+"/force", authz, request, False, force_schedulers=force_schedulers,default_props=default_props) }}
+{% endif %}
+
+</div>
+
+{% endblock %}
index b323a77..c53cab0 100644 (file)
@@ -5,7 +5,7 @@
 {% block content %}
 <h1>Buildslave: {{ slavename|e }}</h1>
 
-<div class="col-md-6">
+<div>
 
 {% if current %}
   <h2>Currently building:</h2>
@@ -27,7 +27,7 @@
 {{ build_table(recent, True) }}
   
 </div>
-<div class="col-md-6">
+<div>
 {% if access_uri %}
   <a href="{{ access_uri|e }}">Click to Access Slave</a>
 {% endif %}
index 44422aa..5a52975 100644 (file)
   {% endif %}
 {% endmacro %}
 
+{# TODO(sergey): Move hardcoded span with inline-block into a CSS class. #}
+
 {% macro force_build_scheduler_parameter(f, authz, request, sch, default_props) %}
     {% if f and not f.hide and (f.fullName != "username" or not authz.authenticated(request)) %}
-    <div class="row{% for subtype in f.type %} force-{{subtype}}{%endfor%}"{% if f.name %} id="force-{{sch.name}}-{{f.fullName}}"{% endif %}>
+    <div class="{% for subtype in f.type %} force-{{subtype}}{%endfor%}"{% if f.name %} id="force-{{sch.name}}-{{f.fullName}}"{% endif %}><p>
     {% if 'text' in f.type or 'int' in f.type %}
-       <span class="label">{{f.label}}</span>
+       <span style="display: inline-block; width: 20%;">{{f.label}}</span>
        <input type='text' size='{{f.size}}' name='{{f.fullName}}' value='{{default_props[sch.name+"."+f.fullName]}}' />
     {% elif 'bool' in f.type%}
        <input type='checkbox' name='checkbox' value='{{f.fullName}}' {{default_props[sch.name+"."+f.fullName]}} />
        <span class="label">{{f.label}}</span>
        <textarea name='{{f.fullName}}' rows={{f.rows}} cols={{f.cols}}>{{default_props[sch.name+"."+f.fullName]}}</textarea>
     {% elif 'list' in f.type %}
-       <span class="label">{{f.label}}</span>
+       <span style="display: inline-block; width: 20%;">{{f.label}}</span>
        <span class="select">
        <select name='{{f.fullName}}' {{ f.multiple and "multiple" or ""}}>
          {% for c in default_props[sch.name+"."+f.fullName+".choices"] %}
        </select>
        </span>
     {% elif 'nested' in f.type %}
-      {% if f.label %}<span class="label">{{f.label}}</span>{% endif %}
+      {% if f.label %}<span>{{f.label}}</span>{% endif %}
       {% for subfield in f.fields %}
         {{ force_build_scheduler_parameter(subfield, authz, request, sch, default_props) }}
       {% endfor %}
     {% endif %}
-    </div>
+    </p></div>
   {% endif %}
 {% endmacro %}
 
   {% for f in sch.all_fields %}
     {{ force_build_scheduler_parameter(f, authz, request, sch, default_props) }}
   {% endfor %}
-
-  <input class="btn btn-default btn-success btn-squishy" type="submit" value="{{ sch.buttonName }}" />
+  <hr>
+  <p><input class="btn btn-default btn-success btn-squishy btn-block" type="submit" value="{{ sch.buttonName }}" /></p>
  </form>
 {% endmacro %}
 {% macro force_build(force_url, authz, request, on_all=False, on_selected=False, builders=[], force_schedulers={},default_props={}) %}
+  <div class="box">
   {% for name, sch in force_schedulers.items() | sort %}
     {{ force_build_one_scheduler(force_url, authz, request, on_all, on_selected, builders, sch, default_props=default_props) }}
   {% endfor %}
-
+  </div>
 {% endmacro %}
 
 {% macro graceful_shutdown(shutdown_url, authz) %}
 
 {% macro rebuild_build(rebuild_url, authz, ss) %}
  <form method="post" action="{{ rebuild_url }}" class="form-horizontal rebuild">
-
+<div class="box">
   {% if on_all %}
      <p>To force a build on <strong>all Builders</strong>, fill out the following fields
           and push the 'Force Build' button</p>
   {% else %}
      <p>To force a build, fill out the following fields and
-        push the 'Force Build' button</p>
+        push the 'Rebuild' button</p>
   {% endif %}
-   <div class="row">
-     <span class="label">Reason for re-running build:</span>
+   <p>
+     <span style="display: inline-block; width: 20%;">Reason for re-running build:</span>
      <input type='text' name='comments' />
-   </div>
-   <div class="row">
-     Rebuild using:
+   </p>
+   <p>
+     <span style="display: inline-block; width: 20%;">Rebuild using:</span>
      <select name="useSourcestamp">
         <option value='exact' selected>Exact same revisions</option>
         <option value='updated'>Same sourcestamps (ignoring 'got revision')</option>
      </select>
-   </div>
-   <input class="btn btn-default btn-success btn-squishy" type="submit" value="Rebuild" />
+   </p>
+   <hr>
+   <p><input class="btn btn-default btn-success btn-squishy btn-block" type="submit" value="Rebuild" /></p>
+</div>
  </form>
 {% endmacro %}
 
diff --git a/templates/grid.html b/templates/grid.html
new file mode 100644 (file)
index 0000000..e37b59d
--- /dev/null
@@ -0,0 +1,31 @@
+{% extends "layout.html" %}
+{% import 'grid_macros.html' as grid with context %}
+
+{% block content %}
+
+<h1>Grid View</h1>
+
+<table class="Grid table table-striped table-hover box" border="0" cellspacing="0">
+
+<tr>
+ <td class="title"><a href="{{ title_url }}">{{ title }}</a>
+  {{ grid.category_title() }}
+ </td>
+
+ {% for s in stamps %}
+  {{ grid.stamp_td(s) }}
+ {% endfor %}
+</tr>
+
+{% for builder in builders %}
+ <tr>
+ {{ grid.builder_td(builder) }}
+ {% for build in builder.builds %}
+   {{ grid.build_td(build) }}
+ {% endfor %}
+ </tr>
+{% endfor %}
+
+</table>
+
+{% endblock %}
diff --git a/templates/grid_transposed.html b/templates/grid_transposed.html
new file mode 100644 (file)
index 0000000..82655e9
--- /dev/null
@@ -0,0 +1,30 @@
+{% extends "layout.html" %}
+{% import 'grid_macros.html' as grid with context %}
+
+{% block content %}
+
+<h1>Transposed Grid View</h1>
+
+<table class="Grid table table-striped table-hover box" border="0" cellspacing="0">
+
+<tr>
+ <td class="title"><a href="{{ title_url }}">{{ title }}</a>
+  {{ grid.category_title() }}
+ </td>
+ {% for builder in builders %}
+  {{ grid.builder_td(builder) }}
+ {% endfor %}
+</tr>
+
+{% for i in range %}
+ <tr>
+ {{ grid.stamp_td(stamps[i]) }}
+ {% for b in builder_builds %}
+   {{ grid.build_td(b[i]) }}
+ {% endfor %}
+ </tr>
+{% endfor %}
+
+</table>
+
+{% endblock %}
diff --git a/templates/waterfall.html b/templates/waterfall.html
new file mode 100644 (file)
index 0000000..d8738db
--- /dev/null
@@ -0,0 +1,66 @@
+{% extends "layout.html" %}
+{% from "box_macros.html" import box %}
+
+{% block content %}
+
+<div>
+  <h1 style="display: inline;">Waterfall</h1>
+  <a style="float: right;" href="{{ help_url }}">waterfall help</a>
+</div>
+
+<table border="0" cellspacing="0" class="table">
+
+<tr class="LastBuild">
+  <td align="right" colspan="2" class="Project">
+   last build
+  </td>
+
+{% for b in builders %}  
+  <td align="center" class="{{ b.top_class }}">
+    <a href="{{ b.url }}">{{ b.name }}</a><br/>
+    {{ " ".join(b.top) }}
+  </td>
+{% endfor %}
+</tr>
+
+<tr class="Activity">
+<td align="right" colspan="2">current activity</td>
+
+{% for b in builders %}  
+  <td align="center" class="{{ b.status_class }}">
+    {{ "<br/>".join(b.status) }}
+  </td>
+{% endfor %}
+</tr>
+
+<tr>
+<td align="center" class="Time">{{ tz }}</td>
+<td align="center" class="Change"><a href="{{ changes_url }}">changes</a></td>
+
+{% for b in builders %}
+ <td align="center" class="Builder"><a href="{{ b.url }}">{{ b.name }}</a></td>
+{% endfor %}
+</tr>
+
+{# waterfall contents goes here #}    
+{% for i in range(gridlen) -%}
+  <tr>
+  {% for strip in grid -%}        
+    {%- if strip[i] -%}{{ box(**strip[i]) }}
+    {%- elif no_bubble -%}{{ box() }}
+    {%- endif -%}
+  {%- endfor -%}
+  </tr>
+{% endfor %}
+
+</table>
+
+{% if nextpage %}
+ <a href="{{ nextpage }}">next page</a>
+{% endif %}
+
+{% if no_reload_page %}
+ <a href="{{ no_reload_page }}">Stop Reloading</a> 
+{% endif %}
+
+{% endblock %}