diff --git a/api/maven-api-settings/src/main/mdo/settings.mdo b/api/maven-api-settings/src/main/mdo/settings.mdo index fe69efeeff16..f7eb554d5c62 100644 --- a/api/maven-api-settings/src/main/mdo/settings.mdo +++ b/api/maven-api-settings/src/main/mdo/settings.mdo @@ -529,6 +529,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 dac986044776..928f424ba118 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 051b8f44722d..5b9dc8008783 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,9 +29,11 @@ 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; @@ -181,6 +183,7 @@ private Settings readSettings( return new Settings(); } + settings.setServers(serversByIds(settings.getServers())); settingsValidator.validate(settings, problems); return settings; @@ -251,4 +254,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.getIds().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()) + .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..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 @@ -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,110 @@ 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); + 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 253989512052..7a861e35b669 100644 --- a/compat/maven-settings/pom.xml +++ b/compat/maven-settings/pom.xml @@ -75,7 +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-impl/src/main/java/org/apache/maven/impl/DefaultSettingsBuilder.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSettingsBuilder.java index 53731c6009cc..3834f723e951 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 { @@ -203,6 +203,10 @@ private Settings readSettings( settings = interpolate(settings, request, problems); settings = decrypt(settingsSource, settings, request, problems); + if (!isProjectSettings) { + settings = settings.withServers(serversByIds(settings.getServers())); + } + settingsValidator.validate(settings, isProjectSettings, problems); if (isProjectSettings) { @@ -228,6 +232,17 @@ private Settings readSettings( return settings; } + private List serversByIds(List servers) { + return servers.stream() + .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( Settings settings, SettingsBuilderRequest request, ProblemCollector problems) { UnaryOperator src; @@ -332,7 +347,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/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 22f7fe8fc10b..89d81ecea8f7 100644 --- a/impl/maven-support/pom.xml +++ b/impl/maven-support/pom.xml @@ -118,7 +118,7 @@ - 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