Merge branch 'stable-3.0'
* stable-3.0:
Simple Task UI
Change-Id: I37a7f4ce1ae6e6c354415b5c206175f37674d6b9
diff --git a/.gitignore b/.gitignore
index deb830a..da5cb24 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,5 +7,6 @@
/.settings/org.eclipse.m2e.core.prefs
/.settings/org.eclipse.core.resources.prefs
/.settings/org.eclipse.jdt.core.prefs
-
+/package-lock.json
/task.iml
+/node_modules/
diff --git a/BUILD b/BUILD
index 614546f..5a2eb90 100644
--- a/BUILD
+++ b/BUILD
@@ -1,4 +1,10 @@
-load("//tools/bzl:plugin.bzl", "gerrit_plugin")
+load(
+ "//tools/bzl:plugin.bzl",
+ "PLUGIN_DEPS",
+ "gerrit_plugin",
+)
+load("//tools/bzl:genrule2.bzl", "genrule2")
+load("//tools/bzl:js.bzl", "polygerrit_plugin")
gerrit_plugin(
name = "task",
@@ -10,5 +16,27 @@
"Implementation-URL: https://gerrit-review.googlesource.com/#/admin/projects/plugins/task",
"Gerrit-Module: com.googlesource.gerrit.plugins.task.Modules$Module",
],
+ resource_jars = [":gr-task-plugin-static"],
resources = glob(["src/main/resources/**/*"]),
)
+
+genrule2(
+ name = "gr-task-plugin-static",
+ srcs = [":gr-task-plugin"],
+ outs = ["gr-task-plugin-static.jar"],
+ cmd = " && ".join([
+ "mkdir $$TMP/static",
+ "cp -r $(locations :gr-task-plugin) $$TMP/static",
+ "cd $$TMP",
+ "zip -Drq $$ROOT/$@ -g .",
+ ]),
+)
+
+polygerrit_plugin(
+ name = "gr-task-plugin",
+ srcs = glob([
+ "gr-task-plugin/*.html",
+ "gr-task-plugin/*.js",
+ ]),
+ app = "plugin.html",
+)
diff --git a/WORKSPACE b/WORKSPACE
index 1458c37..43852f7 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -7,6 +7,32 @@
#local_path = "/home/<user>/projects/bazlets",
)
+# Polymer dependencies
+load(
+ "@com_googlesource_gerrit_bazlets//:gerrit_polymer.bzl",
+ "gerrit_polymer",
+)
+
+gerrit_polymer()
+
+# Load closure compiler with transitive dependencies
+load("@io_bazel_rules_closure//closure:defs.bzl", "closure_repositories")
+
+closure_repositories()
+
+# Load Gerrit npm_binary toolchain
+load("@com_googlesource_gerrit_bazlets//tools:js.bzl", "GERRIT", "npm_binary")
+
+npm_binary(
+ name = "polymer-bundler",
+ repository = GERRIT,
+)
+
+npm_binary(
+ name = "crisper",
+ repository = GERRIT,
+)
+
# Release Plugin API
load(
"@com_googlesource_gerrit_bazlets//:gerrit_api.bzl",
diff --git a/gr-task-plugin/.eslintrc.json b/gr-task-plugin/.eslintrc.json
new file mode 100644
index 0000000..b5d3dae
--- /dev/null
+++ b/gr-task-plugin/.eslintrc.json
@@ -0,0 +1,80 @@
+{
+ "extends": ["eslint:recommended", "google"],
+ "parserOptions": {
+ "ecmaVersion": 8
+ },
+ "env": {
+ "browser": true,
+ "es6": true
+ },
+ "globals": {
+ "__dirname": false,
+ "app": false,
+ "page": false,
+ "Polymer": false,
+ "process": false,
+ "require": false,
+ "Gerrit": false,
+ "Promise": false,
+ "assert": false,
+ "test": false,
+ "flushAsynchronousOperations": false
+ },
+ "rules": {
+ "arrow-parens": ["error", "as-needed"],
+ "block-spacing": ["error", "always"],
+ "brace-style": ["error", "1tbs", { "allowSingleLine": true }],
+ "camelcase": "off",
+ "comma-dangle": ["error", "always-multiline"],
+ "eol-last": "off",
+ "indent": "off",
+ "indent-legacy": ["error", 2, {
+ "MemberExpression": 2,
+ "FunctionDeclaration": {"body": 1, "parameters": 2},
+ "FunctionExpression": {"body": 1, "parameters": 2},
+ "CallExpression": {"arguments": 2},
+ "ArrayExpression": 1,
+ "ObjectExpression": 1,
+ "SwitchCase": 1
+ }],
+ "keyword-spacing": ["error", { "after": true, "before": true }],
+ "max-len": [
+ "error",
+ 80,
+ 2,
+ {"ignoreComments": true}
+ ],
+ "new-cap": ["error", { "capIsNewExceptions": ["Polymer"] }],
+ "no-console": "off",
+ "no-restricted-syntax": [
+ "error",
+ {
+ "selector": "ExpressionStatement > CallExpression > MemberExpression[object.name='test'][property.name='only']",
+ "message": "Remove test.only."
+ },
+ {
+ "selector": "ExpressionStatement > CallExpression > MemberExpression[object.name='suite'][property.name='only']",
+ "message": "Remove suite.only."
+ }
+ ],
+ "no-undef": "off",
+ "no-useless-escape": "off",
+ "no-var": "error",
+ "object-shorthand": ["error", "always"],
+ "prefer-arrow-callback": "error",
+ "prefer-const": "error",
+ "prefer-promise-reject-errors": "off",
+ "prefer-spread": "error",
+ "quote-props": ["error", "consistent-as-needed"],
+ "require-jsdoc": "off",
+ "semi": [2, "always"],
+ "template-curly-spacing": "error",
+ "valid-jsdoc": "off"
+ },
+ "plugins": [
+ "html"
+ ],
+ "settings": {
+ "html/report-bad-indent": "error"
+ }
+}
diff --git a/gr-task-plugin/gr-task-plugin.html b/gr-task-plugin/gr-task-plugin.html
new file mode 100644
index 0000000..67c1319
--- /dev/null
+++ b/gr-task-plugin/gr-task-plugin.html
@@ -0,0 +1,55 @@
+<!--
+Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<dom-module id="gr-task-plugin">
+ <template>
+ <style>
+ ul { padding-left: 30px; }
+ h3 { padding-left: 5px; }
+ </style>
+
+ <div id="tasks" hidden$="[[!_tasks.length]]">
+ <h3>Tasks: (Needs + Blocked)</h3>
+ <ul>
+ <gr-task-plugin-tasks tasks="[[_tasks]]"></gr-task-plugin-tasks>
+ </ul>
+ </div>
+ </template>
+ <script src="gr-task-plugin.js"></script>
+</dom-module>
+
+<dom-module id="gr-task-plugin-tasks">
+ <template>
+ <template is="dom-repeat" as="task" items="[[tasks]]">
+ <template is="dom-if" if="[[task.message]]">
+ <li>[[task.message]]</li>
+ </template>
+ <gr-task-plugin-tasks tasks="[[task.sub_tasks]]"></gr-task-plugin-tasks>
+ </template>
+ </template>
+ <script>
+ Polymer({
+ is: 'gr-task-plugin-tasks',
+ properties: {
+ tasks: {
+ type: Array,
+ notify: true,
+ value() { return []; },
+ },
+ },
+ });
+ </script>
+</dom-module>
diff --git a/gr-task-plugin/gr-task-plugin.js b/gr-task-plugin/gr-task-plugin.js
new file mode 100644
index 0000000..9fca732
--- /dev/null
+++ b/gr-task-plugin/gr-task-plugin.js
@@ -0,0 +1,89 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+(function() {
+ 'use strict';
+
+ const Defs = {};
+ /**
+ * @typedef {{
+ * message: string,
+ * sub_tasks: Array<Defs.Task>,
+ * hint: ?string,
+ * name: string,
+ * status: string
+ * }}
+ */
+ Defs.Task;
+
+ Polymer({
+ is: 'gr-task-plugin',
+ properties: {
+ change: {
+ type: Object,
+ },
+
+ // @type {Array<Defs.Task>}
+ _tasks: {
+ type: Array,
+ notify: true,
+ value() { return []; },
+ },
+ },
+
+ attached() {
+ this._getTasks();
+ },
+
+ _getTasks() {
+ const endpoint =
+ `/changes/?q=change:${this.change._number}&--task--applicable`;
+
+ return this.plugin.restApi().get(endpoint).then(response => {
+ if (response && response.length === 1) {
+ const cinfo = response[0];
+ if (cinfo.plugins) {
+ const taskPluginInfo = cinfo.plugins.find(
+ pluginInfo => pluginInfo.name === 'task');
+
+ if (taskPluginInfo) {
+ this._tasks = this._addTasks(taskPluginInfo.roots);
+ }
+ }
+ }
+ });
+ },
+
+ _getTaskDescription(task) {
+ return task.hint || task.name;
+ },
+
+ _computeMessage(task) {
+ switch (task.status) {
+ case 'FAIL':
+ case 'READY':
+ case 'INVALID':
+ return this._getTaskDescription(task);
+ }
+ },
+
+ _addTasks(tasks) { // rename to process, remove DOM bits
+ if (!tasks) return [];
+ tasks.forEach(task => {
+ task.message = this._computeMessage(task);
+ this._addTasks(task.sub_tasks);
+ });
+ return tasks;
+ },
+ });
+})();
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..4fe838a
--- /dev/null
+++ b/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "task",
+ "version": "2.16.13-SNAPSHOT",
+ "description": "Task Plugin",
+ "dependencies": {},
+ "devDependencies": {
+ "eslint": "^6.6.0",
+ "eslint-config-google": "^0.13.0",
+ "eslint-plugin-html": "^6.0.0"
+ },
+ "scripts": {
+ "eslint": "./node_modules/eslint/bin/eslint.js --ext .html,.js gr-task-plugin || exit 0",
+ "eslintfix": "./node_modules/eslint/bin/eslint.js --fix --ext .html,.js gr-task-plugin || exit 0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://gerrit.googlesource.com/plugins/task"
+ },
+ "author": "",
+ "license": "Apache-2.0"
+}
diff --git a/plugin.html b/plugin.html
new file mode 100644
index 0000000..9d3144c
--- /dev/null
+++ b/plugin.html
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<link rel="import" href="./gr-task-plugin/gr-task-plugin.html">
+
+<dom-module id="task-plugin">
+ <script>
+ if (window.Polymer) {
+ Gerrit.install(function(plugin) {
+ plugin.registerCustomComponent(
+ 'change-view-integration', 'gr-task-plugin');
+ });
+ }
+ </script>
+</dom-module>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/Modules.java b/src/main/java/com/googlesource/gerrit/plugins/task/Modules.java
index 6ef2ba6..ee960cc 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/Modules.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/Modules.java
@@ -15,6 +15,9 @@
package com.googlesource.gerrit.plugins.task;
import com.google.gerrit.extensions.annotations.Exports;
+import com.google.gerrit.extensions.registration.DynamicSet;
+import com.google.gerrit.extensions.webui.JavaScriptPlugin;
+import com.google.gerrit.extensions.webui.WebUiPlugin;
import com.google.gerrit.server.DynamicOptions.DynamicBean;
import com.google.gerrit.server.change.ChangeAttributeFactory;
import com.google.gerrit.server.restapi.change.QueryChanges;
@@ -36,6 +39,7 @@
bind(DynamicBean.class).annotatedWith(Exports.named(Query.class)).to(MyOptions.class);
bind(DynamicBean.class).annotatedWith(Exports.named(QueryChanges.class)).to(MyOptions.class);
+ DynamicSet.bind(binder(), WebUiPlugin.class).toInstance(new JavaScriptPlugin("gr-task-plugin.html"));
}
}
diff --git a/tools/bzl/genrule2.bzl b/tools/bzl/genrule2.bzl
new file mode 100644
index 0000000..e223dcd
--- /dev/null
+++ b/tools/bzl/genrule2.bzl
@@ -0,0 +1,2 @@
+load("@com_googlesource_gerrit_bazlets//tools:genrule2.bzl", _genrule2 = "genrule2")
+genrule2 = _genrule2
diff --git a/tools/bzl/js.bzl b/tools/bzl/js.bzl
new file mode 100644
index 0000000..ec1e08a
--- /dev/null
+++ b/tools/bzl/js.bzl
@@ -0,0 +1,2 @@
+load("@com_googlesource_gerrit_bazlets//tools:js.bzl", _polygerrit_plugin = "polygerrit_plugin")
+polygerrit_plugin = _polygerrit_plugin