Support importing tasks from All-Projects:refs/meta/config
This change adds support to import common tasks located from
All-Projects:refs/meta/config. See docs for syntax.
Change-Id: I83665cd0c8dc79c1b804c3b84aa51864446ceeee
diff --git a/src/main/antlr4/com/googlesource/gerrit/plugins/task/TaskReference.g4 b/src/main/antlr4/com/googlesource/gerrit/plugins/task/TaskReference.g4
index b360040..fc461d7 100644
--- a/src/main/antlr4/com/googlesource/gerrit/plugins/task/TaskReference.g4
+++ b/src/main/antlr4/com/googlesource/gerrit/plugins/task/TaskReference.g4
@@ -17,6 +17,7 @@
* This file defines the grammar used for Task Reference
*
* TASK_REFERENCE = [
+ * [ // TASK_FILE_PATH ] |
* [ @USERNAME [ TASK_FILE_PATH ] ] |
* [ TASK_FILE_PATH ]
* ] '^' TASK_NAME
@@ -53,6 +54,15 @@
* Implied task:
* file: All-Users:refs/users/<jim>:task/foo^simple task: sample
*
+ * file: Any projects, ref, file
+ * reference: //foo.config^sample
+ * Implied task:
+ * file: All-Projects:refs/meta/config:task/foo task: sample
+ *
+ * file: Any projects, ref, file
+ * reference: //^simple
+ * Implied task:
+ * file: All-Projects:refs/meta/config:task.config task: sample
*/
grammar TaskReference;
@@ -66,7 +76,9 @@
;
file_path
- : user absolute? TASK_DELIMETER
+ : ALL_PROJECTS_ROOT
+ | FWD_SLASH absolute TASK_DELIMETER
+ | user absolute? TASK_DELIMETER
| (absolute| relative)? TASK_DELIMETER
;
@@ -75,7 +87,7 @@
;
absolute
- : '/' relative
+ : FWD_SLASH relative
;
relative
@@ -83,7 +95,7 @@
;
dir
- : (NAME '/')
+ : (NAME FWD_SLASH)
;
TASK
@@ -110,3 +122,11 @@
TASK_DELIMETER
: '^'
;
+
+ALL_PROJECTS_ROOT
+ : FWD_SLASH FWD_SLASH TASK_DELIMETER
+ ;
+
+FWD_SLASH
+ : '/'
+ ;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/TaskKey.java b/src/main/java/com/googlesource/gerrit/plugins/task/TaskKey.java
index 8cddac0..a6bc7e1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskKey.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskKey.java
@@ -19,6 +19,7 @@
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.server.account.AccountCache;
+import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.AllUsersName;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -59,14 +60,20 @@
public static class Builder {
protected final AccountCache accountCache;
+ protected final AllProjectsName allProjectsName;
protected final AllUsersName allUsersName;
protected final FileKey relativeTo;
protected BranchNameKey branch;
protected String file;
protected String task;
- Builder(FileKey relativeTo, AllUsersName allUsersName, AccountCache accountCache) {
+ Builder(
+ FileKey relativeTo,
+ AllProjectsName allProjectsName,
+ AllUsersName allUsersName,
+ AccountCache accountCache) {
this.relativeTo = relativeTo;
+ this.allProjectsName = allProjectsName;
this.allUsersName = allUsersName;
this.accountCache = accountCache;
}
@@ -127,6 +134,10 @@
.id()));
}
+ public void setReferringAllProjectsTask() {
+ branch = BranchNameKey.create(allProjectsName, RefNames.REFS_CONFIG);
+ }
+
protected void throwIfInvalidPath() throws ConfigInvalidException {
Path path = Paths.get(file);
if (!path.startsWith(TaskFileConstants.TASK_DIR)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/TaskReference.java b/src/main/java/com/googlesource/gerrit/plugins/task/TaskReference.java
index 308bae8..91c6f10 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskReference.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskReference.java
@@ -16,6 +16,7 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.gerrit.server.account.AccountCache;
+import com.google.gerrit.server.config.AllProjectsNameProvider;
import com.google.gerrit.server.config.AllUsersNameProvider;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -42,11 +43,15 @@
@Inject
public TaskReference(
+ AllProjectsNameProvider allProjectsNameProvider,
AllUsersNameProvider allUsersNameProvider,
AccountCache accountCache,
@Assisted FileKey relativeTo,
@Assisted String reference) {
- this(new TaskKey.Builder(relativeTo, allUsersNameProvider.get(), accountCache), reference);
+ this(
+ new TaskKey.Builder(
+ relativeTo, allProjectsNameProvider.get(), allUsersNameProvider.get(), accountCache),
+ reference);
}
@VisibleForTesting
@@ -122,6 +127,10 @@
@Override
public void enterFile_path(TaskReferenceParser.File_pathContext ctx) {
+ if (ctx.ALL_PROJECTS_ROOT() != null || (ctx.FWD_SLASH() != null && ctx.absolute() != null)) {
+ builder.setReferringAllProjectsTask();
+ }
+
if (ctx.absolute() == null && ctx.relative() == null) {
try {
builder.setRefRootFile();
diff --git a/src/main/resources/Documentation/task_expression.md b/src/main/resources/Documentation/task_expression.md
index 498d2b4..66afaf8 100644
--- a/src/main/resources/Documentation/task_expression.md
+++ b/src/main/resources/Documentation/task_expression.md
@@ -38,6 +38,7 @@
```
TASK_REFERENCE = [
+ [ // TASK_FILE_PATH ]
[ @USERNAME [ TASK_FILE_PATH ] ] |
[ TASK_FILE_PATH ]
] '^' TASK_NAME
@@ -150,3 +151,33 @@
preload-task = @user_a_username/dir/common.config^common task
...
```
+
+To reference a task from root task.config on the All-Projects.git, prefix the task name with `//^`
+and to reference a task from task dir on the All-Projects.git, use
+`//<relative path from task dir>^<task_name>`. It doesn't matter which project, ref and file one
+is referencing from while using this syntax.
+
+Example:
+
+All-Projects:refs/meta/config:task.config
+```
+ ...
+ [task "root task"]
+ ...
+```
+
+All-Projects:refs/meta/config:/task/dir/sample.config
+
+```
+ ...
+ [task "sample task"]
+ ...
+```
+
+All-Users:refs/users/00/1000000:task.config
+```
+ ...
+ preload-task = //dir/sample.config^sample task
+ preload-task = //^root task
+ ...
+```
diff --git a/src/main/resources/Documentation/test/task_states.md b/src/main/resources/Documentation/test/task_states.md
index e325a9a..315b05f 100644
--- a/src/main/resources/Documentation/test/task_states.md
+++ b/src/main/resources/Documentation/test/task_states.md
@@ -2298,6 +2298,55 @@
]
}
+[root "Root Reference tasks from All-Projects"]
+ applicable = is:open
+ subtask = //^Subtask PASS
+ subtask = @testuser/dir/relative.config^Import All-Projects root task
+ subtask = @testuser/dir/relative.config^Import All-Projects non-root task
+
+{
+ "applicable" : true,
+ "hasPass" : false,
+ "name" : "Root Reference tasks from All-Projects",
+ "status" : "PASS",
+ "subTasks" : [
+ {
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "Subtask PASS",
+ "status" : "PASS"
+ },
+ {
+ "applicable" : true,
+ "hasPass" : false,
+ "name" : "Import All-Projects root task",
+ "status" : "PASS",
+ "subTasks" : [
+ {
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "Subtask PASS",
+ "status" : "PASS"
+ }
+ ]
+ },
+ {
+ "applicable" : true,
+ "hasPass" : false,
+ "name" : "Import All-Projects non-root task",
+ "status" : "PASS",
+ "subTasks" : [
+ {
+ "applicable" : true,
+ "hasPass" : true,
+ "name" : "Sample relative task in sub dir",
+ "status" : "PASS"
+ }
+ ]
+ }
+ ]
+}
+
[root "Root INVALID Preload"]
preload-task = missing
@@ -3114,6 +3163,14 @@
[task "Relative Task"]
applicable = is:open
pass = is:open
+
+[task "Import All-Projects root task"]
+ applicable = is:open
+ subtask = //^Subtask PASS
+
+[task "Import All-Projects non-root task"]
+ applicable = is:open
+ subtask = //dir/common.config^Sample relative task in sub dir
```
file: `All-Users:refs/users/self:task/dir/sub_dir/relative.config`
diff --git a/src/test/java/com/googlesource/gerrit/plugins/task/TaskExpressionTest.java b/src/test/java/com/googlesource/gerrit/plugins/task/TaskExpressionTest.java
index fe01ee2..87042a9 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/task/TaskExpressionTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/task/TaskExpressionTest.java
@@ -17,6 +17,7 @@
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.account.AccountCache;
+import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.AllUsersName;
import java.util.Iterator;
import java.util.NoSuchElementException;
@@ -239,6 +240,7 @@
new TaskReference(
new TaskKey.Builder(
(FileKey) invocation.getArguments()[0],
+ new AllProjectsName("All-Projects"),
new AllUsersName("All-Users"),
accountCache),
(String) invocation.getArguments()[1]));
diff --git a/src/test/java/com/googlesource/gerrit/plugins/task/TaskReferenceTest.java b/src/test/java/com/googlesource/gerrit/plugins/task/TaskReferenceTest.java
index 2036f16..9da1f44 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/task/TaskReferenceTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/task/TaskReferenceTest.java
@@ -17,8 +17,10 @@
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Project;
+import com.google.gerrit.entities.RefNames;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountState;
+import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.AllUsersName;
import java.sql.Timestamp;
import java.util.NoSuchElementException;
@@ -30,14 +32,17 @@
public class TaskReferenceTest extends TestCase {
private static final String ALL_USERS = "All-Users";
-
+ private static final String ALL_PROJECTS = "All-Projects";
public static String SIMPLE = "simple";
public static String ROOT = "task.config";
public static String COMMON = "task/common.config";
public static String SUB_COMMON = "task/dir/common.config";
- public static FileKey ROOT_CFG = createFileKey("project", "branch", ROOT);
- public static FileKey COMMON_CFG = createFileKey("project", "branch", COMMON);
- public static FileKey SUB_COMMON_CFG = createFileKey("project", "branch", SUB_COMMON);
+ public static FileKey ROOT_CFG = createFileKey(ALL_PROJECTS, RefNames.REFS_CONFIG, ROOT);
+ public static FileKey COMMON_CFG = createFileKey(ALL_PROJECTS, RefNames.REFS_CONFIG, COMMON);
+ public static FileKey SUB_COMMON_CFG =
+ createFileKey(ALL_PROJECTS, RefNames.REFS_CONFIG, SUB_COMMON);
+
+ public static FileKey SAMPLE_PROJ_CFG = createFileKey("foo", RefNames.REFS_CONFIG, ROOT);
public static final String TEST_USER = "testuser";
public static final int TEST_USER_ID = 100000;
@@ -93,6 +98,19 @@
}
@Test
+ public void testReferencingRootAllProjectsTask() throws Exception {
+ String reference = "//^" + SIMPLE;
+ assertEquals(createTaskKey(ROOT_CFG, SIMPLE), getTaskFromReference(SAMPLE_PROJ_CFG, reference));
+ }
+
+ @Test
+ public void testReferencingAllProjectsTask() throws Exception {
+ String reference = "//common.config^" + SIMPLE;
+ assertEquals(
+ createTaskKey(COMMON_CFG, SIMPLE), getTaskFromReference(SAMPLE_PROJ_CFG, reference));
+ }
+
+ @Test
public void testReferencingRootUserTask() throws Exception {
String reference = "@" + TEST_USER + "^" + SIMPLE;
assertEquals(
@@ -125,7 +143,12 @@
.thenReturn(Optional.of(AccountState.forAccount(TEST_USER_ACCOUNT)));
try {
return new TaskReference(
- new TaskKey.Builder(file, new AllUsersName(ALL_USERS), accountCache), expression)
+ new TaskKey.Builder(
+ file,
+ new AllProjectsName(ALL_PROJECTS),
+ new AllUsersName(ALL_USERS),
+ accountCache),
+ expression)
.getTaskKey();
} catch (ConfigInvalidException e) {
throw new NoSuchElementException();