Merge changes Ifc67b7cb,Iadc9f544,I3e62af9e,I7ee1b63d,I61224c57, ... into stable-2.16 * changes: fixup! refactor predicate cache into its own class fixup! Add support for tasks-factory and names-factory keywords fixup! Support outputting elapsed evaluation time on tasks fixup! Revert "Revert "plugin:task Adds support for names-factory of type change"" Add a Container.toString() to help when debugging. Harden inputs to basename Fix to alter change context for TaskChangeFactories
diff --git a/src/main/java/com/google/gerrit/common/Container.java b/src/main/java/com/google/gerrit/common/Container.java index eb0a0f6..6e11534 100644 --- a/src/main/java/com/google/gerrit/common/Container.java +++ b/src/main/java/com/google/gerrit/common/Container.java
@@ -55,4 +55,21 @@ } return Objects.hash(values); } + + @Override + public String toString() { + List<String> fieldStrings = new ArrayList<>(); + try { + for (Field field : getClass().getDeclaredFields()) { + field.setAccessible(true); + fieldStrings.add(field.getName() + ": " + Objects.toString(field.get(this))); + } + } catch (IllegalArgumentException | IllegalAccessException e) { + } + String fields = String.join(", ", fieldStrings); + if (!"".equals(fields)) { + fields = "{" + fields + "}"; + } + return getClass().toString() + fields; + } }
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 f927d51..6346a73 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/task/Modules.java +++ b/src/main/java/com/googlesource/gerrit/plugins/task/Modules.java
@@ -68,7 +68,7 @@ public boolean onlyInvalid = false; @Option(name = "--evaluation-time", usage = "Include elapsed evaluation time on each task") - boolean evaluationTime = false; + public boolean evaluationTime = false; @Option( name = "--preview",
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/PredicateCache.java b/src/main/java/com/googlesource/gerrit/plugins/task/PredicateCache.java index 0921db1..aa3da13 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/task/PredicateCache.java +++ b/src/main/java/com/googlesource/gerrit/plugins/task/PredicateCache.java
@@ -59,7 +59,7 @@ if ("true".equalsIgnoreCase(query)) { return true; } - return cqb.parse(query).asMatchable().match(c); + return getPredicate(query).asMatchable().match(c); } protected Predicate<ChangeData> getPredicate(String query) throws QueryParseException {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfig.java b/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfig.java index 80effb5..8cd8022 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfig.java +++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfig.java
@@ -44,7 +44,7 @@ } } - private class Section extends Container { + protected class Section extends Container { public TaskConfig config; public Section() { @@ -58,7 +58,6 @@ public String fail; public String failHint; public String inProgress; - public String name; public String pass; public String preloadTask; public Map<String, String> properties; @@ -79,7 +78,6 @@ fail = getString(s, KEY_FAIL, null); failHint = getString(s, KEY_FAIL_HINT, null); inProgress = getString(s, KEY_IN_PROGRESS, null); - name = s.subSection; pass = getString(s, KEY_PASS, null); preloadTask = getString(s, KEY_PRELOAD_TASK, null); properties = getProperties(s, KEY_PROPERTIES_PREFIX); @@ -133,7 +131,7 @@ public Task(SubSection s, boolean isVisible, boolean isTrusted) { super(s, isVisible, isTrusted); - name = getString(s, KEY_NAME, s.subSection); + name = s.subSection; } protected Task(TaskBase base) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java b/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java index c023f04..ed9e7ee 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java +++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java
@@ -43,6 +43,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; +import java.util.function.BiFunction; import org.eclipse.jgit.errors.ConfigInvalidException; /** @@ -91,6 +92,14 @@ return root.getRootNodes(); } + public Node createNodeOrNull(NodeList parent, Task definition) { + try { + return new Node(parent, definition); + } catch (Exception e) { + return null; + } + } + protected class NodeList { protected NodeList parent = null; protected LinkedList<String> path = new LinkedList<>(); @@ -104,20 +113,21 @@ } protected void addSubDefinition(Task def) { + addSubDefinition(def, (d, c) -> createNodeOrNull(d, c)); + } + + protected void addSubDefinition(Task def, BiFunction<NodeList, Task, Node> nodeConstructor) { Node node = null; if (def != null && !path.contains(def.name) && names.add(def.name)) { // path check above detects looping definitions // names check above detects duplicate subtasks - try { - node = new Node(this, def); - } catch (Exception e) { - } // bad definition, handled with null + node = nodeConstructor.apply(this, def); } nodes.add(node); } public ChangeData getChangeData() { - return TaskTree.this.changeData; + return parent == null ? TaskTree.this.changeData : parent.getChangeData(); } protected Properties.Task getProperties() { @@ -244,7 +254,9 @@ .query(changeQueryBuilderProvider.get().parse(namesFactory.changes)) .entities(); for (ChangeData changeData : changeDataList) { - addSubDefinition(task.config.createTask(tasksFactory, changeData.getId().toString())); + addSubDefinition( + task.config.createTask(tasksFactory, changeData.getId().toString()), + new ChangeNodeFactory(changeData)::createChangeNodeOrNull); } return; } @@ -295,4 +307,31 @@ return new Branch.NameKey(allUsers.get(), RefNames.refsUsers(acct.getId())); } } + + public class ChangeNodeFactory { + public class ChangeNode extends Node { + public ChangeNode(NodeList parent, Task definition) + throws ConfigInvalidException, OrmException { + super(parent, definition); + } + + public ChangeData getChangeData() { + return ChangeNodeFactory.this.changeData; + } + } + + protected ChangeData changeData; + + public ChangeNodeFactory(ChangeData changeData) { + this.changeData = changeData; + } + + public ChangeNode createChangeNodeOrNull(NodeList parent, Task definition) { + try { + return new ChangeNode(parent, definition); + } catch (Exception e) { + return null; + } + } + } }
diff --git a/src/main/resources/Documentation/test/task_states.md b/src/main/resources/Documentation/test/task_states.md index fd7fb37..ea09541 100644 --- a/src/main/resources/Documentation/test/task_states.md +++ b/src/main/resources/Documentation/test/task_states.md
@@ -739,7 +739,7 @@ [root "Root tasks-factory static (empty name)"] subtasks-factory = tasks-factory static (empty name) -# Grouping task since it has no pass criteria, not output since it has no subtasks + # Grouping task since it has no pass criteria, not output since it has no subtasks [tasks-factory "tasks-factory static (empty name)"] names-factory = names-factory static (empty name list) @@ -971,13 +971,13 @@ [tasks-factory "tasks-factory CHANGE Properties"] set-welcome-message = Welcome to the pleasuredome - names-factory = names-factory my change + names-factory = names-factory a change fail-hint = ${welcome-message} Name(${_name}) Change Number(${_change_number}) Change Id(${_change_id}) Change Project(${_change_project}) Change Branch(${_change_branch}) Change Status(${_change_status}) Change Topic(${_change_topic}) fail = True -[names-factory "names-factory my change"] +[names-factory "names-factory a change"] type = change - changes = change:${_change_number} + changes = change:_change1_number OR change:_change2_number { "applicable" : true, @@ -988,8 +988,15 @@ { "applicable" : true, "hasPass" : true, - "hint" : "Welcome to the pleasuredome Name(_change_number) Change Number(_change_number) Change Id(_change_id) Change Project(_change_project) Change Branch(_change_branch) Change Status(_change_status) Change Topic(_change_topic)", - "name" : "_change_number", + "hint" : "Welcome to the pleasuredome Name(_change1_number) Change Number(_change1_number) Change Id(_change1_id) Change Project(_change1_project) Change Branch(_change1_branch) Change Status(_change1_status) Change Topic(_change1_topic)", + "name" : "_change1_number", + "status" : "FAIL" + }, + { + "applicable" : true, + "hasPass" : true, + "hint" : "Welcome to the pleasuredome Name(_change2_number) Change Number(_change2_number) Change Id(_change2_id) Change Project(_change2_project) Change Branch(_change2_branch) Change Status(_change2_status) Change Topic(_change2_topic)", + "name" : "_change2_number", "status" : "FAIL" } ]
diff --git a/test/docker/run_tests/wait-for-it.sh b/test/docker/run_tests/wait-for-it.sh index d7b6e3c..17436f2 100755 --- a/test/docker/run_tests/wait-for-it.sh +++ b/test/docker/run_tests/wait-for-it.sh
@@ -2,7 +2,7 @@ # https://github.com/vishnubob/wait-for-it/blob/master/wait-for-it.sh # Use this script to test if a given TCP host/port are available -cmdname=$(basename $0) +cmdname=$(basename -- "$0") echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }