GetCodeOwnerConfigFiles: Allow to include non-parsable files in the response
Some callers may be interested in all code owner config files, even if
they are non-parsable.
The new option to include non-parsable files cannot be used in
combination with the email option, since for non-parsable files we
cannot check if it contains a code owner with that email.
Signed-off-by: Edwin Kempin <ekempin@google.com>
Change-Id: Ia04d2e32abcf76cc035c76086c9308779d9eb77e
diff --git a/java/com/google/gerrit/plugins/codeowners/api/BranchCodeOwners.java b/java/com/google/gerrit/plugins/codeowners/api/BranchCodeOwners.java
index 1836ca9..2b81afb 100644
--- a/java/com/google/gerrit/plugins/codeowners/api/BranchCodeOwners.java
+++ b/java/com/google/gerrit/plugins/codeowners/api/BranchCodeOwners.java
@@ -32,8 +32,20 @@
CodeOwnerConfigFilesRequest codeOwnerConfigFiles() throws RestApiException;
abstract class CodeOwnerConfigFilesRequest {
+ private boolean includeNonParsableFiles;
private String email;
+ /** Includes non-parsable code owner config files into the result. */
+ public CodeOwnerConfigFilesRequest includeNonParsableFiles(boolean includeNonParsableFiles) {
+ this.includeNonParsableFiles = includeNonParsableFiles;
+ return this;
+ }
+
+ /** Whether non-parsable code owner config files should be included into the result. */
+ public boolean getIncludeNonParsableFiles() {
+ return includeNonParsableFiles;
+ }
+
/**
* Limits the returned code owner config files to those that contain the given email.
*
diff --git a/java/com/google/gerrit/plugins/codeowners/api/BranchCodeOwnersImpl.java b/java/com/google/gerrit/plugins/codeowners/api/BranchCodeOwnersImpl.java
index 6ed89a9..aacc3e2 100644
--- a/java/com/google/gerrit/plugins/codeowners/api/BranchCodeOwnersImpl.java
+++ b/java/com/google/gerrit/plugins/codeowners/api/BranchCodeOwnersImpl.java
@@ -60,6 +60,7 @@
@Override
public List<String> paths() throws RestApiException {
GetCodeOwnerConfigFiles getCodeOwnerConfigFiles = getCodeOwnerConfigFilesProvider.get();
+ getCodeOwnerConfigFiles.setIncludeNonParsableFiles(getIncludeNonParsableFiles());
getCodeOwnerConfigFiles.setEmail(getEmail());
return getCodeOwnerConfigFiles.apply(branchResource).value();
}
diff --git a/java/com/google/gerrit/plugins/codeowners/restapi/GetCodeOwnerConfigFiles.java b/java/com/google/gerrit/plugins/codeowners/restapi/GetCodeOwnerConfigFiles.java
index 0ebf942..8190e7c 100644
--- a/java/com/google/gerrit/plugins/codeowners/restapi/GetCodeOwnerConfigFiles.java
+++ b/java/com/google/gerrit/plugins/codeowners/restapi/GetCodeOwnerConfigFiles.java
@@ -20,6 +20,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
+import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerBackend;
@@ -48,9 +49,17 @@
private final CodeOwnersPluginConfiguration codeOwnersPluginConfiguration;
private final CodeOwnerConfigScanner.Factory codeOwnerConfigScannerFactory;
+ private boolean includeNonParsableFiles;
private String email;
@Option(
+ name = "--include-non-parsable-files",
+ usage = "includes non-parseable code owner config files in the response")
+ public void setIncludeNonParsableFiles(boolean includeNonParsableFiles) {
+ this.includeNonParsableFiles = includeNonParsableFiles;
+ }
+
+ @Option(
name = "--email",
metaVar = "EMAIL",
usage = "limits the returned code owner config files to those that contain this email")
@@ -67,7 +76,9 @@
}
@Override
- public Response<List<String>> apply(BranchResource resource) {
+ public Response<List<String>> apply(BranchResource resource) throws BadRequestException {
+ validateOptions();
+
CodeOwnerBackend codeOwnerBackend =
codeOwnersPluginConfiguration.getBackend(resource.getBranchKey());
ImmutableList.Builder<Path> codeOwnerConfigs = ImmutableList.builder();
@@ -93,7 +104,11 @@
}
return true;
},
- CodeOwnerConfigScanner.ignoreInvalidCodeOwnerConfigFiles());
+ includeNonParsableFiles
+ ? (codeOwnerConfigFilePath, configInvalidException) -> {
+ codeOwnerConfigs.add(codeOwnerConfigFilePath);
+ }
+ : CodeOwnerConfigScanner.ignoreInvalidCodeOwnerConfigFiles());
return Response.ok(
codeOwnerConfigs.build().stream().map(Path::toString).collect(toImmutableList()));
}
@@ -120,4 +135,11 @@
}
return containsEmail;
}
+
+ private void validateOptions() throws BadRequestException {
+ if (email != null && includeNonParsableFiles) {
+ throw new BadRequestException(
+ "the options 'email' and 'include-non-parsable-files' are mutually exclusive");
+ }
+ }
}
diff --git a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/GetCodeOwnerConfigFilesIT.java b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/GetCodeOwnerConfigFilesIT.java
index 50b795b..284f01b 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/GetCodeOwnerConfigFilesIT.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/GetCodeOwnerConfigFilesIT.java
@@ -15,9 +15,11 @@
package com.google.gerrit.plugins.codeowners.acceptance.api;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.entities.RefNames;
+import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.plugins.codeowners.JgitPath;
import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersIT;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerBackend;
@@ -226,6 +228,50 @@
}
@Test
+ public void includeInvalidCodeOwnerConfigFiles() throws Exception {
+ String nameOfInvalidCodeOwnerConfigFile = getCodeOwnerConfigFileName();
+ createInvalidCodeOwnerConfig(nameOfInvalidCodeOwnerConfigFile);
+
+ CodeOwnerConfig.Key codeOwnerConfigKey =
+ codeOwnerConfigOperations
+ .newCodeOwnerConfig()
+ .project(project)
+ .branch("master")
+ .folderPath("/foo/")
+ .addCodeOwnerEmail(admin.email())
+ .create();
+
+ assertThat(
+ projectCodeOwnersApiFactory
+ .project(project)
+ .branch("master")
+ .codeOwnerConfigFiles()
+ .includeNonParsableFiles(true)
+ .paths())
+ .containsExactly(
+ JgitPath.of(nameOfInvalidCodeOwnerConfigFile).getAsAbsolutePath().toString(),
+ codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getFilePath());
+ }
+
+ @Test
+ public void includeNonParsableFilesAndEmailOptionsAreMutuallyExclusive() throws Exception {
+ BadRequestException exception =
+ assertThrows(
+ BadRequestException.class,
+ () ->
+ projectCodeOwnersApiFactory
+ .project(project)
+ .branch("master")
+ .codeOwnerConfigFiles()
+ .includeNonParsableFiles(true)
+ .withEmail(admin.email())
+ .paths());
+ assertThat(exception)
+ .hasMessageThat()
+ .isEqualTo("the options 'email' and 'include-non-parsable-files' are mutually exclusive");
+ }
+
+ @Test
public void filterByEmail() throws Exception {
TestAccount user2 = accountCreator.user2();
TestAccount user3 = accountCreator.create("user3", "user3@example.com", "User3", null);
diff --git a/resources/Documentation/rest-api.md b/resources/Documentation/rest-api.md
index 7044cd8..c2aafff 100644
--- a/resources/Documentation/rest-api.md
+++ b/resources/Documentation/rest-api.md
@@ -182,8 +182,8 @@
| Field Name | | Description |
| ----------- | -------- | ----------- |
-| `email` | optional | Code owner email that must appear in the returned
-code owner config files.
+| `include-non-parsable-files` | optional | Includes non-parseable code owner config files in the response. By default `false`. Cannot be used in combination with the `email` option.
+| `email` | optional | Code owner email that must appear in the returned code owner config files.
#### Request
@@ -195,7 +195,8 @@
result also includes code owner config that use name prefixes
('\<prefix\>_OWNERS') or name extensions ('OWNERS_\<extension\>').
-Non-parseable code owner config files are omitted from the response.
+Non-parseable code owner config files are omitted from the response, unless the
+`include-non-parsable-files` option was set.
#### Response