Add an in-progress key to tasks

For tasks with an in-progress key, add and evaluate an inProgress
attribute. This is useful to help prevent multiple instances of a CI
system from running at the same time.

Change-Id: Ib475932671b386bac705b382579bc902c0fc7990
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java b/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java
index c8d5bf8..ed6743f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java
@@ -43,6 +43,7 @@
   }
 
   public static class TaskAttribute {
+    public Boolean inProgress;
     public String name;
     public String readyHint;
     public Status status;
@@ -134,6 +135,9 @@
     try {
       if (match(c, def.applicable)) {
         TaskAttribute task = new TaskAttribute(def.name);
+        if (def.inProgress != null) {
+          task.inProgress = match(c, def.inProgress);
+        }
         task.subTasks = getSubTasks(c, path, def);
         task.status = getStatus(c, def, task);
         if (task.status == Status.READY) {
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 df4572e..818b0fa 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfig.java
@@ -26,6 +26,7 @@
   protected static final String SECTION_TASK = "task";
   protected static final String KEY_APPLICABLE = "applicable";
   protected static final String KEY_FAIL = "fail";
+  protected static final String KEY_IN_PROGRESS = "in-progress";
   protected static final String KEY_NAME = "name";
   protected static final String KEY_PASS = "pass";
   protected static final String KEY_READY_HINT = "ready-hint";
@@ -56,6 +57,7 @@
     TaskDefinition task = new TaskDefinition(branch, fileName);
     task.applicable = getString(s, KEY_APPLICABLE, null);
     task.fail = getString(s, KEY_FAIL, null);
+    task.inProgress = getString(s, KEY_IN_PROGRESS, null);
     task.name = getString(s, KEY_NAME, s.subSection);
     task.pass = getString(s, KEY_PASS, null);
     task.readyHint = getString(s, KEY_READY_HINT, null);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/TaskDefinition.java b/src/main/java/com/googlesource/gerrit/plugins/task/TaskDefinition.java
index b119132..491d88b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskDefinition.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskDefinition.java
@@ -24,6 +24,7 @@
 
   public String applicable;
   public String fail;
+  public String inProgress;
   public String name;
   public String readyHint;
   public String pass;
@@ -47,6 +48,7 @@
         && Objects.equals(fileName, t.fileName)
         && Objects.equals(applicable, t.applicable)
         && Objects.equals(fail, t.fail)
+        && Objects.equals(inProgress, t.inProgress)
         && Objects.equals(name, t.name)
         && Objects.equals(readyHint, t.readyHint)
         && Objects.equals(pass, t.pass)
@@ -55,6 +57,7 @@
 
   @Override
   public int hashCode() {
-    return Objects.hash(branch, fileName, applicable, fail, name, pass, readyHint, subTasks);
+    return Objects.hash(
+        branch, fileName, applicable, fail, inProgress, name, pass, readyHint, subTasks);
   }
 }
diff --git a/src/main/resources/Documentation/task.md b/src/main/resources/Documentation/task.md
index ba02d25..423ddef 100644
--- a/src/main/resources/Documentation/task.md
+++ b/src/main/resources/Documentation/task.md
@@ -86,6 +86,17 @@
     fail = label:verified-1
 ```
 
+`in-progress`
+
+: This key defines a query that is used to determine whether a task is
+currently in-progress or not. A CI system may use this to ensure that it
+only runs one verification instance for a specific change.
+
+Example:
+```
+    in-progress = label:patchset-lock,user=jenkins
+```
+
 `pass`
 
 : This key defines a query that is used to determine whether a task has
@@ -178,6 +189,7 @@
     name: task
     roots:
       name: Jenkins Build and Test
+      inProgress: false
       status: READY
       subTasks:
         name: code review
diff --git a/src/main/resources/Documentation/task_states.md b/src/main/resources/Documentation/task_states.md
index ecb18c3..9364620 100644
--- a/src/main/resources/Documentation/task_states.md
+++ b/src/main/resources/Documentation/task_states.md
@@ -231,10 +231,12 @@
                ]
             },
             {
+               "inProgress" : true,
                "name" : "Root IN PROGRESS",
                "status" : "READY"
             },
             {
+               "inProgress" : false,
                "name" : "Root NOT IN PROGRESS",
                "status" : "READY"
             }