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 }