Add eslint rules and do a run
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.eslintignore
diff --git a/.eslintrc.json b/.eslintrc.json
index 61dd1c8..8adc172 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -4,7 +4,7 @@
"google"
],
"parserOptions": {
- "ecmaVersion": 8,
+ "ecmaVersion": 2018,
"sourceType": "module"
},
"env": {
@@ -235,4 +235,4 @@
}
}
]
-}
\ No newline at end of file
+}
diff --git a/BUILD b/BUILD
index 80fb03d..7d3467f 100644
--- a/BUILD
+++ b/BUILD
@@ -1,5 +1,6 @@
load("@npm//@bazel/rollup:index.bzl", "rollup_bundle")
load("//tools/bzl:js.bzl", "bundle_assets", "polygerrit_plugin")
+load("//tools/js:eslint.bzl", "eslint")
polygerrit_plugin(
name = "zuul_results_summary",
@@ -19,3 +20,24 @@
"@tools_npm//rollup-plugin-node-resolve",
],
)
+
+# Define the eslinter for the plugin
+# The eslint macro creates 2 rules: lint_test and lint_bin
+eslint(
+ name = "lint",
+ srcs = glob([
+ "zuul-results-summary/**/*.js",
+ ]),
+ config = ".eslintrc.json",
+ data = [],
+ extensions = [
+ ".js",
+ ],
+ ignore = ".eslintignore",
+ plugins = [
+ "@npm//eslint-config-google",
+ "@npm//eslint-plugin-html",
+ "@npm//eslint-plugin-import",
+ "@npm//eslint-plugin-jsdoc",
+ ],
+)
diff --git a/zuul-results-summary/zuul-results-summary.js b/zuul-results-summary/zuul-results-summary.js
index 1bf9de4..5de9e0a 100644
--- a/zuul-results-summary/zuul-results-summary.js
+++ b/zuul-results-summary/zuul-results-summary.js
@@ -12,22 +12,21 @@
// License for the specific language governing permissions and limitations
// under the License.
-let ZUUL_PRIORITY = [ 22348 ];
+const ZUUL_PRIORITY = [22348];
/*
* Tab contents
*/
class ZuulSummaryStatusTab extends Polymer.Element {
+ static get properties() {
+ return {
+ change: Object,
+ revision: Object,
+ };
+ }
- static get properties() {
- return {
- change: Object,
- revision: Object
- }
- }
-
- static get template() {
- return Polymer.html`
+ static get template() {
+ return Polymer.html`
<style>
table {
table-layout: fixed;
@@ -92,179 +91,180 @@
</table>
</div>
</template>`;
- }
+ }
- _match_message_via_tag(message) {
- return (message.tag &&
+ _match_message_via_tag(message) {
+ return (message.tag &&
message.tag.startsWith('autogenerated:zuul')) ? true : false;
- }
+ }
- _match_message_via_regex(message) {
- // TODO: allow this to be passed in via config
- let authorRe = /^(?<author>.* CI|Zuul)/;
- let author = authorRe.exec(message.author.name);
- return author ? true : false;
- }
+ _match_message_via_regex(message) {
+ // TODO: allow this to be passed in via config
+ const authorRe = /^(?<author>.* CI|Zuul)/;
+ const author = authorRe.exec(message.author.name);
+ return author ? true : false;
+ }
- _get_status_and_pipeline(message) {
- /* Look for the full Zuul-3ish build status message, e.g.:
+ _get_status_and_pipeline(message) {
+ /* Look for the full Zuul-3ish build status message, e.g.:
* Build succeeded (check pipeline).
*/
- let statusRe = /^Build (?<status>\w+) \((?<pipeline>[\w]+) pipeline\)\./gm
- let statusMatch = statusRe.exec(message.message);
- if (!statusMatch) {
- /* Match non-pipeline CI comments, e.g.:
+ const statusRe = /^Build (?<status>\w+) \((?<pipeline>[\w]+) pipeline\)\./gm;
+ let statusMatch = statusRe.exec(message.message);
+ if (!statusMatch) {
+ /* Match non-pipeline CI comments, e.g.:
* Build succeeded.
*/
- let statusRe = /^Build (?<status>\w+)\./gm
- statusMatch = statusRe.exec(message.message)
- }
- if (!statusMatch) {
- return false; // we can't parse this
- }
-
- let status = statusMatch.groups.status
- let pipeline = statusMatch.groups.pipeline ?
- statusMatch.groups.pipeline : 'unknown';
- return [status, pipeline]
+ const statusRe = /^Build (?<status>\w+)\./gm;
+ statusMatch = statusRe.exec(message.message);
+ }
+ if (!statusMatch) {
+ return false; // we can't parse this
}
- ready() {
- super.ready();
+ const status = statusMatch.groups.status;
+ const pipeline = statusMatch.groups.pipeline ?
+ statusMatch.groups.pipeline : 'unknown';
+ return [status, pipeline];
+ }
- /*
- * change-view-tab-content gets passed ChangeInfo object [1],
- * registered in the property "change". We walk the list of
- * messages with some regexps to extract into a datastructure
- * stored in __table
- *
- * __table is an [] of objects
- *
- * author: "<string> CI"
- * date: date message posted
- * status: one of <succeeded|failed>
- * pipeline: string of reporting pipeline
- * (may be undefined for some CI)
- * results: [] of objects
- * job: job name
- * link: raw URL link to logs
- * result: one of <SUCCESS|FAILURE>
- * time: duration of run in human string (e.g. 2m 5s)
- *
- * This is then presented by the template
- *
- * [1] https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-info
- */
- this.__table = [];
- this.change.messages.forEach((message) => {
+ ready() {
+ super.ready();
- if (! (this._match_message_via_tag(message) ||
+ /*
+ * change-view-tab-content gets passed ChangeInfo object [1],
+ * registered in the property "change". We walk the list of
+ * messages with some regexps to extract into a datastructure
+ * stored in __table
+ *
+ * __table is an [] of objects
+ *
+ * author: "<string> CI"
+ * date: date message posted
+ * date_string: printable version of date
+ * revision: the revision the patchset was made against
+ * rechecks: the number of times we've seen the same
+ * ci run for the same revision
+ * status: one of <succeeded|failed>
+ * pipeline: string of reporting pipeline
+ * (may be undefined for some CI)
+ * results: [] of objects
+ * job: job name
+ * link: raw URL link to logs
+ * result: one of <SUCCESS|FAILURE>
+ * time: duration of run in human string (e.g. 2m 5s)
+ *
+ * This is then presented by the template
+ *
+ * [1] https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-info
+ */
+ this.__table = [];
+ this.change.messages.forEach(message => {
+ if (! (this._match_message_via_tag(message) ||
this._match_message_via_regex(message))) {
- return;
- }
+ return;
+ }
- const date = new Date(message.date);
- const revision = message._revision_number;
- const sp = this._get_status_and_pipeline(message);
- if (!sp) {
- // This shouldn't happen as we've validated it is a Zuul message.
- return;
- }
- const status = sp[0];
- const pipeline = sp[1];
+ const date = new Date(message.date);
+ const revision = message._revision_number;
+ const sp = this._get_status_and_pipeline(message);
+ if (!sp) {
+ // This shouldn't happen as we've validated it is a Zuul message.
+ return;
+ }
+ const status = sp[0];
+ const pipeline = sp[1];
- // We only want the latest entry for each CI system in
- // each pipeline
- const existing = this.__table.findIndex(entry =>
- (entry.author_id === message.author._account_id) &&
+ // We only want the latest entry for each CI system in
+ // each pipeline
+ const existing = this.__table.findIndex(entry =>
+ (entry.author_id === message.author._account_id) &&
(entry.pipeline === pipeline));
- // If this is a comment by the same CI on the same pipeline and
- // the same revision, it's considered a "recheck" ... i.e. likely
- // manually triggered to run again. Take a note of this.
- let rechecks = 0
- if (existing != -1) {
- if (this.__table[existing].revision === revision) {
- rechecks = this.__table[existing].rechecks + 1;
- }
- }
+ // If this is a comment by the same CI on the same pipeline and
+ // the same revision, it's considered a "recheck" ... i.e. likely
+ // manually triggered to run again. Take a note of this.
+ let rechecks = 0;
+ if (existing != -1) {
+ if (this.__table[existing].revision === revision) {
+ rechecks = this.__table[existing].rechecks + 1;
+ }
+ }
- /* Find each result line, e.g. :
- * - openstack-tox-py35 http://... : SUCCESS in 2m 45
- */
- let results = [];
- const lines = message.message.split("\n");
- const resultRe = /^- (?<job>[^ ]+) (?<link>[^ ]+) : (?<result>[^ ]+) in (?<time>.*)/
- lines.forEach((line) => {
- const result = resultRe.exec(line);
- if (result) {
- results.push(result.groups);
- }
- });
+ // Find each result line, e.g. :
+ // - openstack-tox-py35 http://... : SUCCESS in 2m 45
+ const results = [];
+ const lines = message.message.split('\n');
+ const resultRe = /^- (?<job>[^ ]+) (?<link>[^ ]+) : (?<result>[^ ]+) in (?<time>.*)/;
+ lines.forEach(line => {
+ const result = resultRe.exec(line);
+ if (result) {
+ results.push(result.groups);
+ }
+ });
- const table = {
- 'author_name': message.author.name,
- 'author_id': message.author._account_id,
- 'revision': revision,
- 'rechecks': rechecks,
- 'date': date,
- 'date_string': date.toLocaleString(),
- 'status': status,
- 'succeeded': status === 'succeeded' ? true : false,
- 'pipeline': pipeline,
- 'results': results
- }
+ const table = {
+ author_name: message.author.name,
+ author_id: message.author._account_id,
+ revision,
+ rechecks,
+ date,
+ date_string: date.toLocaleString(),
+ status,
+ succeeded: status === 'succeeded' ? true : false,
+ pipeline,
+ results,
+ };
- if (existing == -1) {
- this.__table.push(table);
- } else {
- this.__table[existing] = table;
- }
+ if (existing == -1) {
+ this.__table.push(table);
+ } else {
+ this.__table[existing] = table;
+ }
- // Sort first by listed priority, then by date
- this.__table.sort((a, b) => {
- // >>> 0 is just a trick to convert -1 to uint max
- // of 2^32-1
- let p_a = ZUUL_PRIORITY.indexOf(a.author_id) >>> 0;
- let p_b = ZUUL_PRIORITY.indexOf(b.author_id) >>> 0;
- let priority = p_a - p_b;
- let date = b.date - a.date;
- return priority || date;
- });
- });
- }
+ // Sort first by listed priority, then by date
+ this.__table.sort((a, b) => {
+ // >>> 0 is just a trick to convert -1 to uint max
+ // of 2^32-1
+ const p_a = ZUUL_PRIORITY.indexOf(a.author_id) >>> 0;
+ const p_b = ZUUL_PRIORITY.indexOf(b.author_id) >>> 0;
+ const priority = p_a - p_b;
+ const date = b.date - a.date;
+ return priority || date;
+ });
+ });
+ }
}
customElements.define('zuul-summary-status-tab',
- ZuulSummaryStatusTab);
+ ZuulSummaryStatusTab);
/*
* Tab Header Element
*/
class ZuulSummaryStatusTabHeader extends Polymer.Element {
- static get template() {
- return Polymer.html`Zuul Summary`;
- }
- }
+ static get template() {
+ return Polymer.html`Zuul Summary`;
+ }
+}
customElements.define('zuul-summary-status-tab-header',
- ZuulSummaryStatusTabHeader);
-
+ ZuulSummaryStatusTabHeader);
/*
* Install plugin
*/
Gerrit.install(plugin => {
- 'use strict';
-
- plugin.registerDynamicCustomComponent(
- 'change-view-tab-header',
- 'zuul-summary-status-tab-header'
- );
+ 'use strict';
- plugin.registerDynamicCustomComponent(
- 'change-view-tab-content',
- 'zuul-summary-status-tab'
- );
+ plugin.registerDynamicCustomComponent(
+ 'change-view-tab-header',
+ 'zuul-summary-status-tab-header'
+ );
+
+ plugin.registerDynamicCustomComponent(
+ 'change-view-tab-content',
+ 'zuul-summary-status-tab'
+ );
});