Fix subtasks-external lookup to not fail when preloaded from another file
Before this change, plugin failed to lookup a subtasks-external when
a task with this subtasks-external was preloaded using a task
reference [1]. While preloading a task, all the subtasks are copied
to the current task. Since the subtasks-external property was a String,
it does not maintain the information regarding the location of the
subtasks-external. Thus, fix this issue by using ConfigSourcedValue as
the type for subtasks-external property, which helps in tracking the
location of the subtasks-external. Add tests for the same.
[1]
file: `All-Projects:refs/meta/config:task.config`
```
[root "root task"]
applicable = status:open
preload-task = //common.config^simple task with subtasks
```
file: `All-Projects:refs/meta/config:task/common.config`
```
[task "simple task with subtasks"]
applicable = is:open
subtasks-external = user special tasks
[external "user special tasks"]
user = testuser
file = special.config
```
Change-Id: I1aff32ae5885c3969ef8fdce7c019d3b448109f5
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 aa25e7f..55d2f48 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfig.java
@@ -65,7 +65,7 @@
public Map<String, String> properties;
public String readyHint;
public List<ConfigSourcedValue> subTasks;
- public List<String> subTasksExternals;
+ public List<ConfigSourcedValue> subTasksExternals;
public List<ConfigSourcedValue> subTasksFactories;
public List<String> subTasksFiles;
@@ -90,7 +90,10 @@
getStringList(s, KEY_SUBTASK).stream()
.map(subTask -> ConfigSourcedValue.create(s.file(), subTask))
.collect(Collectors.toList());
- subTasksExternals = getStringList(s, KEY_SUBTASKS_EXTERNAL);
+ subTasksExternals =
+ getStringList(s, KEY_SUBTASKS_EXTERNAL).stream()
+ .map(subTask -> ConfigSourcedValue.create(s.file(), subTask))
+ .collect(Collectors.toList());
subTasksFactories =
getStringList(s, KEY_SUBTASKS_FACTORY).stream()
.map(subTask -> ConfigSourcedValue.create(s.file(), subTask))
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 01afb89..b34dccd 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java
@@ -397,9 +397,12 @@
}
protected void addSubTasksExternals() throws StorageException {
- for (String external : task.subTasksExternals) {
+ for (ConfigSourcedValue configSourcedValue : task.subTasksExternals) {
try {
- External ext = task.config.getExternal(external);
+ External ext =
+ taskConfigCache
+ .getTaskConfig(configSourcedValue.sourceFile())
+ .getExternal(configSourcedValue.value());
if (ext == null) {
addInvalidNode();
} else {
diff --git a/src/main/resources/Documentation/test/task_states.md b/src/main/resources/Documentation/test/task_states.md
index 4b296b2..273e21d 100644
--- a/src/main/resources/Documentation/test/task_states.md
+++ b/src/main/resources/Documentation/test/task_states.md
@@ -2553,6 +2553,68 @@
]
}
+[root "Root Preload from all-projects sub-dir which has subtasks-external in same file"]
+ preload-task = //dir/common.config^Sample relative task in sub dir with subtasks-external from same file
+
+{
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "Root Preload from all-projects sub-dir which has subtasks-external in same file",
+ "status" : "WAITING",
+ "subTasks" : [
+ {
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "userfile task/special.config PASS",
+ "status" : "PASS"
+ },
+ {
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "userfile task/special.config FAIL",
+ "status" : "FAIL"
+ },
+ {
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "file task/common.config Preload PASS",
+ "status" : "PASS"
+ },
+ {
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "Referencing single task from same user ref",
+ "status" : "PASS",
+ "subTasks" : [
+ {
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "Relative Task",
+ "status" : "PASS"
+ },
+ {
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "Relative Task in sub dir",
+ "status" : "PASS"
+ },
+ {
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "task in user root config file",
+ "status" : "PASS"
+ },
+ {
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "Absolute Task",
+ "status" : "PASS"
+ }
+ ]
+ }
+ ]
+}
+
[root "Root Preload from user ref"]
preload-task = @testuser/dir/relative.config^Relative Task
@@ -3299,6 +3361,21 @@
type = static
name = my d task
+[task "Sample relative task in sub dir with subtasks-external from same file"]
+ applicable = is:open
+ pass = is:open
+ set-my-external-prop = user sample config
+ subtasks-external = user special tasks
+ subtasks-external = ${my-external-prop}
+
+[external "user special tasks"]
+ user = testuser
+ file = special.config
+
+[external "user sample config"]
+ user = testuser
+ file = dir/sample.config
+
[task "Sample relative task in sub dir with subtask from different file"]
applicable = is:open
pass = is:open