From 74e12aea0f20637cefa4d0561a55d5b9b54b27ee Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Sun, 12 Jul 2026 15:17:45 +0200 Subject: [PATCH] [MNG-5913] Allow defining aliases for existing server configurations in settings.xml * [MNG-5913] Allow defining aliases for existing server configurations in settings.xml Add the next tag aliases to the server in settings.xml Additional server will be created in memory by SettingsBuilder, so the generated configuration should be transparent to other as Settings#getServers() will return complete list. (cherry picked from commit 09b2dfc9151030e026a993f234c8e9c507c2d198) --- api/maven-api-settings/pom.xml | 3 + .../src/main/mdo/settings.mdo | 12 +++ .../building/DefaultSettingsBuilder.java | 18 ++++ .../validation/DefaultSettingsValidator.java | 17 +++ .../DefaultSettingsBuilderFactoryTest.java | 100 ++++++++++++++++- .../DefaultSettingsValidatorTest.java | 52 +++++++++ .../settings/factory/settings-servers-1.xml | 37 +++++++ .../settings/factory/settings-servers-2.xml | 49 +++++++++ .../settings/factory/settings-servers-3.xml | 40 +++++++ compat/maven-settings/pom.xml | 5 +- .../maven/impl/DefaultSettingsBuilder.java | 19 +++- .../maven/impl/DefaultSettingsValidator.java | 20 ++++ .../DefaultSettingsBuilderFactoryTest.java | 101 +++++++++++++++++- .../impl/DefaultSettingsValidatorTest.java | 47 ++++++++ .../resources/settings/settings-servers-1.xml | 37 +++++++ .../resources/settings/settings-servers-2.xml | 49 +++++++++ .../resources/settings/settings-servers-3.xml | 40 +++++++ .../{ => settings}/settings-simple.xml | 0 impl/maven-support/pom.xml | 5 +- pom.xml | 5 + 20 files changed, 641 insertions(+), 15 deletions(-) create mode 100644 compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-1.xml create mode 100644 compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-2.xml create mode 100644 compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-3.xml create mode 100644 impl/maven-impl/src/test/resources/settings/settings-servers-1.xml create mode 100644 impl/maven-impl/src/test/resources/settings/settings-servers-2.xml create mode 100644 impl/maven-impl/src/test/resources/settings/settings-servers-3.xml rename impl/maven-impl/src/test/resources/{ => settings}/settings-simple.xml (100%) diff --git a/api/maven-api-settings/pom.xml b/api/maven-api-settings/pom.xml index 426a03af582f..e923e820ed4d 100644 --- a/api/maven-api-settings/pom.xml +++ b/api/maven-api-settings/pom.xml @@ -54,6 +54,9 @@ under the License. org.codehaus.modello modello-maven-plugin + + alias + 2.0.0 ${project.basedir}/../../src/mdo diff --git a/api/maven-api-settings/src/main/mdo/settings.mdo b/api/maven-api-settings/src/main/mdo/settings.mdo index fe69efeeff16..0e8803b2d464 100644 --- a/api/maven-api-settings/src/main/mdo/settings.mdo +++ b/api/maven-api-settings/src/main/mdo/settings.mdo @@ -529,6 +529,18 @@ Extra configuration for the transport layer. + + aliases + 1.3.0+ + List of additional server aliases. For each alias, an additional server entry will be generated + with the same configuration as the original one, but with the ID replaced by the alias + and with an empty aliases list. + This is useful when the same credentials should be used for multiple servers. + + String + * + + diff --git a/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilder.java b/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilder.java index 051b8f44722d..3df86c961629 100644 --- a/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilder.java +++ b/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilder.java @@ -26,12 +26,15 @@ import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.stream.Stream; import org.apache.maven.building.FileSource; import org.apache.maven.building.Source; +import org.apache.maven.settings.Server; import org.apache.maven.settings.Settings; import org.apache.maven.settings.TrackableBase; import org.apache.maven.settings.io.SettingsParseException; @@ -182,6 +185,7 @@ private Settings readSettings( } settingsValidator.validate(settings, problems); + settings.setServers(new ArrayList<>(serversByIds(settings.getServers()))); return settings; } @@ -251,4 +255,18 @@ public Object execute(String expression, Object value) { return result; } + + private List serversByIds(List servers) { + return servers.stream() + .flatMap(server -> Stream.concat( + Stream.of(server), server.getAliases().stream().map(id -> serverAlias(server, id)))) + .toList(); + } + + private Server serverAlias(Server server, String id) { + return new Server(org.apache.maven.api.settings.Server.newBuilder(server.getDelegate(), true) + .id(id) + .aliases(List.of()) + .build()); + } } diff --git a/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/DefaultSettingsValidator.java b/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/DefaultSettingsValidator.java index 6df108748cb9..c4d8e196a219 100644 --- a/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/DefaultSettingsValidator.java +++ b/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/DefaultSettingsValidator.java @@ -93,6 +93,23 @@ public void validate(Settings settings, SettingsProblemCollector problems) { "must be unique but found duplicate server with id " + server.getId()); } } + + for (int i = 0; i < servers.size(); i++) { + Server server = servers.get(i); + for (int a = 0; a < server.getAliases().size(); a++) { + String alias = server.getAliases().get(a); + validateStringNotEmpty( + problems, "servers.server[" + i + "].aliases[" + a + "]", alias, server.getId()); + if (!serverIds.add(alias)) { + addViolation( + problems, + Severity.WARNING, + "servers.server[" + i + "].aliases[" + a + "]", + server.getId(), + "must be unique across all server ids and aliases but found duplicate alias " + alias); + } + } + } } List mirrors = settings.getMirrors(); diff --git a/compat/maven-settings-builder/src/test/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactoryTest.java b/compat/maven-settings-builder/src/test/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactoryTest.java index 2959e4f68243..84c74feb0fa9 100644 --- a/compat/maven-settings-builder/src/test/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactoryTest.java +++ b/compat/maven-settings-builder/src/test/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactoryTest.java @@ -19,10 +19,16 @@ package org.apache.maven.settings.building; import java.io.File; +import java.util.List; +import java.util.Properties; +import org.apache.maven.api.settings.Server; +import org.apache.maven.settings.Settings; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; /** */ @@ -32,17 +38,101 @@ private File getSettings(String name) { return new File("src/test/resources/settings/factory/" + name + ".xml").getAbsoluteFile(); } - @Test - void testCompleteWiring() throws Exception { + SettingsBuildingResult execute(String settingsName) throws Exception { + Properties properties = new Properties(); + properties.setProperty("user.home", "/home/user"); + SettingsBuilder builder = new DefaultSettingsBuilderFactory().newInstance(); assertNotNull(builder); DefaultSettingsBuildingRequest request = new DefaultSettingsBuildingRequest(); - request.setSystemProperties(System.getProperties()); - request.setUserSettingsFile(getSettings("simple")); + request.setSystemProperties(properties); + request.setUserSettingsFile(getSettings(settingsName)); SettingsBuildingResult result = builder.build(request); assertNotNull(result); - assertNotNull(result.getEffectiveSettings()); + return result; + } + + @Test + void testCompleteWiring() throws Exception { + Settings settings = execute("simple").getEffectiveSettings(); + + String localRepository = settings.getLocalRepository(); + assertTrue(localRepository.equals("/home/user/.m2/repository") + || localRepository.endsWith("\\home\\user\\.m2\\repository")); + } + + @Test + void testSettingsWithServers() throws Exception { + Settings settings = execute("settings-servers-1").getEffectiveSettings(); + + List servers = settings.getDelegate().getServers(); + assertEquals(2, servers.size()); + + Server server1 = getServerById(servers, "server-1"); + assertEquals("username1", server1.getUsername()); + assertEquals("password1", server1.getPassword()); + + Server server2 = getServerById(servers, "server-2"); + assertEquals("username2", server2.getUsername()); + assertEquals("password2", server2.getPassword()); + } + + @Test + void testSettingsWithServersAndAliases() throws Exception { + Settings settings = execute("settings-servers-2").getEffectiveSettings(); + + List servers = settings.getDelegate().getServers(); + assertEquals(6, servers.size()); + + Server server1 = getServerById(servers, "server-1"); + assertEquals("username1", server1.getUsername()); + assertEquals("password1", server1.getPassword()); + assertEquals(List.of("server-11", "server-12"), server1.getAliases()); + + Server server11 = getServerById(servers, "server-11"); + assertEquals("username1", server11.getUsername()); + assertEquals("password1", server11.getPassword()); + assertTrue(server11.getAliases().isEmpty()); + + Server server12 = getServerById(servers, "server-12"); + assertEquals("username1", server12.getUsername()); + assertEquals("password1", server12.getPassword()); + assertTrue(server12.getAliases().isEmpty()); + + Server server2 = getServerById(servers, "server-2"); + assertEquals("username2", server2.getUsername()); + assertEquals("password2", server2.getPassword()); + assertEquals(List.of("server-21"), server2.getAliases()); + + Server server21 = getServerById(servers, "server-21"); + assertEquals("username2", server21.getUsername()); + assertEquals("password2", server21.getPassword()); + assertTrue(server21.getAliases().isEmpty()); + + Server server3 = getServerById(servers, "server-3"); + assertEquals("username3", server3.getUsername()); + assertEquals("password3", server3.getPassword()); + assertTrue(server3.getAliases().isEmpty()); + } + + private Server getServerById(List servers, String id) { + return servers.stream() + .filter(s -> s.getId().equals(id)) + .findFirst() + .orElseThrow( + () -> new IllegalStateException("Server with id " + id + " not found on list: " + servers)); + } + + @Test + void testSettingsWithDuplicateServersIds() throws Exception { + SettingsBuildingResult result = execute("settings-servers-3"); + + List problems = result.getProblems(); + assertEquals(1, problems.size()); + assertEquals( + "'servers.server[0].aliases[0]' for server-1 must be unique across all server ids and aliases but found duplicate alias server-2", + problems.get(0).getMessage()); } } diff --git a/compat/maven-settings-builder/src/test/java/org/apache/maven/settings/validation/DefaultSettingsValidatorTest.java b/compat/maven-settings-builder/src/test/java/org/apache/maven/settings/validation/DefaultSettingsValidatorTest.java index d2f95b21dad7..4bec76a359bf 100644 --- a/compat/maven-settings-builder/src/test/java/org/apache/maven/settings/validation/DefaultSettingsValidatorTest.java +++ b/compat/maven-settings-builder/src/test/java/org/apache/maven/settings/validation/DefaultSettingsValidatorTest.java @@ -219,6 +219,58 @@ void testValidateProxy() throws Exception { assertContains(problems.messages.get(0), "'proxies.proxy.host' for default is missing"); } + @Test + void testValidateServerIdAlias() { + Settings settings = new Settings(); + Server server = new Server(); + server.setId("server-1"); + server.addAlias("server-1"); + settings.addServer(server); + + SimpleProblemCollector problems = new SimpleProblemCollector(); + validator.validate(settings, problems); + assertEquals(1, problems.messages.size()); + assertContains( + problems.messages.get(0), + "'servers.server[0].aliases[0]' for server-1 must be unique across all server ids and aliases but found duplicate alias server-1"); + } + + @Test + void testMultipleUsageOfAliases() { + Settings settings = new Settings(); + + Server server1 = new Server(); + server1.setId("server-1"); + server1.addAlias("alias-1"); + settings.addServer(server1); + + Server server2 = new Server(); + server2.setId("server-2"); + server2.addAlias("alias-1"); + settings.addServer(server2); + + SimpleProblemCollector problems = new SimpleProblemCollector(); + validator.validate(settings, problems); + assertEquals(1, problems.messages.size()); + assertContains( + problems.messages.get(0), + "'servers.server[1].aliases[0]' for server-2 must be unique across all server ids and aliases but found duplicate alias alias-1"); + } + + @Test + void testValidateServerIdAliasesWithEmptyValue() { + Settings settings = new Settings(); + Server server = new Server(); + server.setId("server-1"); + server.addAlias(""); + settings.addServer(server); + + SimpleProblemCollector problems = new SimpleProblemCollector(); + validator.validate(settings, problems); + assertEquals(1, problems.messages.size()); + assertContains(problems.messages.get(0), "'servers.server[0].aliases[0]' for server-1 is missing"); + } + private static class SimpleProblemCollector implements SettingsProblemCollector { List messages = new ArrayList<>(); diff --git a/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-1.xml b/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-1.xml new file mode 100644 index 000000000000..7076749943b2 --- /dev/null +++ b/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-1.xml @@ -0,0 +1,37 @@ + + + + + + ${user.home}/.m2/repository + + + server-1 + username1 + password1 + + + server-2 + username2 + password2 + + + + diff --git a/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-2.xml b/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-2.xml new file mode 100644 index 000000000000..a8464a49a302 --- /dev/null +++ b/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-2.xml @@ -0,0 +1,49 @@ + + + + + + ${user.home}/.m2/repository + + + server-1 + + server-11 + server-12 + + username1 + password1 + + + server-2 + + server-21 + + username2 + password2 + + + server-3 + username3 + password3 + + + + diff --git a/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-3.xml b/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-3.xml new file mode 100644 index 000000000000..e0a13454e2e8 --- /dev/null +++ b/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-3.xml @@ -0,0 +1,40 @@ + + + + + + ${user.home}/.m2/repository + + + server-1 + + server-2 + + username1 + password1 + + + server-2 + username2 + password2 + + + + diff --git a/compat/maven-settings/pom.xml b/compat/maven-settings/pom.xml index 3a825e9ddc6d..bb3b7b7f7679 100644 --- a/compat/maven-settings/pom.xml +++ b/compat/maven-settings/pom.xml @@ -68,6 +68,9 @@ under the License. org.codehaus.modello modello-maven-plugin + + alias + 2.0.0 ${project.basedir}/../../api/maven-api-settings ${project.basedir}/../../src/mdo @@ -75,7 +78,7 @@ under the License. src/main/mdo/settings.mdo - forcedIOModelVersion=1.2.0 + forcedIOModelVersion=1.3.0 packageModelV3=org.apache.maven.settings packageModelV4=org.apache.maven.api.settings packageToolV4=org.apache.maven.settings.v4 diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSettingsBuilder.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSettingsBuilder.java index be7dd9e86312..b5014498bf24 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSettingsBuilder.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSettingsBuilder.java @@ -31,6 +31,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; import java.util.function.UnaryOperator; +import java.util.stream.Stream; import org.apache.maven.api.Constants; import org.apache.maven.api.ProtoSession; @@ -62,7 +63,6 @@ /** * Builds the effective settings from a user settings file and/or a global settings file. - * */ @Named public class DefaultSettingsBuilder implements SettingsBuilder { @@ -205,7 +205,9 @@ private Settings readSettings( settingsValidator.validate(settings, isProjectSettings, problems); - if (isProjectSettings) { + if (!isProjectSettings) { + settings = settings.withServers(serversByIds(settings.getServers())); + } else { settings = Settings.newBuilder(settings, true) .localRepository(null) .interactiveMode(false) @@ -220,6 +222,7 @@ private Settings readSettings( .password(null) .filePermissions(null) .directoryPermissions(null) + .aliases(List.of()) .build()) .toList()) .build(); @@ -228,6 +231,17 @@ private Settings readSettings( return settings; } + private List serversByIds(List servers) { + return servers.stream() + .flatMap(server -> Stream.concat( + Stream.of(server), server.getAliases().stream().map(id -> serverAlias(server, id)))) + .toList(); + } + + private Server serverAlias(Server server, String id) { + return Server.newBuilder(server, true).id(id).aliases(List.of()).build(); + } + private Settings interpolate( Settings settings, SettingsBuilderRequest request, ProblemCollector problems) { UnaryOperator src; @@ -348,7 +362,6 @@ public org.apache.maven.api.model.Profile convert(Profile profile) { /** * Collects the output of the settings builder. - * */ static class DefaultSettingsBuilderResult implements SettingsBuilderResult { diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSettingsValidator.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSettingsValidator.java index 21284afa0c31..b85c5f0d2074 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSettingsValidator.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSettingsValidator.java @@ -73,6 +73,9 @@ public void validate(Settings settings, boolean isProjectSettings, ProblemCollec validateStringEmpty(problems, serverField + ".filePermissions", server.getFilePermissions(), msgS); validateStringEmpty( problems, serverField + ".directoryPermissions", server.getDirectoryPermissions(), msgS); + if (!server.getAliases().isEmpty()) { + addViolation(problems, BuilderProblem.Severity.WARNING, serverField + ".aliases", null, msgP); + } } } @@ -123,6 +126,23 @@ public void validate(Settings settings, boolean isProjectSettings, ProblemCollec "must be unique but found duplicate server with id " + server.getId()); } } + + for (int i = 0; i < servers.size(); i++) { + Server server = servers.get(i); + for (int a = 0; a < server.getAliases().size(); a++) { + String alias = server.getAliases().get(a); + validateStringNotEmpty( + problems, "servers.server[" + i + "].aliases[" + a + "]", alias, server.getId()); + if (!serverIds.add(alias)) { + addViolation( + problems, + BuilderProblem.Severity.WARNING, + "servers.server[" + i + "].aliases[" + a + "]", + server.getId(), + "must be unique across all server ids and aliases but found duplicate alias " + alias); + } + } + } } List mirrors = settings.getMirrors(); diff --git a/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultSettingsBuilderFactoryTest.java b/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultSettingsBuilderFactoryTest.java index 5419b27d6287..f76b9067be6c 100644 --- a/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultSettingsBuilderFactoryTest.java +++ b/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultSettingsBuilderFactoryTest.java @@ -20,14 +20,19 @@ import java.nio.file.Path; import java.nio.file.Paths; +import java.util.List; import java.util.Map; import org.apache.maven.api.Session; +import org.apache.maven.api.services.BuilderProblem; +import org.apache.maven.api.services.ProblemCollector; import org.apache.maven.api.services.SettingsBuilder; import org.apache.maven.api.services.SettingsBuilderRequest; import org.apache.maven.api.services.SettingsBuilderResult; import org.apache.maven.api.services.Sources; import org.apache.maven.api.services.xml.SettingsXmlFactory; +import org.apache.maven.api.settings.Server; +import org.apache.maven.api.settings.Settings; import org.apache.maven.impl.model.DefaultInterpolator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -36,9 +41,12 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; /** + * */ @ExtendWith(MockitoExtension.class) class DefaultSettingsBuilderFactoryTest { @@ -53,23 +61,106 @@ void setup() { .thenReturn(new DefaultSettingsXmlFactory()); } - @Test - void testCompleteWiring() { + SettingsBuilderResult execute(String settingsName) { SettingsBuilder builder = new DefaultSettingsBuilder(new DefaultSettingsXmlFactory(), new DefaultInterpolator(), Map.of()); assertNotNull(builder); SettingsBuilderRequest request = SettingsBuilderRequest.builder() .session(session) - .userSettingsSource(Sources.buildSource(getSettings("settings-simple"))) + .userSettingsSource(Sources.buildSource(getSettings(settingsName))) .build(); SettingsBuilderResult result = builder.build(request); assertNotNull(result); - assertNotNull(result.getEffectiveSettings()); + return result; + } + + @Test + void testCompleteWiring() { + Settings settings = execute("settings-simple").getEffectiveSettings(); + + String localRepository = settings.getLocalRepository(); + assertTrue(localRepository.equals("${user.home}/.m2/repository") + || localRepository.endsWith("\\${user.home}\\.m2\\repository")); + } + + @Test + void testSettingsWithServers() { + Settings settings = execute("settings-servers-1").getEffectiveSettings(); + + List servers = settings.getServers(); + assertEquals(2, servers.size()); + + Server server1 = getServerById(servers, "server-1"); + assertEquals("username1", server1.getUsername()); + assertEquals("password1", server1.getPassword()); + + Server server2 = getServerById(servers, "server-2"); + assertEquals("username2", server2.getUsername()); + assertEquals("password2", server2.getPassword()); + } + + @Test + void testSettingsWithServersAndAliases() { + Settings settings = execute("settings-servers-2").getEffectiveSettings(); + + assertEquals("${user.home}/.m2/repository", settings.getLocalRepository()); + + List servers = settings.getServers(); + assertEquals(6, servers.size()); + + Server server1 = getServerById(servers, "server-1"); + assertEquals("username1", server1.getUsername()); + assertEquals("password1", server1.getPassword()); + assertEquals(List.of("server-11", "server-12"), server1.getAliases()); + + Server server11 = getServerById(servers, "server-11"); + assertEquals("username1", server11.getUsername()); + assertEquals("password1", server11.getPassword()); + assertTrue(server11.getAliases().isEmpty()); + + Server server12 = getServerById(servers, "server-12"); + assertEquals("username1", server12.getUsername()); + assertEquals("password1", server12.getPassword()); + assertTrue(server12.getAliases().isEmpty()); + + Server server2 = getServerById(servers, "server-2"); + assertEquals("username2", server2.getUsername()); + assertEquals("password2", server2.getPassword()); + assertEquals(List.of("server-21"), server2.getAliases()); + + Server server21 = getServerById(servers, "server-21"); + assertEquals("username2", server21.getUsername()); + assertEquals("password2", server21.getPassword()); + assertTrue(server21.getAliases().isEmpty()); + + Server server3 = getServerById(servers, "server-3"); + assertEquals("username3", server3.getUsername()); + assertEquals("password3", server3.getPassword()); + assertTrue(server3.getAliases().isEmpty()); + } + + private Server getServerById(List servers, String id) { + return servers.stream() + .filter(s -> s.getId().equals(id)) + .findFirst() + .orElseThrow( + () -> new IllegalStateException("Server with id " + id + " not found on list: " + servers)); + } + + @Test + void testSettingsWithDuplicateServersIds() throws Exception { + SettingsBuilderResult result = execute("settings-servers-3"); + + ProblemCollector problems = result.getProblems(); + assertEquals(1, problems.problems().count()); + assertEquals( + "'servers.server[0].aliases[0]' for server-1 must be unique across all server ids and aliases but found duplicate alias server-2", + problems.problems().findFirst().orElseThrow().getMessage()); } private Path getSettings(String name) { - return Paths.get("src/test/resources/" + name + ".xml").toAbsolutePath(); + return Paths.get("src/test/resources/settings/" + name + ".xml").toAbsolutePath(); } } diff --git a/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultSettingsValidatorTest.java b/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultSettingsValidatorTest.java index f604fe6bb3af..46ae074de0eb 100644 --- a/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultSettingsValidatorTest.java +++ b/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultSettingsValidatorTest.java @@ -26,6 +26,7 @@ import org.apache.maven.api.services.SettingsBuilder; import org.apache.maven.api.settings.Profile; import org.apache.maven.api.settings.Repository; +import org.apache.maven.api.settings.Server; import org.apache.maven.api.settings.Settings; import org.apache.maven.impl.model.DefaultInterpolator; import org.junit.jupiter.api.BeforeEach; @@ -70,4 +71,50 @@ void testValidate() { problems = validator.validate(model2); assertEquals(0, problems.totalProblemsReported()); } + + @Test + void testValidateServerIdAlias() { + Server server = + Server.newBuilder().id("server-1").aliases(List.of("server-1")).build(); + + Settings settings = Settings.newBuilder().servers(List.of(server)).build(); + + ProblemCollector problems = validator.validate(settings); + assertEquals(1, problems.totalProblemsReported()); + assertEquals( + "'servers.server[0].aliases[0]' for server-1 must be unique across all server ids and aliases but found duplicate alias server-1", + problems.problems().findFirst().orElseThrow().getMessage()); + } + + @Test + void testMultipleUsageOfAliases() { + + Server server1 = + Server.newBuilder().id("server-1").aliases(List.of("alias-1")).build(); + + Server server2 = + Server.newBuilder().id("server-2").aliases(List.of("alias-1")).build(); + + Settings settings = + Settings.newBuilder().servers(List.of(server1, server2)).build(); + + ProblemCollector problems = validator.validate(settings); + assertEquals(1, problems.totalProblemsReported()); + assertEquals( + "'servers.server[1].aliases[0]' for server-2 must be unique across all server ids and aliases but found duplicate alias alias-1", + problems.problems().findFirst().orElseThrow().getMessage()); + } + + @Test + void testValidateServerIdAliasesWithEmptyValue() { + Server server = Server.newBuilder().id("server-1").aliases(List.of("")).build(); + + Settings settings = Settings.newBuilder().servers(List.of(server)).build(); + + ProblemCollector problems = validator.validate(settings); + assertEquals(1, problems.totalProblemsReported()); + assertEquals( + "'servers.server[0].aliases[0]' for server-1 is missing", + problems.problems().findFirst().orElseThrow().getMessage()); + } } diff --git a/impl/maven-impl/src/test/resources/settings/settings-servers-1.xml b/impl/maven-impl/src/test/resources/settings/settings-servers-1.xml new file mode 100644 index 000000000000..7076749943b2 --- /dev/null +++ b/impl/maven-impl/src/test/resources/settings/settings-servers-1.xml @@ -0,0 +1,37 @@ + + + + + + ${user.home}/.m2/repository + + + server-1 + username1 + password1 + + + server-2 + username2 + password2 + + + + diff --git a/impl/maven-impl/src/test/resources/settings/settings-servers-2.xml b/impl/maven-impl/src/test/resources/settings/settings-servers-2.xml new file mode 100644 index 000000000000..a8464a49a302 --- /dev/null +++ b/impl/maven-impl/src/test/resources/settings/settings-servers-2.xml @@ -0,0 +1,49 @@ + + + + + + ${user.home}/.m2/repository + + + server-1 + + server-11 + server-12 + + username1 + password1 + + + server-2 + + server-21 + + username2 + password2 + + + server-3 + username3 + password3 + + + + diff --git a/impl/maven-impl/src/test/resources/settings/settings-servers-3.xml b/impl/maven-impl/src/test/resources/settings/settings-servers-3.xml new file mode 100644 index 000000000000..e0a13454e2e8 --- /dev/null +++ b/impl/maven-impl/src/test/resources/settings/settings-servers-3.xml @@ -0,0 +1,40 @@ + + + + + + ${user.home}/.m2/repository + + + server-1 + + server-2 + + username1 + password1 + + + server-2 + username2 + password2 + + + + diff --git a/impl/maven-impl/src/test/resources/settings-simple.xml b/impl/maven-impl/src/test/resources/settings/settings-simple.xml similarity index 100% rename from impl/maven-impl/src/test/resources/settings-simple.xml rename to impl/maven-impl/src/test/resources/settings/settings-simple.xml diff --git a/impl/maven-support/pom.xml b/impl/maven-support/pom.xml index 3b78f3d9edbf..1b84d69d7ad7 100644 --- a/impl/maven-support/pom.xml +++ b/impl/maven-support/pom.xml @@ -123,6 +123,9 @@ under the License. generate-sources + + alias + 2.0.0 ${project.basedir}/../../api/maven-api-settings ${project.basedir}/../../src/mdo @@ -136,7 +139,7 @@ under the License. - forcedIOModelVersion=1.2.0 + forcedIOModelVersion=1.3.0 packageModelV3=org.apache.maven.settings packageModelV4=org.apache.maven.api.settings packageToolV4=org.apache.maven.settings.v4 diff --git a/pom.xml b/pom.xml index 7dbb63f3ad78..c7d3cce61c09 100644 --- a/pom.xml +++ b/pom.xml @@ -782,6 +782,11 @@ under the License. build-helper-maven-plugin 3.6.1 + + org.codehaus.modello + modello-maven-plugin + 2.7.0 + org.apache.maven.plugins maven-deploy-plugin