diff --git a/api/maven-api-settings/pom.xml b/api/maven-api-settings/pom.xml
index a73c2ce1de0d..8262c2efde5a 100644
--- a/api/maven-api-settings/pom.xml
+++ b/api/maven-api-settings/pom.xml
@@ -54,6 +54,9 @@ under the License.
org.codehaus.modello
modello-maven-plugin
+
+ alias
+
2.0.0
${project.basedir}/../../src/mdo
diff --git a/api/maven-api-settings/src/main/mdo/settings.mdo b/api/maven-api-settings/src/main/mdo/settings.mdo
index fe69efeeff16..34b83cf86869 100644
--- a/api/maven-api-settings/src/main/mdo/settings.mdo
+++ b/api/maven-api-settings/src/main/mdo/settings.mdo
@@ -529,6 +529,16 @@
Extra configuration for the transport layer.
+
+ 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.
+
+ String
+ *
+
+
diff --git a/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilder.java b/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilder.java
index 140393bf0659..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
@@ -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.getAliases().stream().map(id -> serverAlias(server, id))))
+ .toList();
+ }
+
+ private Server serverAlias(Server server, String id) {
+ return new Server(org.apache.maven.api.settings.Server.newBuilder(server.getDelegate(), true)
+ .id(id)
+ .aliases(List.of())
+ .build());
+ }
}
diff --git a/compat/maven-settings-builder/src/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..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
@@ -19,10 +19,16 @@
package org.apache.maven.settings.building;
import java.io.File;
+import java.util.List;
+import java.util.Properties;
+import org.apache.maven.api.settings.Server;
+import org.apache.maven.settings.Settings;
import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
*/
@@ -32,17 +38,101 @@ private File getSettings(String name) {
return new File("src/test/resources/settings/factory/" + name + ".xml").getAbsoluteFile();
}
- @Test
- void testCompleteWiring() throws Exception {
+ SettingsBuildingResult execute(String settingsName) throws Exception {
+ Properties properties = new Properties();
+ properties.setProperty("user.home", "/home/user");
+
SettingsBuilder builder = new DefaultSettingsBuilderFactory().newInstance();
assertNotNull(builder);
DefaultSettingsBuildingRequest request = new DefaultSettingsBuildingRequest();
- request.setSystemProperties(System.getProperties());
- request.setUserSettingsFile(getSettings("simple"));
+ request.setSystemProperties(properties);
+ request.setUserSettingsFile(getSettings(settingsName));
SettingsBuildingResult result = builder.build(request);
assertNotNull(result);
- assertNotNull(result.getEffectiveSettings());
+ return result;
+ }
+
+ @Test
+ void testCompleteWiring() throws Exception {
+ Settings settings = execute("simple").getEffectiveSettings();
+
+ String localRepository = settings.getLocalRepository();
+ assertTrue(localRepository.equals("/home/user/.m2/repository")
+ || localRepository.endsWith("\\home\\user\\.m2\\repository"));
+ }
+
+ @Test
+ void testSettingsWithServers() throws Exception {
+ Settings settings = execute("settings-servers-1").getEffectiveSettings();
+
+ List servers = settings.getDelegate().getServers();
+ assertEquals(2, servers.size());
+
+ Server server1 = getServerById(servers, "server-1");
+ assertEquals("username1", server1.getUsername());
+ assertEquals("password1", server1.getPassword());
+
+ Server server2 = getServerById(servers, "server-2");
+ assertEquals("username2", server2.getUsername());
+ assertEquals("password2", server2.getPassword());
+ }
+
+ @Test
+ void testSettingsWithServersAndAliases() throws Exception {
+ Settings settings = execute("settings-servers-2").getEffectiveSettings();
+
+ List servers = settings.getDelegate().getServers();
+ assertEquals(6, servers.size());
+
+ Server server1 = getServerById(servers, "server-1");
+ assertEquals("username1", server1.getUsername());
+ assertEquals("password1", server1.getPassword());
+ assertEquals(List.of("server-11", "server-12"), server1.getAliases());
+
+ Server server11 = getServerById(servers, "server-11");
+ assertEquals("username1", server11.getUsername());
+ assertEquals("password1", server11.getPassword());
+ assertTrue(server11.getAliases().isEmpty());
+
+ Server server12 = getServerById(servers, "server-12");
+ assertEquals("username1", server12.getUsername());
+ assertEquals("password1", server12.getPassword());
+ assertTrue(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");
+
+ 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-1.xml b/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-1.xml
new file mode 100644
index 000000000000..7076749943b2
--- /dev/null
+++ b/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-1.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+ ${user.home}/.m2/repository
+
+
+ server-1
+ username1
+ password1
+
+
+ server-2
+ username2
+ password2
+
+
+
+
diff --git a/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-2.xml b/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-2.xml
new file mode 100644
index 000000000000..a8464a49a302
--- /dev/null
+++ b/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-2.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+ ${user.home}/.m2/repository
+
+
+ server-1
+
+ server-11
+ server-12
+
+ username1
+ password1
+
+
+ server-2
+
+ server-21
+
+ username2
+ password2
+
+
+ server-3
+ username3
+ password3
+
+
+
+
diff --git a/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-3.xml b/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-3.xml
new file mode 100644
index 000000000000..e0a13454e2e8
--- /dev/null
+++ b/compat/maven-settings-builder/src/test/resources/settings/factory/settings-servers-3.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+ ${user.home}/.m2/repository
+
+
+ server-1
+
+ server-2
+
+ username1
+ password1
+
+
+ server-2
+ username2
+ password2
+
+
+
+
diff --git a/compat/maven-settings/pom.xml b/compat/maven-settings/pom.xml
index 6aaa0e4e4246..78119cf62b32 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 be7dd9e86312..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
@@ -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.getAliases().stream().map(id -> serverAlias(server, id))))
+ .toList();
+ }
+
+ private Server serverAlias(Server server, String id) {
+ return Server.newBuilder(server, true).id(id).aliases(List.of()).build();
+ }
+
private Settings interpolate(
Settings settings, SettingsBuilderRequest request, ProblemCollector problems) {
UnaryOperator src;
@@ -348,7 +363,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..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
@@ -20,14 +20,19 @@
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.List;
import java.util.Map;
import org.apache.maven.api.Session;
+import org.apache.maven.api.services.BuilderProblem;
+import org.apache.maven.api.services.ProblemCollector;
import org.apache.maven.api.services.SettingsBuilder;
import org.apache.maven.api.services.SettingsBuilderRequest;
import org.apache.maven.api.services.SettingsBuilderResult;
import org.apache.maven.api.services.Sources;
import org.apache.maven.api.services.xml.SettingsXmlFactory;
+import org.apache.maven.api.settings.Server;
+import org.apache.maven.api.settings.Settings;
import org.apache.maven.impl.model.DefaultInterpolator;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -36,9 +41,12 @@
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
+ *
*/
@ExtendWith(MockitoExtension.class)
class DefaultSettingsBuilderFactoryTest {
@@ -53,23 +61,106 @@ void setup() {
.thenReturn(new DefaultSettingsXmlFactory());
}
- @Test
- void testCompleteWiring() {
+ SettingsBuilderResult execute(String settingsName) {
SettingsBuilder builder =
new DefaultSettingsBuilder(new DefaultSettingsXmlFactory(), new DefaultInterpolator(), Map.of());
assertNotNull(builder);
SettingsBuilderRequest request = SettingsBuilderRequest.builder()
.session(session)
- .userSettingsSource(Sources.buildSource(getSettings("settings-simple")))
+ .userSettingsSource(Sources.buildSource(getSettings(settingsName)))
.build();
SettingsBuilderResult result = builder.build(request);
assertNotNull(result);
- assertNotNull(result.getEffectiveSettings());
+ return result;
+ }
+
+ @Test
+ void testCompleteWiring() {
+ Settings settings = execute("settings-simple").getEffectiveSettings();
+
+ String localRepository = settings.getLocalRepository();
+ assertTrue(localRepository.equals("${user.home}/.m2/repository")
+ || localRepository.endsWith("\\${user.home}\\.m2\\repository"));
+ }
+
+ @Test
+ void testSettingsWithServers() {
+ Settings settings = execute("settings-servers-1").getEffectiveSettings();
+
+ List servers = settings.getServers();
+ assertEquals(2, servers.size());
+
+ Server server1 = getServerById(servers, "server-1");
+ assertEquals("username1", server1.getUsername());
+ assertEquals("password1", server1.getPassword());
+
+ Server server2 = getServerById(servers, "server-2");
+ assertEquals("username2", server2.getUsername());
+ assertEquals("password2", server2.getPassword());
+ }
+
+ @Test
+ void testSettingsWithServersAndAliases() {
+ Settings settings = execute("settings-servers-2").getEffectiveSettings();
+
+ assertEquals("${user.home}/.m2/repository", settings.getLocalRepository());
+
+ List servers = settings.getServers();
+ assertEquals(6, servers.size());
+
+ Server server1 = getServerById(servers, "server-1");
+ assertEquals("username1", server1.getUsername());
+ assertEquals("password1", server1.getPassword());
+ assertEquals(List.of("server-11", "server-12"), server1.getAliases());
+
+ Server server11 = getServerById(servers, "server-11");
+ assertEquals("username1", server11.getUsername());
+ assertEquals("password1", server11.getPassword());
+ assertTrue(server11.getAliases().isEmpty());
+
+ Server server12 = getServerById(servers, "server-12");
+ assertEquals("username1", server12.getUsername());
+ assertEquals("password1", server12.getPassword());
+ assertTrue(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");
+
+ 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) {
- 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..a8464a49a302
--- /dev/null
+++ b/impl/maven-impl/src/test/resources/settings/settings-servers-2.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+ ${user.home}/.m2/repository
+
+
+ server-1
+
+ server-11
+ server-12
+
+ username1
+ password1
+
+
+ server-2
+
+ server-21
+
+ username2
+ password2
+
+
+ server-3
+ username3
+ password3
+
+
+
+
diff --git a/impl/maven-impl/src/test/resources/settings/settings-servers-3.xml b/impl/maven-impl/src/test/resources/settings/settings-servers-3.xml
new file mode 100644
index 000000000000..e0a13454e2e8
--- /dev/null
+++ b/impl/maven-impl/src/test/resources/settings/settings-servers-3.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+ ${user.home}/.m2/repository
+
+
+ server-1
+
+ server-2
+
+ username1
+ password1
+
+
+ server-2
+ username2
+ password2
+
+
+
+
diff --git a/impl/maven-impl/src/test/resources/settings-simple.xml b/impl/maven-impl/src/test/resources/settings/settings-simple.xml
similarity index 100%
rename from impl/maven-impl/src/test/resources/settings-simple.xml
rename to impl/maven-impl/src/test/resources/settings/settings-simple.xml
diff --git a/impl/maven-support/pom.xml b/impl/maven-support/pom.xml
index 65f1eb0a7c5a..7171363b74fc 100644
--- a/impl/maven-support/pom.xml
+++ b/impl/maven-support/pom.xml
@@ -123,6 +123,9 @@ under the License.
generate-sources
+
+ alias
+
2.0.0
${project.basedir}/../../api/maven-api-settings
${project.basedir}/../../src/mdo
@@ -136,7 +139,7 @@ under the License.
writer-stax.vm
- forcedIOModelVersion=1.2.0
+ forcedIOModelVersion=1.3.0
packageModelV3=org.apache.maven.settings
packageModelV4=org.apache.maven.api.settings
packageToolV4=org.apache.maven.settings.v4
diff --git a/pom.xml b/pom.xml
index 08260706e3ed..b109514105be 100644
--- a/pom.xml
+++ b/pom.xml
@@ -745,6 +745,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