Configure branches for ITS integration on init

Add an init step that allows to configure the branches for which the
issue tracker system should be enabled/enforced. Admins can specify a
branch name, a ref pattern or a regular expression. By default
'refs/heads/*' is proposed which excludes the refs/meta/config branch
which is not used for product development and hence normally commits
to it don't need to contain any associations to issues. Still if
refs/meta/config should be included the ref pattern can easily be
changed to 'ref/*'.

The init step only supports the configuration of a single value for
branch. If multiple values are already configured in the
'project.config' file of the All-Projects project the init step
refuses to change the configuration as it doesn't want to overwrite
other values. In this case the init step prints out a message saying
that the branch configuration has to be done manually in the
'project.config' file of the All-Projects project.

Change-Id: Ic815b069dfa600be071f6f27d440cb043e63507b
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
diff --git a/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/its/InitIts.java b/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/its/InitIts.java
index 18df41d..da65ff8 100644
--- a/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/its/InitIts.java
+++ b/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/its/InitIts.java
@@ -14,7 +14,10 @@
 
 package com.googlesource.gerrit.plugins.hooks.its;
 
+import com.google.common.base.Strings;
+import com.google.gerrit.common.data.RefConfigSection;
 import com.google.gerrit.pgm.init.AllProjectsConfig;
+import com.google.gerrit.pgm.init.AllProjectsNameOnInitProvider;
 import com.google.gerrit.pgm.init.InitStep;
 import com.google.gerrit.pgm.init.Section;
 import com.google.gerrit.pgm.util.ConsoleUI;
@@ -40,13 +43,16 @@
   private final String itsDisplayName;
   protected final ConsoleUI ui;
   private final AllProjectsConfig allProjectsConfig;
+  private final AllProjectsNameOnInitProvider allProjects;
 
   public InitIts(String pluginName, String itsDisplayName, ConsoleUI ui,
-      AllProjectsConfig allProjectsConfig) {
+      AllProjectsConfig allProjectsConfig,
+      AllProjectsNameOnInitProvider allProjects) {
     this.pluginName = pluginName;
     this.itsDisplayName = itsDisplayName;
     this.ui = ui;
     this.allProjectsConfig = allProjectsConfig;
+    this.allProjects = allProjects;
   }
 
   @Override
@@ -74,9 +80,11 @@
     switch (itsintegration) {
       case ENFORCED:
         cfg.setString("plugin", pluginName, "enabled", "enforced");
+        configureBranches(cfg);
         break;
       case ENABLED:
         cfg.setBoolean("plugin", pluginName, "enabled", true);
+        configureBranches(cfg);
         break;
       case DISABLED:
         cfg.unset("plugin", pluginName, "enabled");
@@ -88,6 +96,36 @@
     allProjectsConfig.save(pluginName, "Initialize " + itsDisplayName + " Integration");
   }
 
+  private void configureBranches(Config cfg) {
+    String[] branches = cfg.getStringList("plugin", pluginName, "branch");
+    if (branches.length > 1) {
+      ui.message("The issue tracker integration is configured for multiple branches."
+          + " Please adapt the configuration in the 'project.config' file of the '%s' project.\n",
+          allProjects.get());
+      return;
+    }
+
+    String branch = branches.length == 1 ? branches[0] : null;
+    if (Strings.isNullOrEmpty(branch)) {
+      branch = "refs/heads/*";
+    }
+
+    boolean validRef;
+    do {
+      String v = ui.readString(branch, "Branches for which the issue tracker integration"
+          + " should be enabled (ref, ref pattern or regular expression)");
+      validRef = RefConfigSection.isValid(v);
+      if (validRef) {
+        branch = v;
+      } else {
+        ui.message(
+            "'%s' is not valid. Please specify a valid ref, ref pattern or regular expression\n", v);
+      }
+    } while (!validRef);
+
+    cfg.setString("plugin", pluginName, "branch", branch);
+  }
+
   public boolean isConnectivityRequested(String url) {
     return ui.yesno(false, "Test connectivity to %s", url);
   }