Add logic to handle blank subtask and blank name in names-factory
Before the change, NPE was thrown in case the subtask or name field in
names-factory is blank. This makes the parent task invalid which is not
ideal. Add logic to handle these cases so that only the concerned task
is marked as invalid.
Change-Id: I1f8faf06f7bc55b6619a1ef40bd40ee98bd3b51b
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 0c3136e..be7f120 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfig.java
@@ -300,8 +300,9 @@
}
protected List<String> getStringList(SubSectionKey s, String key) {
- return Collections.unmodifiableList(
- Arrays.asList(cfg.getStringList(s.section(), s.subSection(), key)));
+ List<String> stringList = Arrays.asList(cfg.getStringList(s.section(), s.subSection(), key));
+ stringList.replaceAll(str -> str == null ? "" : str);
+ return Collections.unmodifiableList(stringList);
}
protected SubSectionKey subSectionKey(String section, String subSection) {
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 ac65a0f..501e9db 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java
@@ -58,6 +58,7 @@
import java.util.Optional;
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.util.StringUtils;
/**
* Add structure to access the task definitions from the config as a tree.
@@ -430,7 +431,11 @@
protected void addStaticTypeTasks(TasksFactory tasksFactory, NamesFactory namesFactory)
throws ConfigInvalidException, IOException, StorageException {
for (String name : namesFactory.names) {
- addPreloaded(preloader.preload(task.config.new Task(tasksFactory, name)));
+ if (StringUtils.isEmptyOrNull(name)) {
+ addInvalidNode();
+ } else {
+ addPreloaded(preloader.preload(task.config.new Task(tasksFactory, name)));
+ }
}
}
diff --git a/src/main/resources/Documentation/test/preview.md b/src/main/resources/Documentation/test/preview.md
index 6aff577..510f073 100644
--- a/src/main/resources/Documentation/test/preview.md
+++ b/src/main/resources/Documentation/test/preview.md
@@ -102,6 +102,18 @@
]
},
{
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "Subtask Blank",
+ "status" : "WAITING",
+ "subTasks" : [
+ {
+ "name" : "UNKNOWN",
+ "status" : "INVALID"
+ }
+ ]
+ },
+ {
"applicable" : false,
"hasPass" : true,
"name" : "NA Bad PASS query",
@@ -164,6 +176,18 @@
{
"applicable" : true,
"hasPass" : false,
+ "name" : "task (names-factory name Blank)",
+ "status" : "WAITING",
+ "subTasks" : [
+ {
+ "name" : "UNKNOWN",
+ "status" : "INVALID"
+ }
+ ]
+ },
+ {
+ "applicable" : true,
+ "hasPass" : false,
"name" : "task (names-factory duplicate)",
"status" : "WAITING",
"subTasks" : [
@@ -404,6 +428,18 @@
]
},
{
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "Subtask Blank",
+ "status" : "WAITING",
+ "subTasks" : [
+ {
+ "name" : "UNKNOWN",
+ "status" : "INVALID"
+ }
+ ]
+ },
+ {
"applicable" : false,
"hasPass" : true,
"name" : "NA Bad PASS query",
@@ -466,6 +502,18 @@
{
"applicable" : true,
"hasPass" : false,
+ "name" : "task (names-factory name Blank)",
+ "status" : "WAITING",
+ "subTasks" : [
+ {
+ "name" : "UNKNOWN",
+ "status" : "INVALID"
+ }
+ ]
+ },
+ {
+ "applicable" : true,
+ "hasPass" : false,
"name" : "task (names-factory duplicate)",
"status" : "WAITING",
"subTasks" : [
diff --git a/src/main/resources/Documentation/test/task_states.md b/src/main/resources/Documentation/test/task_states.md
index f48f528..f5d4cd8 100644
--- a/src/main/resources/Documentation/test/task_states.md
+++ b/src/main/resources/Documentation/test/task_states.md
@@ -2266,6 +2266,18 @@
]
},
{
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "Subtask Blank",
+ "status" : "WAITING",
+ "subTasks" : [
+ {
+ "name" : "UNKNOWN",
+ "status" : "INVALID"
+ }
+ ]
+ },
+ {
"applicable" : false,
"hasPass" : true,
"name" : "NA Bad PASS query",
@@ -2328,6 +2340,18 @@
{
"applicable" : true,
"hasPass" : false,
+ "name" : "task (names-factory name Blank)",
+ "status" : "WAITING",
+ "subTasks" : [
+ {
+ "name" : "UNKNOWN",
+ "status" : "INVALID"
+ }
+ ]
+ },
+ {
+ "applicable" : true,
+ "hasPass" : false,
"name" : "task (names-factory duplicate)",
"status" : "WAITING",
"subTasks" : [
@@ -2509,6 +2533,18 @@
]
},
{
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "Subtask Blank",
+ "status" : "WAITING",
+ "subTasks" : [
+ {
+ "name" : "UNKNOWN",
+ "status" : "INVALID"
+ }
+ ]
+ },
+ {
"applicable" : false,
"hasPass" : true,
"name" : "NA Bad PASS query",
@@ -2571,6 +2607,18 @@
{
"applicable" : true,
"hasPass" : false,
+ "name" : "task (names-factory name Blank)",
+ "status" : "WAITING",
+ "subTasks" : [
+ {
+ "name" : "UNKNOWN",
+ "status" : "INVALID"
+ }
+ ]
+ },
+ {
+ "applicable" : true,
+ "hasPass" : false,
"name" : "task (names-factory duplicate)",
"status" : "WAITING",
"subTasks" : [
@@ -2669,6 +2717,10 @@
[task "Subtask Optional"]
subtask = MISSING | MISSING
+[task "Subtask Blank"]
+ pass = True
+ subtask =
+
[task "NA Bad PASS query"]
applicable = NOT is:open # Assumes test query is "is:open"
fail = True
@@ -2699,6 +2751,9 @@
[task "task (names-factory type INVALID)"]
subtasks-factory = tasks-factory (names-factory type INVALID)
+[task "task (names-factory name Blank)"]
+ subtasks-factory = tasks-factory (names-factory name Blank)
+
[task "task (names-factory duplicate)"]
subtasks-factory = tasks-factory (names-factory duplicate)
@@ -2718,6 +2773,10 @@
[tasks-factory "tasks-factory (names-factory type INVALID)"]
names-factory = name-factory (type INVALID)
+[tasks-factory "tasks-factory (names-factory name Blank)"]
+ names-factory = names-factory (name Blank)
+ fail = True
+
[tasks-factory "tasks-factory (names-factory duplicate)"]
names-factory = names-factory duplicate
fail = True
@@ -2744,6 +2803,10 @@
name = invalid type test
type = invalid
+[names-factory "names-factory (name Blank)"]
+ name =
+ type = static
+
[names-factory "names-factory duplicate"]
name = duplicate
name = duplicate