Merge "Allow to set fallback code owners for a project via REST"
diff --git a/java/com/google/gerrit/plugins/codeowners/api/CodeOwnerProjectConfigInput.java b/java/com/google/gerrit/plugins/codeowners/api/CodeOwnerProjectConfigInput.java
index 684d715..e571724 100644
--- a/java/com/google/gerrit/plugins/codeowners/api/CodeOwnerProjectConfigInput.java
+++ b/java/com/google/gerrit/plugins/codeowners/api/CodeOwnerProjectConfigInput.java
@@ -14,6 +14,7 @@
 
 package com.google.gerrit.plugins.codeowners.api;
 
+import com.google.gerrit.plugins.codeowners.backend.FallbackCodeOwners;
 import java.util.List;
 
 /**
@@ -61,4 +62,7 @@
    * <p>The override approvals must be specified in the format {@code <label-name>+<label-value>}.
    */
   public List<String> overrideApprovals;
+
+  /** Policy that controls who should own paths that have no code owners defined. */
+  public FallbackCodeOwners fallbackCodeOwners;
 }
diff --git a/java/com/google/gerrit/plugins/codeowners/restapi/PutCodeOwnerProjectConfig.java b/java/com/google/gerrit/plugins/codeowners/restapi/PutCodeOwnerProjectConfig.java
index 1f2733a..69cf3db 100644
--- a/java/com/google/gerrit/plugins/codeowners/restapi/PutCodeOwnerProjectConfig.java
+++ b/java/com/google/gerrit/plugins/codeowners/restapi/PutCodeOwnerProjectConfig.java
@@ -15,6 +15,7 @@
 package com.google.gerrit.plugins.codeowners.restapi;
 
 import static com.google.gerrit.plugins.codeowners.backend.config.CodeOwnersPluginConfiguration.SECTION_CODE_OWNERS;
+import static com.google.gerrit.plugins.codeowners.backend.config.GeneralConfig.KEY_FALLBACK_CODE_OWNERS;
 import static com.google.gerrit.plugins.codeowners.backend.config.GeneralConfig.KEY_FILE_EXTENSION;
 import static com.google.gerrit.plugins.codeowners.backend.config.OverrideApprovalConfig.KEY_OVERRIDE_APPROVAL;
 import static com.google.gerrit.plugins.codeowners.backend.config.RequiredApprovalConfig.KEY_REQUIRED_APPROVAL;
@@ -141,6 +142,14 @@
             input.overrideApprovals);
       }
 
+      if (input.fallbackCodeOwners != null) {
+        codeOwnersConfig.setEnum(
+            SECTION_CODE_OWNERS,
+            /* subsection= */ null,
+            KEY_FALLBACK_CODE_OWNERS,
+            input.fallbackCodeOwners);
+      }
+
       validateConfig(projectResource.getProjectState(), codeOwnersConfig);
 
       codeOwnersProjectConfigFile.commit(metaDataUpdate);
diff --git a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/PutCodeOwnerProjectConfigIT.java b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/PutCodeOwnerProjectConfigIT.java
index 2da6c3d..11d60b7 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/PutCodeOwnerProjectConfigIT.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/PutCodeOwnerProjectConfigIT.java
@@ -33,6 +33,7 @@
 import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersIT;
 import com.google.gerrit.plugins.codeowners.api.CodeOwnerProjectConfigInfo;
 import com.google.gerrit.plugins.codeowners.api.CodeOwnerProjectConfigInput;
+import com.google.gerrit.plugins.codeowners.backend.FallbackCodeOwners;
 import com.google.gerrit.plugins.codeowners.backend.config.CodeOwnersPluginConfiguration;
 import com.google.gerrit.plugins.codeowners.backend.config.RequiredApproval;
 import com.google.gerrit.server.project.ProjectState;
@@ -287,6 +288,26 @@
   }
 
   @Test
+  public void setFallbackCodeOwners() throws Exception {
+    assertThat(codeOwnersPluginConfiguration.getFallbackCodeOwners(project))
+        .isEqualTo(FallbackCodeOwners.NONE);
+
+    CodeOwnerProjectConfigInput input = new CodeOwnerProjectConfigInput();
+    input.fallbackCodeOwners = FallbackCodeOwners.ALL_USERS;
+    CodeOwnerProjectConfigInfo updatedConfig =
+        projectCodeOwnersApiFactory.project(project).updateConfig(input);
+    assertThat(updatedConfig.general.fallbackCodeOwners).isEqualTo(FallbackCodeOwners.ALL_USERS);
+    assertThat(codeOwnersPluginConfiguration.getFallbackCodeOwners(project))
+        .isEqualTo(FallbackCodeOwners.ALL_USERS);
+
+    input.fallbackCodeOwners = FallbackCodeOwners.NONE;
+    updatedConfig = projectCodeOwnersApiFactory.project(project).updateConfig(input);
+    assertThat(updatedConfig.general.fallbackCodeOwners).isEqualTo(FallbackCodeOwners.NONE);
+    assertThat(codeOwnersPluginConfiguration.getFallbackCodeOwners(project))
+        .isEqualTo(FallbackCodeOwners.NONE);
+  }
+
+  @Test
   @UseClockStep
   public void checkCommitData() throws Exception {
     RevCommit head1 = projectOperations.project(project).getHead(RefNames.REFS_CONFIG);
diff --git a/resources/Documentation/rest-api.md b/resources/Documentation/rest-api.md
index bde20bd..764b3d4 100644
--- a/resources/Documentation/rest-api.md
+++ b/resources/Documentation/rest-api.md
@@ -839,6 +839,7 @@
 | `file_extension` | optional | The file extension that should be used for code owner config files in this project.
 | `required_approval` | optional | The approval that is required from code owners. Must be specified in the format "\<label-name\>+\<label-value\>". If an empty string is provided the required approval configuration is unset. Unsetting the required approval means that the inherited required approval configuration or the default required approval (`Code-Review+1`) will apply. In contrast to providing an empty string, providing `null` (or not setting the value) means that the required approval configuration is not updated.
 | `override_approvals` | optional | The approvals that count as override for the code owners submit check. Must be specified in the format "\<label-name\>+\<label-value\>".
+| `fallback_code_owners` | optional | Policy that controls who should own paths that have no code owners defined.
 
 ---