This is an automated email from the ASF dual-hosted git repository. royteeuwen pushed a commit to branch feature/sling-cli-release-automation in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git
commit e45d21ffd3974dd74a1c7e0b623cd61c7d109e00 Author: Roy Teeuwen <[email protected]> AuthorDate: Sat May 30 08:09:36 2026 +0200 release list: include open staging repositories `release list` previously filtered to closed repositories only, so a freshly staged repository (still open, not yet in the Lucene index) could not be found through the CLI. Drop the closed-only filter from RepositoryService.list() and show each repository's [open]/[closed] state, the committer who staged it (Nexus userId), and its description in ListCommand, so a newly staged repo can be located before it is closed for voting. --- .../sling/cli/impl/nexus/RepositoryService.java | 1 - .../sling/cli/impl/nexus/StagingRepository.java | 14 +++ .../apache/sling/cli/impl/release/ListCommand.java | 7 +- .../cli/impl/nexus/RepositoryServiceTest.java | 6 +- .../sling/cli/impl/release/ListCommandTest.java | 99 ++++++++++++++++++++++ src/test/resources/nexus/staging-repositories.json | 24 ++++++ 6 files changed, 147 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/apache/sling/cli/impl/nexus/RepositoryService.java b/src/main/java/org/apache/sling/cli/impl/nexus/RepositoryService.java index 31946aa..4625944 100644 --- a/src/main/java/org/apache/sling/cli/impl/nexus/RepositoryService.java +++ b/src/main/java/org/apache/sling/cli/impl/nexus/RepositoryService.java @@ -93,7 +93,6 @@ public class RepositoryService { return this.withStagingRepositories(reader -> { Gson gson = new Gson(); return gson.fromJson(reader, StagingRepositories.class).getData().stream() - .filter(r -> r.getType() == Status.closed) .filter(r -> r.getRepositoryId().startsWith(REPOSITORY_PREFIX)) .collect(Collectors.toList()); }); diff --git a/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepository.java b/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepository.java index af7d0c0..efcfbb1 100644 --- a/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepository.java +++ b/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepository.java @@ -33,6 +33,7 @@ public class StagingRepository { protected String repositoryId; protected String repositoryURI; protected Status type; + protected String userId; public String getDescription() { return description; @@ -42,6 +43,19 @@ public class StagingRepository { this.description = description; } + /** + * Returns the id of the committer who staged this repository, as reported by Nexus. + * + * @return the staging user id + */ + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + public String getRepositoryId() { return repositoryId; } diff --git a/src/main/java/org/apache/sling/cli/impl/release/ListCommand.java b/src/main/java/org/apache/sling/cli/impl/release/ListCommand.java index 43cc36a..c75ac0d 100644 --- a/src/main/java/org/apache/sling/cli/impl/release/ListCommand.java +++ b/src/main/java/org/apache/sling/cli/impl/release/ListCommand.java @@ -57,7 +57,12 @@ public class ListCommand implements Command { try { repositoryService .list() - .forEach(r -> logger.info("{}\t{}", r.getRepositoryId(), cleanupNewlines(r.getDescription()))); + .forEach(r -> logger.info( + "{}\t[{}]\t{}\t{}", + r.getRepositoryId(), + r.getType(), + r.getUserId(), + cleanupNewlines(r.getDescription()))); return CommandLine.ExitCode.OK; } catch (IOException e) { logger.warn("Failed executing command", e); diff --git a/src/test/java/org/apache/sling/cli/impl/nexus/RepositoryServiceTest.java b/src/test/java/org/apache/sling/cli/impl/nexus/RepositoryServiceTest.java index 55e387b..58f1732 100644 --- a/src/test/java/org/apache/sling/cli/impl/nexus/RepositoryServiceTest.java +++ b/src/test/java/org/apache/sling/cli/impl/nexus/RepositoryServiceTest.java @@ -96,8 +96,10 @@ public class RepositoryServiceTest { @Test public void testRepositoryList() throws IOException { List<StagingRepository> stagingRepositories = repositoryService.list(); - assertEquals(2, stagingRepositories.size()); - Set<String> repositoriesIds = new HashSet<>(Set.of("orgapachesling-0", "orgapachesling-1")); + // Includes both closed repositories and the open (not yet closed) one, so that newly + // staged repositories show up before they have been closed for voting. + assertEquals(3, stagingRepositories.size()); + Set<String> repositoriesIds = new HashSet<>(Set.of("orgapachesling-0", "orgapachesling-1", "orgapachesling-2")); for (StagingRepository repository : stagingRepositories) { assertEquals( "http://localhost:" + nexus.getBoundPort() + "/content/repositories/" diff --git a/src/test/java/org/apache/sling/cli/impl/release/ListCommandTest.java b/src/test/java/org/apache/sling/cli/impl/release/ListCommandTest.java new file mode 100644 index 0000000..24551d0 --- /dev/null +++ b/src/test/java/org/apache/sling/cli/impl/release/ListCommandTest.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.cli.impl.release; + +import java.util.Arrays; +import java.util.Collections; + +import org.apache.sling.cli.impl.Command; +import org.apache.sling.cli.impl.junit.LogCapture; +import org.apache.sling.cli.impl.nexus.RepositoryService; +import org.apache.sling.cli.impl.nexus.StagingRepository; +import org.apache.sling.testing.mock.osgi.junit.OsgiContext; +import org.junit.Rule; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +public class ListCommandTest { + + @Rule + public OsgiContext osgiContext = new OsgiContext(); + + @Rule + public final LogCapture logCapture = new LogCapture(ListCommand.class); + + @Test + public void testList() throws Exception { + StagingRepository repo1 = mock(StagingRepository.class); + when(repo1.getRepositoryId()).thenReturn("orgapachesling-1"); + when(repo1.getUserId()).thenReturn("jagger"); + when(repo1.getDescription()).thenReturn("Apache Sling CLI Test 1.0.0"); + + StagingRepository repo2 = mock(StagingRepository.class); + when(repo2.getRepositoryId()).thenReturn("orgapachesling-2"); + when(repo2.getUserId()).thenReturn("richards"); + when(repo2.getDescription()).thenReturn("Apache Sling CLI Test 2.0.0"); + + RepositoryService repositoryService = mock(RepositoryService.class); + when(repositoryService.list()).thenReturn(Arrays.asList(repo1, repo2)); + osgiContext.registerService(repositoryService); + + Command list = createCommand(); + assertEquals(0, (int) list.call()); + + assertTrue(logCapture.containsMessage("orgapachesling-1")); + assertTrue(logCapture.containsMessage("orgapachesling-2")); + // the staging user is shown alongside the id/state/description + assertTrue(logCapture.containsMessage("jagger")); + assertTrue(logCapture.containsMessage("richards")); + assertTrue(logCapture.containsMessage("Apache Sling CLI Test 1.0.0")); + assertTrue(logCapture.containsMessage("Apache Sling CLI Test 2.0.0")); + } + + @Test + public void testListCollapsesNewlines() throws Exception { + StagingRepository repo = mock(StagingRepository.class); + when(repo.getRepositoryId()).thenReturn("orgapachesling-1"); + when(repo.getDescription()).thenReturn("line1\nline2"); + + RepositoryService repositoryService = mock(RepositoryService.class); + when(repositoryService.list()).thenReturn(Collections.singletonList(repo)); + osgiContext.registerService(repositoryService); + + Command list = createCommand(); + assertEquals(0, (int) list.call()); + + assertTrue(logCapture.containsMessage("line1 line2")); + } + + private Command createCommand() { + ListCommand listCommand = spy(new ListCommand()); + osgiContext.registerInjectActivateService(listCommand); + Command result = osgiContext.getService(Command.class); + assertTrue( + "Expected to retrieve the ListCommand from the mocked OSGi environment.", + result instanceof ListCommand); + return result; + } +} diff --git a/src/test/resources/nexus/staging-repositories.json b/src/test/resources/nexus/staging-repositories.json index 1d418f7..3b644c0 100644 --- a/src/test/resources/nexus/staging-repositories.json +++ b/src/test/resources/nexus/staging-repositories.json @@ -47,6 +47,30 @@ "releaseRepositoryName": "Releases", "notifications" : 0, "transitioning" : false + }, + { + "profileId" : "6a443ac86e2212", + "profileName" : "org.apache.sling", + "profileType" : "repository", + "repositoryId" : "orgapachesling-2", + "type" : "open", + "policy" : "release", + "userId" : "radu", + "userAgent" : "Apache-Maven/3.6.1 (Java 1.8.0_222; Mac OS X 10.14.6)", + "ipAddress" : "127.0.0.1", + "repositoryURI" : "{nexusHost}/content/repositories/orgapachesling-2", + "created" : "2019-09-13T00:00:00.000Z", + "createdDate" : "Fri Sep 13 00:00:00 UTC 2019", + "createdTimestamp" : 1568332800000, + "updated" : "2019-09-13T00:00:00.000Z", + "updatedDate" : "Fri Sep 13 00:00:00 UTC 2019", + "updatedTimestamp" : 1568332800000, + "description" : "Implicitly created (auto staging).", + "provider" : "maven2", + "releaseRepositoryId" : "releases", + "releaseRepositoryName": "Releases", + "notifications" : 0, + "transitioning" : false } ] }
