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