From c6adaf852fa761ab68c4c7e23876a4d7f941a3d3 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Tue, 13 May 2025 21:23:43 +0200 Subject: [PATCH 01/11] [MNG-5913] Allow defining aliases for existing server configurations in settings.xml Add the next tag ids 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. --- .../src/main/mdo/settings.mdo | 13 ++ compat/maven-settings-builder/pom.xml | 5 + .../building/DefaultSettingsBuilder.java | 23 ++++ .../DefaultSettingsBuilderFactoryTest.java | 118 ++++++++++++++++-- .../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 | 1 + .../maven/impl/DefaultSettingsBuilder.java | 25 +++- .../DefaultSettingsBuilderFactoryTest.java | 114 +++++++++++++++-- .../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 | 1 + 15 files changed, 535 insertions(+), 17 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/src/main/mdo/settings.mdo b/api/maven-api-settings/src/main/mdo/settings.mdo index fe69efeeff16..05183ae9501b 100644 --- a/api/maven-api-settings/src/main/mdo/settings.mdo +++ b/api/maven-api-settings/src/main/mdo/settings.mdo @@ -181,6 +181,7 @@ repositories + 1.3.0+ The lists of the remote repositories. @@ -192,6 +193,7 @@ pluginRepositories + 1.3.0+ The lists of the remote repositories for discovering plugins. @@ -529,6 +531,17 @@ Extra configuration for the transport layer. + + ids + 1.3.0+ + + List of additional ids for server. + + + String + * + + diff --git a/compat/maven-settings-builder/pom.xml b/compat/maven-settings-builder/pom.xml index 24e62ee65639..9b94d3a498f3 100644 --- a/compat/maven-settings-builder/pom.xml +++ b/compat/maven-settings-builder/pom.xml @@ -78,6 +78,11 @@ under the License. junit-jupiter-api test + + org.assertj + assertj-core + test + 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 140393bf0659..dd4ad96215b0 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,14 @@ 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 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; @@ -181,6 +183,7 @@ private Settings readSettings( return new Settings(); } + settings.setServers(serversByIds(settings.getServers())); settingsValidator.validate(settings, problems); return settings; @@ -251,4 +254,24 @@ public Object execute(String expression, Object value) { return result; } + + private List serversByIds(List servers) { + + if (servers.stream().allMatch(server -> server.getIds().isEmpty())) { + return servers; + } + + ArrayList result = new ArrayList<>(servers); + + servers.stream().filter(server -> !server.getIds().isEmpty()).forEach(server -> server.getIds() + .forEach(id -> result.add(newServer(server, id)))); + return result; + } + + private Server newServer(Server server, String id) { + return new Server(org.apache.maven.api.settings.Server.newBuilder(server.getDelegate(), false) + .id(id) + .ids(Collections.emptyList()) + .build()); + } } 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..15219a2ca5fd 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,15 @@ 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.assertj.core.api.recursive.comparison.RecursiveComparisonConfiguration; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.assertj.core.api.Assertions.assertThat; /** */ @@ -32,17 +37,114 @@ private File getSettings(String name) { return new File("src/test/resources/settings/factory/" + name + ".xml").getAbsoluteFile(); } - @Test - void testCompleteWiring() throws Exception { + private org.apache.maven.settings.Server asServer(Server delegate) { + return new org.apache.maven.settings.Server(delegate); + } + + SettingsBuildingResult execute(String settingsName) throws Exception { + Properties properties = new Properties(); + properties.setProperty("user.home", "/home/user"); + SettingsBuilder builder = new DefaultSettingsBuilderFactory().newInstance(); - assertNotNull(builder); + assertThat(builder).isNotNull(); 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 assertThat(result).isNotNull().actual(); + } + + @Test + void testCompleteWiring() throws Exception { + Settings settings = assertThat(execute("simple")) + .extracting(SettingsBuildingResult::getEffectiveSettings) + .actual(); + + assertThat(settings.getLocalRepository()) + .satisfiesAnyOf( + repo -> assertThat(repo).isEqualTo("/home/user/.m2/repository"), + repo -> assertThat(repo).endsWith("\\home\\user\\.m2\\repository")); + } + + @Test + void testSettingsWithServers() throws Exception { + Settings settings = assertThat(execute("settings-servers-1")) + .extracting(SettingsBuildingResult::getEffectiveSettings) + .actual(); + + assertThat(settings.getDelegate().getServers()) + .hasSize(2) + .usingRecursiveFieldByFieldElementComparator(RecursiveComparisonConfiguration.builder() + .withIgnoredFields("locations") + .build()) + .containsExactlyInAnyOrder( + Server.newBuilder() + .id("server-1") + .username("username1") + .password("password1") + .build(), + Server.newBuilder() + .id("server-2") + .username("username2") + .password("password2") + .build()); + } + + @Test + void testSettingsWithServersAndAliases() throws Exception { + Settings settings = assertThat(execute("settings-servers-2")) + .extracting(SettingsBuildingResult::getEffectiveSettings) + .actual(); + + assertThat(settings.getDelegate().getServers()) + .hasSize(6) + .usingRecursiveFieldByFieldElementComparator(RecursiveComparisonConfiguration.builder() + .withIgnoredFields("locations") + .build()) + .containsExactlyInAnyOrder( + Server.newBuilder() + .id("server-1") + .username("username1") + .password("password1") + .ids(List.of("server-11", "server-12")) + .build(), + Server.newBuilder() + .id("server-11") + .username("username1") + .password("password1") + .build(), + Server.newBuilder() + .id("server-12") + .username("username1") + .password("password1") + .build(), + Server.newBuilder() + .id("server-2") + .username("username2") + .password("password2") + .ids(List.of("server-21")) + .build(), + Server.newBuilder() + .id("server-21") + .username("username2") + .password("password2") + .build(), + Server.newBuilder() + .id("server-3") + .username("username3") + .password("password3") + .build()); + } + + @Test + void testSettingsWithDuplicateServersIds() throws Exception { + SettingsBuildingResult result = execute("settings-servers-3"); + + assertThat(result.getProblems()) + .hasSize(1) + .extracting(SettingsProblem::getMessage) + .containsExactly("'servers.server.id' must be unique but found duplicate server with id server-2"); } } 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..1504f536ab11 --- /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..3fe2937c1fb5 --- /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 6aaa0e4e4246..66ecd27c77bb 100644 --- a/compat/maven-settings/pom.xml +++ b/compat/maven-settings/pom.xml @@ -75,6 +75,7 @@ under the License. src/main/mdo/settings.mdo + forcedIOModelVersion=1.2.0 packageModelV3=org.apache.maven.settings packageModelV4=org.apache.maven.api.settings 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..7119b78f0ceb 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 @@ -26,6 +26,8 @@ import java.io.InputStream; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; @@ -62,7 +64,6 @@ /** * Builds the effective settings from a user settings file and/or a global settings file. - * */ @Named public class DefaultSettingsBuilder implements SettingsBuilder { @@ -203,6 +204,12 @@ private Settings readSettings( settings = interpolate(settings, request, problems); settings = decrypt(settingsSource, settings, request, problems); + if (!isProjectSettings) { + settings = Settings.newBuilder(settings, false) + .servers(serversByIds(settings.getServers())) + .build(); + } + settingsValidator.validate(settings, isProjectSettings, problems); if (isProjectSettings) { @@ -228,6 +235,22 @@ private Settings readSettings( return settings; } + private List serversByIds(List servers) { + + if (servers.stream().allMatch(server -> server.getIds().isEmpty())) { + return servers; + } + + ArrayList result = new ArrayList<>(servers); + + servers.stream().filter(server -> !server.getIds().isEmpty()).forEach(server -> server.getIds() + .forEach(id -> result.add(Server.newBuilder(server) + .id(id) + .ids(Collections.emptyList()) + .build()))); + return result; + } + private Settings interpolate( Settings settings, SettingsBuilderRequest request, ProblemCollector problems) { UnaryOperator src; 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..accabb8d8e54 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,15 +20,20 @@ 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.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.assertj.core.api.recursive.comparison.RecursiveComparisonConfiguration; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -36,9 +41,10 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; -import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.assertj.core.api.Assertions.assertThat; /** + * */ @ExtendWith(MockitoExtension.class) class DefaultSettingsBuilderFactoryTest { @@ -53,23 +59,115 @@ void setup() { .thenReturn(new DefaultSettingsXmlFactory()); } - @Test - void testCompleteWiring() { + SettingsBuilderResult execute(String settingsName) { SettingsBuilder builder = new DefaultSettingsBuilder(new DefaultSettingsXmlFactory(), new DefaultInterpolator(), Map.of()); - assertNotNull(builder); + assertThat(builder).isNotNull(); 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 assertThat(result).isNotNull().actual(); + } + + @Test + void testCompleteWiring() { + Settings settings = assertThat(execute("settings-simple")) + .extracting(SettingsBuilderResult::getEffectiveSettings) + .actual(); + + assertThat(settings.getLocalRepository()) + .satisfiesAnyOf( + repo -> assertThat(repo).isEqualTo("${user.home}/.m2/repository"), + repo -> assertThat(repo).endsWith("\\${user.home}\\.m2\\repository")); + } + + @Test + void testSettingsWithServers() { + Settings settings = assertThat(execute("settings-servers-1")) + .extracting(SettingsBuilderResult::getEffectiveSettings) + .actual(); + + assertThat(settings.getServers()) + .hasSize(2) + .usingRecursiveFieldByFieldElementComparator(RecursiveComparisonConfiguration.builder() + .withIgnoredFields("locations") + .build()) + .containsExactlyInAnyOrder( + Server.newBuilder() + .id("server-1") + .username("username1") + .password("password1") + .build(), + Server.newBuilder() + .id("server-2") + .username("username2") + .password("password2") + .build()); + } + + @Test + void testSettingsWithServersAndAliases() { + Settings settings = assertThat(execute("settings-servers-2")) + .extracting(SettingsBuilderResult::getEffectiveSettings) + .actual(); + + assertThat(settings.getLocalRepository()).isEqualTo("${user.home}/.m2/repository"); + + assertThat(settings.getServers()) + .hasSize(6) + .usingRecursiveFieldByFieldElementComparator(RecursiveComparisonConfiguration.builder() + .withIgnoredFields("locations") + .build()) + .containsExactlyInAnyOrder( + Server.newBuilder() + .id("server-1") + .username("username1") + .password("password1") + .ids(List.of("server-11", "server-12")) + .build(), + Server.newBuilder() + .id("server-11") + .username("username1") + .password("password1") + .build(), + Server.newBuilder() + .id("server-12") + .username("username1") + .password("password1") + .build(), + Server.newBuilder() + .id("server-2") + .username("username2") + .password("password2") + .ids(List.of("server-21")) + .build(), + Server.newBuilder() + .id("server-21") + .username("username2") + .password("password2") + .build(), + Server.newBuilder() + .id("server-3") + .username("username3") + .password("password3") + .build()); + } + + @Test + void testSettingsWithDuplicateServersIds() throws Exception { + SettingsBuilderResult result = execute("settings-servers-3"); + + assertThat(result.getProblems().problems()) + .hasSize(1) + .extracting(BuilderProblem::getMessage) + .containsExactly("'servers.server.id' must be unique but found duplicate server with id server-2"); } 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/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..1504f536ab11 --- /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..3fe2937c1fb5 --- /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 65f1eb0a7c5a..5608e5d4cd3e 100644 --- a/impl/maven-support/pom.xml +++ b/impl/maven-support/pom.xml @@ -136,6 +136,7 @@ under the License. + forcedIOModelVersion=1.2.0 packageModelV3=org.apache.maven.settings packageModelV4=org.apache.maven.api.settings From 81ff6376c7e219ca4681097926b8d3e1edaa1993 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Thu, 15 May 2025 00:15:34 +0200 Subject: [PATCH 02/11] Apply review suggestion - 1 --- .../building/DefaultSettingsBuilder.java | 18 ++++++++++----- .../DefaultSettingsBuilderFactoryTest.java | 4 ---- .../maven/impl/DefaultSettingsBuilder.java | 23 +++++++++++-------- 3 files changed, 26 insertions(+), 19 deletions(-) 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 dd4ad96215b0..4ac6fde1a7f6 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,10 +26,11 @@ 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.Collectors; +import java.util.stream.Stream; import org.apache.maven.building.FileSource; import org.apache.maven.building.Source; @@ -261,11 +262,16 @@ private List serversByIds(List servers) { return servers; } - ArrayList result = new ArrayList<>(servers); - - servers.stream().filter(server -> !server.getIds().isEmpty()).forEach(server -> server.getIds() - .forEach(id -> result.add(newServer(server, id)))); - return result; + return servers.stream() + .flatMap(server -> { + List ids = server.getIds(); + if (ids.isEmpty()) { + return Stream.of(server); + } else { + return Stream.concat(Stream.of(server), ids.stream().map(id -> newServer(server, id))); + } + }) + .collect(Collectors.toList()); } private Server newServer(Server server, String id) { 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 15219a2ca5fd..181c8576ca01 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 @@ -37,10 +37,6 @@ private File getSettings(String name) { return new File("src/test/resources/settings/factory/" + name + ".xml").getAbsoluteFile(); } - private org.apache.maven.settings.Server asServer(Server delegate) { - return new org.apache.maven.settings.Server(delegate); - } - SettingsBuildingResult execute(String settingsName) throws Exception { Properties properties = new Properties(); properties.setProperty("user.home", "/home/user"); 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 7119b78f0ceb..f1c401ea5697 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 @@ -26,13 +26,14 @@ import java.io.InputStream; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; import java.util.function.UnaryOperator; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.maven.api.Constants; import org.apache.maven.api.ProtoSession; @@ -241,14 +242,18 @@ private List serversByIds(List servers) { return servers; } - ArrayList result = new ArrayList<>(servers); - - servers.stream().filter(server -> !server.getIds().isEmpty()).forEach(server -> server.getIds() - .forEach(id -> result.add(Server.newBuilder(server) - .id(id) - .ids(Collections.emptyList()) - .build()))); - return result; + return servers.stream() + .flatMap(server -> { + List ids = server.getIds(); + if (ids.isEmpty()) { + return Stream.of(server); + } + return Stream.concat(Stream.of(server), ids.stream().map(id -> Server.newBuilder(server, true) + .id(id) + .ids(Collections.emptyList()) + .build())); + }) + .collect(Collectors.toList()); } private Settings interpolate( From c303f21183148cc4e746a5c6af88ffc8e7a56f69 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Thu, 15 May 2025 20:22:50 +0200 Subject: [PATCH 03/11] Apply review suggestion - 2 --- .../building/DefaultSettingsBuilder.java | 24 ++++----------- .../maven/impl/DefaultSettingsBuilder.java | 30 +++++-------------- 2 files changed, 14 insertions(+), 40 deletions(-) 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 4ac6fde1a7f6..90bcfdc38926 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 @@ -29,7 +29,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.maven.building.FileSource; @@ -257,27 +256,16 @@ public Object execute(String expression, Object value) { } private List serversByIds(List servers) { - - if (servers.stream().allMatch(server -> server.getIds().isEmpty())) { - return servers; - } - return servers.stream() - .flatMap(server -> { - List ids = server.getIds(); - if (ids.isEmpty()) { - return Stream.of(server); - } else { - return Stream.concat(Stream.of(server), ids.stream().map(id -> newServer(server, id))); - } - }) - .collect(Collectors.toList()); + .flatMap(server -> Stream.concat( + Stream.of(server), server.getIds().stream().map(id -> serverAlias(server, id)))) + .toList(); } - private Server newServer(Server server, String id) { - return new Server(org.apache.maven.api.settings.Server.newBuilder(server.getDelegate(), false) + private Server serverAlias(Server server, String id) { + return new Server(org.apache.maven.api.settings.Server.newBuilder(server.getDelegate(), true) .id(id) - .ids(Collections.emptyList()) + .ids(List.of()) .build()); } } 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 f1c401ea5697..2be376599b5c 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 @@ -26,13 +26,11 @@ import java.io.InputStream; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; import java.util.function.UnaryOperator; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.maven.api.Constants; @@ -206,9 +204,7 @@ private Settings readSettings( settings = decrypt(settingsSource, settings, request, problems); if (!isProjectSettings) { - settings = Settings.newBuilder(settings, false) - .servers(serversByIds(settings.getServers())) - .build(); + settings = settings.withServers(serversByIds(settings.getServers())); } settingsValidator.validate(settings, isProjectSettings, problems); @@ -237,23 +233,14 @@ private Settings readSettings( } private List serversByIds(List servers) { - - if (servers.stream().allMatch(server -> server.getIds().isEmpty())) { - return servers; - } - return servers.stream() - .flatMap(server -> { - List ids = server.getIds(); - if (ids.isEmpty()) { - return Stream.of(server); - } - return Stream.concat(Stream.of(server), ids.stream().map(id -> Server.newBuilder(server, true) - .id(id) - .ids(Collections.emptyList()) - .build())); - }) - .collect(Collectors.toList()); + .flatMap(server -> Stream.concat( + Stream.of(server), server.getIds().stream().map(id -> serverAlias(server, id)))) + .toList(); + } + + private Server serverAlias(Server server, String id) { + return Server.newBuilder(server, true).id(id).ids(List.of()).build(); } private Settings interpolate( @@ -376,7 +363,6 @@ public org.apache.maven.api.model.Profile convert(Profile profile) { /** * Collects the output of the settings builder. - * */ static class DefaultSettingsBuilderResult implements SettingsBuilderResult { From 059ffa7a0f9a7533c607d9374280a2b832787835 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Mon, 19 May 2025 20:54:39 +0200 Subject: [PATCH 04/11] cleanup of introduced comments --- api/maven-api-settings/src/main/mdo/settings.mdo | 2 -- compat/maven-settings/pom.xml | 3 +-- impl/maven-support/pom.xml | 3 +-- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/api/maven-api-settings/src/main/mdo/settings.mdo b/api/maven-api-settings/src/main/mdo/settings.mdo index 05183ae9501b..f7eb554d5c62 100644 --- a/api/maven-api-settings/src/main/mdo/settings.mdo +++ b/api/maven-api-settings/src/main/mdo/settings.mdo @@ -181,7 +181,6 @@ repositories - 1.3.0+ The lists of the remote repositories. @@ -193,7 +192,6 @@ pluginRepositories - 1.3.0+ The lists of the remote repositories for discovering plugins. diff --git a/compat/maven-settings/pom.xml b/compat/maven-settings/pom.xml index 66ecd27c77bb..78119cf62b32 100644 --- a/compat/maven-settings/pom.xml +++ b/compat/maven-settings/pom.xml @@ -75,8 +75,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-support/pom.xml b/impl/maven-support/pom.xml index 5608e5d4cd3e..b1c334995ed8 100644 --- a/impl/maven-support/pom.xml +++ b/impl/maven-support/pom.xml @@ -136,8 +136,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 From ed077a0b088256a073a56ae8509c5814ee71e35e Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Sat, 11 Apr 2026 20:17:10 +0200 Subject: [PATCH 05/11] Refresh changes - rename ids to aliases --- api/maven-api-settings/pom.xml | 4 + .../src/main/mdo/settings.mdo | 6 +- compat/maven-settings-builder/pom.xml | 5 - .../building/DefaultSettingsBuilder.java | 4 +- .../DefaultSettingsBuilderFactoryTest.java | 148 ++++++++--------- .../settings/factory/settings-servers-2.xml | 14 +- .../settings/factory/settings-servers-3.xml | 6 +- .../maven/impl/DefaultSettingsBuilder.java | 4 +- .../DefaultSettingsBuilderFactoryTest.java | 153 +++++++++--------- .../resources/settings/settings-servers-2.xml | 14 +- .../resources/settings/settings-servers-3.xml | 6 +- impl/maven-support/pom.xml | 4 + 12 files changed, 178 insertions(+), 190 deletions(-) diff --git a/api/maven-api-settings/pom.xml b/api/maven-api-settings/pom.xml index a73c2ce1de0d..11b87448607f 100644 --- a/api/maven-api-settings/pom.xml +++ b/api/maven-api-settings/pom.xml @@ -53,7 +53,11 @@ under the License. org.codehaus.modello modello-maven-plugin + 2.6.1-SNAPSHOT + + 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 f7eb554d5c62..471c065dcbc7 100644 --- a/api/maven-api-settings/src/main/mdo/settings.mdo +++ b/api/maven-api-settings/src/main/mdo/settings.mdo @@ -530,11 +530,11 @@ - ids + aliases 1.3.0+ - List of additional ids for server. - + List of additional server aliases. For each alias, an additional server will be generated by copying the entire configuration, but using a different ID. + This is useful when the same credentials should be used for multiple servers. String * diff --git a/compat/maven-settings-builder/pom.xml b/compat/maven-settings-builder/pom.xml index 9b94d3a498f3..24e62ee65639 100644 --- a/compat/maven-settings-builder/pom.xml +++ b/compat/maven-settings-builder/pom.xml @@ -78,11 +78,6 @@ under the License. junit-jupiter-api test - - org.assertj - assertj-core - test - 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 90bcfdc38926..3e11798f06ae 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 @@ -258,14 +258,14 @@ public Object execute(String expression, Object value) { private List serversByIds(List servers) { return servers.stream() .flatMap(server -> Stream.concat( - Stream.of(server), server.getIds().stream().map(id -> serverAlias(server, id)))) + 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) - .ids(List.of()) + .aliases(List.of()) .build()); } } 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 181c8576ca01..cd5fc00516ef 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 @@ -24,10 +24,11 @@ import org.apache.maven.api.settings.Server; import org.apache.maven.settings.Settings; -import org.assertj.core.api.recursive.comparison.RecursiveComparisonConfiguration; import org.junit.jupiter.api.Test; -import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; /** */ @@ -42,105 +43,96 @@ SettingsBuildingResult execute(String settingsName) throws Exception { properties.setProperty("user.home", "/home/user"); SettingsBuilder builder = new DefaultSettingsBuilderFactory().newInstance(); - assertThat(builder).isNotNull(); + assertNotNull(builder); DefaultSettingsBuildingRequest request = new DefaultSettingsBuildingRequest(); request.setSystemProperties(properties); request.setUserSettingsFile(getSettings(settingsName)); SettingsBuildingResult result = builder.build(request); - return assertThat(result).isNotNull().actual(); + assertNotNull(result); + return result; } @Test void testCompleteWiring() throws Exception { - Settings settings = assertThat(execute("simple")) - .extracting(SettingsBuildingResult::getEffectiveSettings) - .actual(); - - assertThat(settings.getLocalRepository()) - .satisfiesAnyOf( - repo -> assertThat(repo).isEqualTo("/home/user/.m2/repository"), - repo -> assertThat(repo).endsWith("\\home\\user\\.m2\\repository")); + 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 = assertThat(execute("settings-servers-1")) - .extracting(SettingsBuildingResult::getEffectiveSettings) - .actual(); - - assertThat(settings.getDelegate().getServers()) - .hasSize(2) - .usingRecursiveFieldByFieldElementComparator(RecursiveComparisonConfiguration.builder() - .withIgnoredFields("locations") - .build()) - .containsExactlyInAnyOrder( - Server.newBuilder() - .id("server-1") - .username("username1") - .password("password1") - .build(), - Server.newBuilder() - .id("server-2") - .username("username2") - .password("password2") - .build()); + 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 = assertThat(execute("settings-servers-2")) - .extracting(SettingsBuildingResult::getEffectiveSettings) - .actual(); - - assertThat(settings.getDelegate().getServers()) - .hasSize(6) - .usingRecursiveFieldByFieldElementComparator(RecursiveComparisonConfiguration.builder() - .withIgnoredFields("locations") - .build()) - .containsExactlyInAnyOrder( - Server.newBuilder() - .id("server-1") - .username("username1") - .password("password1") - .ids(List.of("server-11", "server-12")) - .build(), - Server.newBuilder() - .id("server-11") - .username("username1") - .password("password1") - .build(), - Server.newBuilder() - .id("server-12") - .username("username1") - .password("password1") - .build(), - Server.newBuilder() - .id("server-2") - .username("username2") - .password("password2") - .ids(List.of("server-21")) - .build(), - Server.newBuilder() - .id("server-21") - .username("username2") - .password("password2") - .build(), - Server.newBuilder() - .id("server-3") - .username("username3") - .password("password3") - .build()); + 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(server11.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"); - assertThat(result.getProblems()) - .hasSize(1) - .extracting(SettingsProblem::getMessage) - .containsExactly("'servers.server.id' must be unique but found duplicate server with id server-2"); + List problems = result.getProblems(); + assertEquals(1, problems.size()); + assertEquals( + "'servers.server.id' must be unique but found duplicate server with id server-2", + problems.get(0).getMessage()); } } 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 index 1504f536ab11..a8464a49a302 100644 --- 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 @@ -24,18 +24,18 @@ under the License. server-1 - - server-11 - server-12 - + + server-11 + server-12 + username1 password1 server-2 - - server-21 - + + server-21 + username2 password2 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 index 3fe2937c1fb5..e0a13454e2e8 100644 --- 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 @@ -24,9 +24,9 @@ under the License. server-1 - - server-2 - + + server-2 + username1 password1 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 2be376599b5c..ff4707b0bebe 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 @@ -235,12 +235,12 @@ private Settings readSettings( private List serversByIds(List servers) { return servers.stream() .flatMap(server -> Stream.concat( - Stream.of(server), server.getIds().stream().map(id -> serverAlias(server, id)))) + 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).ids(List.of()).build(); + return Server.newBuilder(server, true).id(id).aliases(List.of()).build(); } private Settings interpolate( 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 accabb8d8e54..a143d41ff9da 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 @@ -25,6 +25,7 @@ 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; @@ -33,7 +34,6 @@ import org.apache.maven.api.settings.Server; import org.apache.maven.api.settings.Settings; import org.apache.maven.impl.model.DefaultInterpolator; -import org.assertj.core.api.recursive.comparison.RecursiveComparisonConfiguration; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -41,7 +41,9 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; -import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @@ -62,7 +64,7 @@ void setup() { SettingsBuilderResult execute(String settingsName) { SettingsBuilder builder = new DefaultSettingsBuilder(new DefaultSettingsXmlFactory(), new DefaultInterpolator(), Map.of()); - assertThat(builder).isNotNull(); + assertNotNull(builder); SettingsBuilderRequest request = SettingsBuilderRequest.builder() .session(session) @@ -70,101 +72,92 @@ SettingsBuilderResult execute(String settingsName) { .build(); SettingsBuilderResult result = builder.build(request); - return assertThat(result).isNotNull().actual(); + assertNotNull(result); + return result; } @Test void testCompleteWiring() { - Settings settings = assertThat(execute("settings-simple")) - .extracting(SettingsBuilderResult::getEffectiveSettings) - .actual(); - - assertThat(settings.getLocalRepository()) - .satisfiesAnyOf( - repo -> assertThat(repo).isEqualTo("${user.home}/.m2/repository"), - repo -> assertThat(repo).endsWith("\\${user.home}\\.m2\\repository")); + 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 = assertThat(execute("settings-servers-1")) - .extracting(SettingsBuilderResult::getEffectiveSettings) - .actual(); - - assertThat(settings.getServers()) - .hasSize(2) - .usingRecursiveFieldByFieldElementComparator(RecursiveComparisonConfiguration.builder() - .withIgnoredFields("locations") - .build()) - .containsExactlyInAnyOrder( - Server.newBuilder() - .id("server-1") - .username("username1") - .password("password1") - .build(), - Server.newBuilder() - .id("server-2") - .username("username2") - .password("password2") - .build()); + 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 = assertThat(execute("settings-servers-2")) - .extracting(SettingsBuilderResult::getEffectiveSettings) - .actual(); - - assertThat(settings.getLocalRepository()).isEqualTo("${user.home}/.m2/repository"); - - assertThat(settings.getServers()) - .hasSize(6) - .usingRecursiveFieldByFieldElementComparator(RecursiveComparisonConfiguration.builder() - .withIgnoredFields("locations") - .build()) - .containsExactlyInAnyOrder( - Server.newBuilder() - .id("server-1") - .username("username1") - .password("password1") - .ids(List.of("server-11", "server-12")) - .build(), - Server.newBuilder() - .id("server-11") - .username("username1") - .password("password1") - .build(), - Server.newBuilder() - .id("server-12") - .username("username1") - .password("password1") - .build(), - Server.newBuilder() - .id("server-2") - .username("username2") - .password("password2") - .ids(List.of("server-21")) - .build(), - Server.newBuilder() - .id("server-21") - .username("username2") - .password("password2") - .build(), - Server.newBuilder() - .id("server-3") - .username("username3") - .password("password3") - .build()); + 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(server11.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"); - assertThat(result.getProblems().problems()) - .hasSize(1) - .extracting(BuilderProblem::getMessage) - .containsExactly("'servers.server.id' must be unique but found duplicate server with id server-2"); + ProblemCollector problems = result.getProblems(); + assertEquals(1, problems.problems().count()); + assertEquals( + "'servers.server.id' must be unique but found duplicate server with id server-2", + problems.problems().findFirst().orElseThrow().getMessage()); } private Path getSettings(String name) { 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 index 1504f536ab11..a8464a49a302 100644 --- a/impl/maven-impl/src/test/resources/settings/settings-servers-2.xml +++ b/impl/maven-impl/src/test/resources/settings/settings-servers-2.xml @@ -24,18 +24,18 @@ under the License. server-1 - - server-11 - server-12 - + + server-11 + server-12 + username1 password1 server-2 - - server-21 - + + server-21 + username2 password2 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 index 3fe2937c1fb5..e0a13454e2e8 100644 --- a/impl/maven-impl/src/test/resources/settings/settings-servers-3.xml +++ b/impl/maven-impl/src/test/resources/settings/settings-servers-3.xml @@ -24,9 +24,9 @@ under the License. server-1 - - server-2 - + + server-2 + username1 password1 diff --git a/impl/maven-support/pom.xml b/impl/maven-support/pom.xml index b1c334995ed8..f3f6761e1085 100644 --- a/impl/maven-support/pom.xml +++ b/impl/maven-support/pom.xml @@ -68,6 +68,7 @@ under the License. org.codehaus.modello modello-maven-plugin + 2.6.1-SNAPSHOT velocity-lifecycle @@ -123,6 +124,9 @@ under the License. generate-sources + + alias + 2.0.0 ${project.basedir}/../../api/maven-api-settings ${project.basedir}/../../src/mdo From af6c00df55d6a590c5cc6970a45b278d5b44818a Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Tue, 14 Apr 2026 09:02:43 +0200 Subject: [PATCH 06/11] Use modello 2.7.0 --- api/maven-api-settings/pom.xml | 1 - impl/maven-support/pom.xml | 1 - pom.xml | 5 +++++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/api/maven-api-settings/pom.xml b/api/maven-api-settings/pom.xml index 11b87448607f..8262c2efde5a 100644 --- a/api/maven-api-settings/pom.xml +++ b/api/maven-api-settings/pom.xml @@ -53,7 +53,6 @@ under the License. org.codehaus.modello modello-maven-plugin - 2.6.1-SNAPSHOT alias diff --git a/impl/maven-support/pom.xml b/impl/maven-support/pom.xml index f3f6761e1085..7171363b74fc 100644 --- a/impl/maven-support/pom.xml +++ b/impl/maven-support/pom.xml @@ -68,7 +68,6 @@ under the License. org.codehaus.modello modello-maven-plugin - 2.6.1-SNAPSHOT velocity-lifecycle diff --git a/pom.xml b/pom.xml index d83ddb44cb59..56470eaeac22 100644 --- a/pom.xml +++ b/pom.xml @@ -743,6 +743,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 From 18c8bca2c7d63c4c19016950c23d19b2c83ffbb6 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Tue, 14 Apr 2026 22:15:40 +0200 Subject: [PATCH 07/11] Fix trailing whitespace --- api/maven-api-settings/src/main/mdo/settings.mdo | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/api/maven-api-settings/src/main/mdo/settings.mdo b/api/maven-api-settings/src/main/mdo/settings.mdo index 471c065dcbc7..34b83cf86869 100644 --- a/api/maven-api-settings/src/main/mdo/settings.mdo +++ b/api/maven-api-settings/src/main/mdo/settings.mdo @@ -532,9 +532,8 @@ aliases 1.3.0+ - - List of additional server aliases. For each alias, an additional server will be generated by copying the entire configuration, but using a different ID. - This is useful when the same credentials should be used for multiple servers. + List of additional server aliases. For each alias, an additional server will be generated by copying the entire configuration, but using a different ID. + This is useful when the same credentials should be used for multiple servers. String * From cd0b8cef993ff2834e705fc86a0b9d96ec00cf7d Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Sun, 7 Jun 2026 23:29:49 +0200 Subject: [PATCH 08/11] Fix tests to check correct server aliases and update aliases description in `settings.mdo`. --- api/maven-api-settings/src/main/mdo/settings.mdo | 4 +++- .../settings/building/DefaultSettingsBuilderFactoryTest.java | 2 +- .../apache/maven/impl/DefaultSettingsBuilderFactoryTest.java | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/api/maven-api-settings/src/main/mdo/settings.mdo b/api/maven-api-settings/src/main/mdo/settings.mdo index 34b83cf86869..ec0ee01d630b 100644 --- a/api/maven-api-settings/src/main/mdo/settings.mdo +++ b/api/maven-api-settings/src/main/mdo/settings.mdo @@ -532,7 +532,9 @@ aliases 1.3.0+ - List of additional server aliases. For each alias, an additional server will be generated by copying the entire configuration, but using a different ID. + List of additional server aliases. For each alias, an additional server will be generated. + Genearte servers items will have the same configuration as the original one, but with the ID specified in this list + 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/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 cd5fc00516ef..fd587d72295a 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 @@ -99,7 +99,7 @@ void testSettingsWithServersAndAliases() throws Exception { Server server12 = getServerById(servers, "server-12"); assertEquals("username1", server12.getUsername()); assertEquals("password1", server12.getPassword()); - assertTrue(server11.getAliases().isEmpty()); + assertTrue(server12.getAliases().isEmpty()); Server server2 = getServerById(servers, "server-2"); assertEquals("username2", server2.getUsername()); 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 a143d41ff9da..5b07aa9e363e 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 @@ -123,7 +123,7 @@ void testSettingsWithServersAndAliases() { Server server12 = getServerById(servers, "server-12"); assertEquals("username1", server12.getUsername()); assertEquals("password1", server12.getPassword()); - assertTrue(server11.getAliases().isEmpty()); + assertTrue(server12.getAliases().isEmpty()); Server server2 = getServerById(servers, "server-2"); assertEquals("username2", server2.getUsername()); From 59d4a563b6534e36f6359634ffd77d01eae31be5 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Tue, 9 Jun 2026 09:02:58 +0200 Subject: [PATCH 09/11] Add validation for server aliases --- .../building/DefaultSettingsBuilder.java | 2 +- .../validation/DefaultSettingsValidator.java | 14 +++++++ .../DefaultSettingsBuilderFactoryTest.java | 2 +- .../DefaultSettingsValidatorTest.java | 38 +++++++++++++++++++ .../maven/impl/DefaultSettingsBuilder.java | 5 ++- .../maven/impl/DefaultSettingsValidator.java | 17 +++++++++ .../DefaultSettingsBuilderFactoryTest.java | 2 +- .../impl/DefaultSettingsValidatorTest.java | 34 +++++++++++++++++ 8 files changed, 109 insertions(+), 5 deletions(-) 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 3e11798f06ae..b80bc1f069b0 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 @@ -183,8 +183,8 @@ private Settings readSettings( return new Settings(); } - settings.setServers(serversByIds(settings.getServers())); settingsValidator.validate(settings, problems); + settings.setServers(serversByIds(settings.getServers())); return settings; } 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 f1913e00de72..3109b11cb756 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,20 @@ 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 (String alias : server.getAliases()) { + if (!serverIds.add(alias)) { + addViolation( + problems, + Severity.WARNING, + "servers.server[" + i + "].aliases", + server.getId(), + "must be unique for all servers id 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 fd587d72295a..99a32ddd6894 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 @@ -132,7 +132,7 @@ void testSettingsWithDuplicateServersIds() throws Exception { List problems = result.getProblems(); assertEquals(1, problems.size()); assertEquals( - "'servers.server.id' must be unique but found duplicate server with id server-2", + "'servers.server[0].aliases' for server-1 must be unique for all servers id 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..472ae9f0be73 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,44 @@ 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.addAliase("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' for server-1 must be unique for all servers id but found duplicate alias server-1"); + } + + @Test + void testMultipleUsageOfAliases() { + Settings settings = new Settings(); + + Server server1 = new Server(); + server1.setId("server-1"); + server1.addAliase("alias-1"); + settings.addServer(server1); + + Server server2 = new Server(); + server2.setId("server-2"); + server2.addAliase("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' for server-2 must be unique for all servers id but found duplicate alias alias-1"); + } + private static class SimpleProblemCollector implements SettingsProblemCollector { List messages = new ArrayList<>(); 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 ff4707b0bebe..ab095ebe9686 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 @@ -203,12 +203,12 @@ private Settings readSettings( settings = interpolate(settings, request, problems); settings = decrypt(settingsSource, settings, request, problems); + settingsValidator.validate(settings, isProjectSettings, problems); + if (!isProjectSettings) { settings = settings.withServers(serversByIds(settings.getServers())); } - settingsValidator.validate(settings, isProjectSettings, problems); - if (isProjectSettings) { settings = Settings.newBuilder(settings, true) .localRepository(null) @@ -224,6 +224,7 @@ private Settings readSettings( .password(null) .filePermissions(null) .directoryPermissions(null) + .aliases(List.of()) .build()) .toList()) .build(); 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 b2df07a6e21c..685387f1b027 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,20 @@ 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 (String alias : server.getAliases()) { + if (!serverIds.add(alias)) { + addViolation( + problems, + BuilderProblem.Severity.WARNING, + "servers.server[" + i + "].aliases", + server.getId(), + "must be unique for all servers id 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 5b07aa9e363e..542773ab20fb 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 @@ -156,7 +156,7 @@ void testSettingsWithDuplicateServersIds() throws Exception { ProblemCollector problems = result.getProblems(); assertEquals(1, problems.problems().count()); assertEquals( - "'servers.server.id' must be unique but found duplicate server with id server-2", + "'servers.server[0].aliases' for server-1 must be unique for all servers id but found duplicate alias server-2", problems.problems().findFirst().orElseThrow().getMessage()); } 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..138475e87ea8 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,37 @@ 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' for server-1 must be unique for all servers id 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' for server-2 must be unique for all servers id but found duplicate alias alias-1", + problems.problems().findFirst().orElseThrow().getMessage()); + } } From daabdc6d885c3272e871684f4f55ed630ee8a253 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Fri, 19 Jun 2026 08:46:48 +0200 Subject: [PATCH 10/11] Next review fixes - check empty value for server aliases --- .../src/main/mdo/settings.mdo | 4 ++-- .../building/DefaultSettingsBuilder.java | 3 ++- .../validation/DefaultSettingsValidator.java | 9 ++++++--- .../DefaultSettingsBuilderFactoryTest.java | 2 +- .../DefaultSettingsValidatorTest.java | 18 ++++++++++++++++-- .../maven/impl/DefaultSettingsValidator.java | 9 ++++++--- .../DefaultSettingsBuilderFactoryTest.java | 2 +- .../impl/DefaultSettingsValidatorTest.java | 17 +++++++++++++++-- 8 files changed, 49 insertions(+), 15 deletions(-) diff --git a/api/maven-api-settings/src/main/mdo/settings.mdo b/api/maven-api-settings/src/main/mdo/settings.mdo index ec0ee01d630b..0e8803b2d464 100644 --- a/api/maven-api-settings/src/main/mdo/settings.mdo +++ b/api/maven-api-settings/src/main/mdo/settings.mdo @@ -532,8 +532,8 @@ aliases 1.3.0+ - List of additional server aliases. For each alias, an additional server will be generated. - Genearte servers items will have the same configuration as the original one, but with the ID specified in this list + 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. 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 b80bc1f069b0..48bb04bb4f5f 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,6 +26,7 @@ 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; @@ -184,7 +185,7 @@ private Settings readSettings( } settingsValidator.validate(settings, problems); - settings.setServers(serversByIds(settings.getServers())); + settings.setServers(new ArrayList<>(serversByIds(settings.getServers()))); return settings; } 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 3109b11cb756..8e497d6b408b 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 @@ -96,14 +96,17 @@ public void validate(Settings settings, SettingsProblemCollector problems) { for (int i = 0; i < servers.size(); i++) { Server server = servers.get(i); - for (String alias : server.getAliases()) { + 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", + "servers.server[" + i + "].aliases[" + a + "]", server.getId(), - "must be unique for all servers id but found duplicate alias " + alias); + "must be unique across all server ids and aliases but found duplicate alias " + alias); } } } 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 99a32ddd6894..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 @@ -132,7 +132,7 @@ void testSettingsWithDuplicateServersIds() throws Exception { List problems = result.getProblems(); assertEquals(1, problems.size()); assertEquals( - "'servers.server[0].aliases' for server-1 must be unique for all servers id but found duplicate alias server-2", + "'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 472ae9f0be73..abc08ff55163 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 @@ -232,7 +232,7 @@ void testValidateServerIdAlias() { assertEquals(1, problems.messages.size()); assertContains( problems.messages.get(0), - "servers.server[0].aliases' for server-1 must be unique for all servers id but found duplicate alias server-1"); + "'servers.server[0].aliases[0]' for server-1 must be unique across all server ids and aliases but found duplicate alias server-1"); } @Test @@ -254,7 +254,21 @@ void testMultipleUsageOfAliases() { assertEquals(1, problems.messages.size()); assertContains( problems.messages.get(0), - "'servers.server[1].aliases' for server-2 must be unique for all servers id but found duplicate alias alias-1"); + "'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.addAliase(""); + 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 { 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 685387f1b027..5e960b152253 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 @@ -129,14 +129,17 @@ public void validate(Settings settings, boolean isProjectSettings, ProblemCollec for (int i = 0; i < servers.size(); i++) { Server server = servers.get(i); - for (String alias : server.getAliases()) { + 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", + "servers.server[" + i + "].aliases[" + a + "]", server.getId(), - "must be unique for all servers id but found duplicate alias " + alias); + "must be unique across all server ids and aliases but found duplicate alias " + alias); } } } 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 542773ab20fb..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 @@ -156,7 +156,7 @@ void testSettingsWithDuplicateServersIds() throws Exception { ProblemCollector problems = result.getProblems(); assertEquals(1, problems.problems().count()); assertEquals( - "'servers.server[0].aliases' for server-1 must be unique for all servers id but found duplicate alias server-2", + "'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()); } 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 138475e87ea8..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 @@ -82,7 +82,7 @@ void testValidateServerIdAlias() { ProblemCollector problems = validator.validate(settings); assertEquals(1, problems.totalProblemsReported()); assertEquals( - "'servers.server[0].aliases' for server-1 must be unique for all servers id but found duplicate alias server-1", + "'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()); } @@ -101,7 +101,20 @@ void testMultipleUsageOfAliases() { ProblemCollector problems = validator.validate(settings); assertEquals(1, problems.totalProblemsReported()); assertEquals( - "'servers.server[1].aliases' for server-2 must be unique for all servers id but found duplicate alias alias-1", + "'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()); } } From 811aa80186da3aa7a77639464d9eff5595971ed2 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Tue, 23 Jun 2026 17:14:03 +0200 Subject: [PATCH 11/11] Add pluralExceptions in compat/maven-settings, simplify condition --- .../settings/validation/DefaultSettingsValidatorTest.java | 8 ++++---- compat/maven-settings/pom.xml | 3 +++ .../org/apache/maven/impl/DefaultSettingsBuilder.java | 4 +--- 3 files changed, 8 insertions(+), 7 deletions(-) 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 abc08ff55163..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 @@ -224,7 +224,7 @@ void testValidateServerIdAlias() { Settings settings = new Settings(); Server server = new Server(); server.setId("server-1"); - server.addAliase("server-1"); + server.addAlias("server-1"); settings.addServer(server); SimpleProblemCollector problems = new SimpleProblemCollector(); @@ -241,12 +241,12 @@ void testMultipleUsageOfAliases() { Server server1 = new Server(); server1.setId("server-1"); - server1.addAliase("alias-1"); + server1.addAlias("alias-1"); settings.addServer(server1); Server server2 = new Server(); server2.setId("server-2"); - server2.addAliase("alias-1"); + server2.addAlias("alias-1"); settings.addServer(server2); SimpleProblemCollector problems = new SimpleProblemCollector(); @@ -262,7 +262,7 @@ void testValidateServerIdAliasesWithEmptyValue() { Settings settings = new Settings(); Server server = new Server(); server.setId("server-1"); - server.addAliase(""); + server.addAlias(""); settings.addServer(server); SimpleProblemCollector problems = new SimpleProblemCollector(); diff --git a/compat/maven-settings/pom.xml b/compat/maven-settings/pom.xml index 78119cf62b32..b057a9d8f67b 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 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 ab095ebe9686..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 @@ -207,9 +207,7 @@ private Settings readSettings( if (!isProjectSettings) { settings = settings.withServers(serversByIds(settings.getServers())); - } - - if (isProjectSettings) { + } else { settings = Settings.newBuilder(settings, true) .localRepository(null) .interactiveMode(false)