Merge "Allow plugins to reference groups in project config"
diff --git a/Documentation/dev-plugins.txt b/Documentation/dev-plugins.txt
index 26072e3..e9ba824 100644
--- a/Documentation/dev-plugins.txt
+++ b/Documentation/dev-plugins.txt
@@ -766,6 +766,17 @@
 can be notified when this configuration parameter is updated on a
 project.
 
+[[configuring-groups]]
+=== Referencing groups in `project.config`
+
+Plugins can refer to groups so that when they are renamed, the project
+config will also be updated in this section. The proper format to use is
+the string representation of a GroupReference, as shown below.
+
+----
+Group[group_name / group_uuid]
+----
+
 [[project-specific-configuration]]
 == Project Specific Configuration in own config file
 
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupReference.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupReference.java
index c261fdd..3362ba2 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupReference.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupReference.java
@@ -27,6 +27,14 @@
     return new GroupReference(group.getGroupUUID(), group.getName());
   }
 
+  public static GroupReference fromString(String ref) {
+    String name =
+        ref.substring(ref.indexOf("[") + 1, ref.lastIndexOf("/")).trim();
+    String uuid =
+        ref.substring(ref.lastIndexOf("/") + 1, ref.lastIndexOf("]")).trim();
+    return new GroupReference(new AccountGroup.UUID(uuid), name);
+  }
+
   protected String uuid;
   protected String name;
 
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
index 4c26fc1..addbc1b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
@@ -778,6 +778,17 @@
       Config pluginConfig = new Config();
       pluginConfigs.put(plugin, pluginConfig);
       for (String name : rc.getNames(PLUGIN, plugin)) {
+        String value = rc.getString(PLUGIN, plugin, name);
+        if (value.startsWith("Group[")) {
+          GroupReference refFromString = GroupReference.fromString(value);
+          GroupReference ref = groupList.byUUID(refFromString.getUUID());
+          if (ref == null) {
+            ref = refFromString;
+            error(new ValidationError(PROJECT_CONFIG,
+                "group \"" + ref.getName() + "\" not in " + GroupList.FILE_NAME));
+          }
+          rc.setString(PLUGIN, plugin, name, ref.toString());
+        }
         pluginConfig.setStringList(PLUGIN, plugin, name,
             Arrays.asList(rc.getStringList(PLUGIN, plugin, name)));
       }
@@ -847,9 +858,9 @@
     saveContributorAgreements(rc, keepGroups);
     saveAccessSections(rc, keepGroups);
     saveNotifySections(rc, keepGroups);
+    savePluginSections(rc, keepGroups);
     groupList.retainUUIDs(keepGroups);
     saveLabelSections(rc);
-    savePluginSections(rc);
 
     saveConfig(PROJECT_CONFIG, rc);
     saveGroupList();
@@ -1101,7 +1112,7 @@
     }
   }
 
-  private void savePluginSections(Config rc) {
+  private void savePluginSections(Config rc, Set<AccountGroup.UUID> keepGroups) {
     List<String> existing = Lists.newArrayList(rc.getSubsections(PLUGIN));
     for (String name : existing) {
       rc.unsetSection(PLUGIN, name);
@@ -1111,6 +1122,14 @@
       String plugin = e.getKey();
       Config pluginConfig = e.getValue();
       for (String name : pluginConfig.getNames(PLUGIN, plugin)) {
+        String value = pluginConfig.getString(PLUGIN, plugin, name);
+        if (value.startsWith("Group[")) {
+          GroupReference ref = resolve(GroupReference.fromString(value));
+          if (ref.getUUID() != null) {
+            keepGroups.add(ref.getUUID());
+            pluginConfig.setString(PLUGIN, plugin, name, ref.toString());
+          }
+        }
         rc.setStringList(PLUGIN, plugin, name,
             Arrays.asList(pluginConfig.getStringList(PLUGIN, plugin, name)));
       }