Skip to content

Commit fe5bf55

Browse files
committed
[MNG-5659] Provide project-specific settings located in ${session.rootdir}/.mvn/settings.xml by default
1 parent 8b0bf37 commit fe5bf55

16 files changed

Lines changed: 346 additions & 14 deletions

File tree

api/maven-api-core/src/main/java/org/apache/maven/api/services/SettingsBuilder.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public interface SettingsBuilder extends Service {
4848
@Nonnull
4949
default SettingsBuilderResult build(
5050
@Nonnull Session session, @Nonnull Source globalSettingsSource, @Nonnull Source userSettingsSource) {
51-
return build(SettingsBuilderRequest.build(session, globalSettingsSource, userSettingsSource));
51+
return build(session, globalSettingsSource, null, userSettingsSource);
5252
}
5353

5454
/**
@@ -60,6 +60,37 @@ default SettingsBuilderResult build(
6060
@Nonnull
6161
default SettingsBuilderResult build(
6262
@Nonnull Session session, @Nonnull Path globalSettingsPath, @Nonnull Path userSettingsPath) {
63-
return build(SettingsBuilderRequest.build(session, globalSettingsPath, userSettingsPath));
63+
return build(session, globalSettingsPath, null, userSettingsPath);
64+
}
65+
66+
/**
67+
* Builds the effective settings of the specified settings sources.
68+
*
69+
* @return the result of the settings building, never {@code null}
70+
* @throws SettingsBuilderException if the effective settings could not be built
71+
*/
72+
@Nonnull
73+
default SettingsBuilderResult build(
74+
@Nonnull Session session,
75+
@Nonnull Source globalSettingsSource,
76+
@Nonnull Source projectSettingsSource,
77+
@Nonnull Source userSettingsSource) {
78+
return build(
79+
SettingsBuilderRequest.build(session, globalSettingsSource, projectSettingsSource, userSettingsSource));
80+
}
81+
82+
/**
83+
* Builds the effective settings of the specified settings paths.
84+
*
85+
* @return the result of the settings building, never {@code null}
86+
* @throws SettingsBuilderException if the effective settings could not be built
87+
*/
88+
@Nonnull
89+
default SettingsBuilderResult build(
90+
@Nonnull Session session,
91+
@Nonnull Path globalSettingsPath,
92+
@Nonnull Path projectSettingsPath,
93+
@Nonnull Path userSettingsPath) {
94+
return build(SettingsBuilderRequest.build(session, globalSettingsPath, projectSettingsPath, userSettingsPath));
6495
}
6596
}

api/maven-api-core/src/main/java/org/apache/maven/api/services/SettingsBuilderRequest.java

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,22 @@ public interface SettingsBuilderRequest {
5656
@Nonnull
5757
Optional<Source> getGlobalSettingsSource();
5858

59+
/**
60+
* Gets the project settings source.
61+
*
62+
* @return the project settings source or {@code null} if none
63+
*/
64+
@Nonnull
65+
Optional<Source> getProjectSettingsSource();
66+
67+
/**
68+
* Gets the project settings path.
69+
*
70+
* @return the project settings path or {@code null} if none
71+
*/
72+
@Nonnull
73+
Optional<Path> getProjectSettingsPath();
74+
5975
/**
6076
* Gets the user settings path.
6177
*
@@ -75,19 +91,39 @@ public interface SettingsBuilderRequest {
7591
@Nonnull
7692
static SettingsBuilderRequest build(
7793
@Nonnull Session session, @Nonnull Source globalSettingsSource, @Nonnull Source userSettingsSource) {
94+
return build(session, globalSettingsSource, null, userSettingsSource);
95+
}
96+
97+
@Nonnull
98+
static SettingsBuilderRequest build(
99+
@Nonnull Session session, @Nonnull Path globalSettingsPath, @Nonnull Path userSettingsPath) {
100+
return build(session, globalSettingsPath, null, userSettingsPath);
101+
}
102+
103+
@Nonnull
104+
static SettingsBuilderRequest build(
105+
@Nonnull Session session,
106+
@Nonnull Source globalSettingsSource,
107+
@Nonnull Source projectSettingsSource,
108+
@Nonnull Source userSettingsSource) {
78109
return builder()
79110
.session(nonNull(session, "session cannot be null"))
80111
.globalSettingsSource(nonNull(globalSettingsSource, "globalSettingsSource cannot be null"))
112+
.projectSettingsSource(nonNull(projectSettingsSource, "projectSettingsSource cannot be null"))
81113
.userSettingsSource(nonNull(userSettingsSource, "userSettingsSource cannot be null"))
82114
.build();
83115
}
84116

85117
@Nonnull
86118
static SettingsBuilderRequest build(
87-
@Nonnull Session session, @Nonnull Path globalSettingsPath, @Nonnull Path userSettingsPath) {
119+
@Nonnull Session session,
120+
@Nonnull Path globalSettingsPath,
121+
@Nonnull Path projectSettingsPath,
122+
@Nonnull Path userSettingsPath) {
88123
return builder()
89124
.session(nonNull(session, "session cannot be null"))
90125
.globalSettingsPath(nonNull(globalSettingsPath, "globalSettingsPath cannot be null"))
126+
.projectSettingsPath(nonNull(projectSettingsPath, "projectSettingsPath cannot be null"))
91127
.userSettingsPath(nonNull(userSettingsPath, "userSettingsPath cannot be null"))
92128
.build();
93129
}
@@ -102,6 +138,8 @@ class SettingsBuilderRequestBuilder {
102138
Session session;
103139
Path globalSettingsPath;
104140
Source globalSettingsSource;
141+
Path projectSettingsPath;
142+
Source projectSettingsSource;
105143
Path userSettingsPath;
106144
Source userSettingsSource;
107145

@@ -120,6 +158,16 @@ public SettingsBuilderRequestBuilder globalSettingsSource(Source globalSettingsS
120158
return this;
121159
}
122160

161+
public SettingsBuilderRequestBuilder projectSettingsPath(Path projectSettingsPath) {
162+
this.projectSettingsPath = projectSettingsPath;
163+
return this;
164+
}
165+
166+
public SettingsBuilderRequestBuilder projectSettingsSource(Source projectSettingsSource) {
167+
this.projectSettingsSource = projectSettingsSource;
168+
return this;
169+
}
170+
123171
public SettingsBuilderRequestBuilder userSettingsPath(Path userSettingsPath) {
124172
this.userSettingsPath = userSettingsPath;
125173
return this;
@@ -132,12 +180,20 @@ public SettingsBuilderRequestBuilder userSettingsSource(Source userSettingsSourc
132180

133181
public SettingsBuilderRequest build() {
134182
return new DefaultSettingsBuilderRequest(
135-
session, globalSettingsPath, globalSettingsSource, userSettingsPath, userSettingsSource);
183+
session,
184+
globalSettingsPath,
185+
globalSettingsSource,
186+
projectSettingsPath,
187+
projectSettingsSource,
188+
userSettingsPath,
189+
userSettingsSource);
136190
}
137191

138192
private static class DefaultSettingsBuilderRequest extends BaseRequest implements SettingsBuilderRequest {
139193
private final Path globalSettingsPath;
140194
private final Source globalSettingsSource;
195+
private final Path projectSettingsPath;
196+
private final Source projectSettingsSource;
141197
private final Path userSettingsPath;
142198
private final Source userSettingsSource;
143199

@@ -146,11 +202,15 @@ private static class DefaultSettingsBuilderRequest extends BaseRequest implement
146202
@Nonnull Session session,
147203
@Nullable Path globalSettingsPath,
148204
@Nullable Source globalSettingsSource,
205+
@Nullable Path projectSettingsPath,
206+
@Nullable Source projectSettingsSource,
149207
@Nullable Path userSettingsPath,
150208
@Nullable Source userSettingsSource) {
151209
super(session);
152210
this.globalSettingsPath = globalSettingsPath;
153211
this.globalSettingsSource = globalSettingsSource;
212+
this.projectSettingsPath = projectSettingsPath;
213+
this.projectSettingsSource = projectSettingsSource;
154214
this.userSettingsPath = userSettingsPath;
155215
this.userSettingsSource = userSettingsSource;
156216
}
@@ -167,6 +227,18 @@ public Optional<Source> getGlobalSettingsSource() {
167227
return Optional.ofNullable(globalSettingsSource);
168228
}
169229

230+
@Nonnull
231+
@Override
232+
public Optional<Path> getProjectSettingsPath() {
233+
return Optional.ofNullable(projectSettingsPath);
234+
}
235+
236+
@Nonnull
237+
@Override
238+
public Optional<Source> getProjectSettingsSource() {
239+
return Optional.ofNullable(projectSettingsSource);
240+
}
241+
170242
@Nonnull
171243
@Override
172244
public Optional<Path> getUserSettingsPath() {

api/maven-api-settings/src/main/mdo/settings.mdo

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
<code>
5454
<![CDATA[
5555
public static final String USER_LEVEL = "user-level";
56+
public static final String PROJECT_LEVEL = "project-level";
5657
public static final String GLOBAL_LEVEL = "global-level";
5758
5859
private String sourceLevel = USER_LEVEL;
@@ -64,9 +65,9 @@
6465
{
6566
throw new IllegalStateException( "Cannot reset sourceLevel attribute; it is already set to: " + sourceLevel );
6667
}
67-
else if ( !( USER_LEVEL.equals( sourceLevel ) || GLOBAL_LEVEL.equals( sourceLevel ) ) )
68+
else if ( !( USER_LEVEL.equals( sourceLevel ) || PROJECT_LEVEL.equals( sourceLevel ) || GLOBAL_LEVEL.equals( sourceLevel ) ) )
6869
{
69-
throw new IllegalArgumentException( "sourceLevel must be one of: {" + USER_LEVEL + "," + GLOBAL_LEVEL + "}" );
70+
throw new IllegalArgumentException( "sourceLevel must be one of: {" + USER_LEVEL + "," + PROJECT_LEVEL + "," + GLOBAL_LEVEL + "}" );
7071
}
7172
else
7273
{

maven-compat/src/main/java/org/apache/maven/settings/DefaultMavenSettingsBuilder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ private Settings build(SettingsBuildingRequest request) throws IOException, XmlP
8787
public Settings buildSettings(MavenExecutionRequest request) throws IOException, XmlPullParserException {
8888
SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
8989
settingsRequest.setUserSettingsFile(request.getUserSettingsFile());
90+
settingsRequest.setProjectSettingsFile(request.getProjectSettingsFile());
9091
settingsRequest.setGlobalSettingsFile(request.getGlobalSettingsFile());
9192
settingsRequest.setUserProperties(request.getUserProperties());
9293
settingsRequest.setSystemProperties(request.getSystemProperties());

maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ public class DefaultMavenExecutionRequest implements MavenExecutionRequest {
9090

9191
private File userSettingsFile;
9292

93+
private File projectSettingsFile;
94+
9395
private File globalSettingsFile;
9496

9597
private File userToolchainsFile;
@@ -842,6 +844,18 @@ public MavenExecutionRequest setUserSettingsFile(File userSettingsFile) {
842844
return this;
843845
}
844846

847+
@Override
848+
public File getProjectSettingsFile() {
849+
return projectSettingsFile;
850+
}
851+
852+
@Override
853+
public MavenExecutionRequest setProjectSettingsFile(File projectSettingsFile) {
854+
this.projectSettingsFile = projectSettingsFile;
855+
856+
return this;
857+
}
858+
845859
@Override
846860
public File getGlobalSettingsFile() {
847861
return globalSettingsFile;

maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,10 @@ public interface MavenExecutionRequest {
393393

394394
MavenExecutionRequest setUserSettingsFile(File userSettingsFile);
395395

396+
File getProjectSettingsFile();
397+
398+
MavenExecutionRequest setProjectSettingsFile(File projectSettingsFile);
399+
396400
File getGlobalSettingsFile();
397401

398402
MavenExecutionRequest setGlobalSettingsFile(File globalSettingsFile);

maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ public class CLIManager {
7878

7979
public static final char ALTERNATE_USER_SETTINGS = 's';
8080

81+
public static final String ALTERNATE_PROJECT_SETTINGS = "ps";
82+
8183
public static final String ALTERNATE_GLOBAL_SETTINGS = "gs";
8284

8385
public static final char ALTERNATE_USER_TOOLCHAINS = 't';
@@ -205,6 +207,11 @@ public CLIManager() {
205207
.desc("Alternate path for the user settings file")
206208
.hasArg()
207209
.build());
210+
options.addOption(Option.builder(ALTERNATE_PROJECT_SETTINGS)
211+
.longOpt("project-settings")
212+
.desc("Alternate path for the project settings file")
213+
.hasArg()
214+
.build());
208215
options.addOption(Option.builder(ALTERNATE_GLOBAL_SETTINGS)
209216
.longOpt("global-settings")
210217
.desc("Alternate path for the global settings file")

maven-embedder/src/main/java/org/apache/maven/cli/CliRequest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,12 @@ public MavenExecutionRequest getRequest() {
110110
public void setUserProperties(Properties properties) {
111111
this.userProperties.putAll(properties);
112112
}
113+
114+
public Path getRootDirectory() {
115+
return rootDirectory;
116+
}
117+
118+
public Path getTopDirectory() {
119+
return topDirectory;
120+
}
113121
}

maven-embedder/src/main/java/org/apache/maven/cli/configuration/SettingsXmlConfigurationProcessor.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.io.File;
2626
import java.io.FileNotFoundException;
2727
import java.util.List;
28+
import java.util.Properties;
2829

2930
import org.apache.commons.cli.CommandLine;
3031
import org.apache.maven.artifact.InvalidRepositoryException;
@@ -66,6 +67,8 @@ public class SettingsXmlConfigurationProcessor implements ConfigurationProcessor
6667

6768
public static final File DEFAULT_USER_SETTINGS_FILE = new File(USER_MAVEN_CONFIGURATION_HOME, "settings.xml");
6869

70+
public static final File DEFAULT_PROJECT_SETTINGS_FILE = new File(".mvn", "settings.xml");
71+
6972
public static final File DEFAULT_GLOBAL_SETTINGS_FILE = new File(System.getProperty("maven.conf"), "settings.xml");
7073

7174
private static final Logger LOGGER = LoggerFactory.getLogger(SettingsXmlConfigurationProcessor.class);
@@ -98,6 +101,24 @@ public void process(CliRequest cliRequest) throws Exception {
98101
userSettingsFile = DEFAULT_USER_SETTINGS_FILE;
99102
}
100103

104+
File projectSettingsFile;
105+
106+
if (commandLine.hasOption(CLIManager.ALTERNATE_PROJECT_SETTINGS)) {
107+
projectSettingsFile = new File(commandLine.getOptionValue(CLIManager.ALTERNATE_PROJECT_SETTINGS));
108+
projectSettingsFile = resolveFile(projectSettingsFile, workingDirectory);
109+
110+
if (!projectSettingsFile.isFile()) {
111+
throw new FileNotFoundException(
112+
"The specified project settings file does not exist: " + projectSettingsFile);
113+
}
114+
} else if (cliRequest.getRootDirectory() != null) {
115+
projectSettingsFile = DEFAULT_PROJECT_SETTINGS_FILE;
116+
projectSettingsFile = resolveFile(
117+
projectSettingsFile, cliRequest.getRootDirectory().toString());
118+
} else {
119+
projectSettingsFile = null;
120+
}
121+
101122
File globalSettingsFile;
102123

103124
if (commandLine.hasOption(CLIManager.ALTERNATE_GLOBAL_SETTINGS)) {
@@ -113,13 +134,21 @@ public void process(CliRequest cliRequest) throws Exception {
113134
}
114135

115136
request.setGlobalSettingsFile(globalSettingsFile);
137+
request.setProjectSettingsFile(projectSettingsFile);
116138
request.setUserSettingsFile(userSettingsFile);
117139

118140
SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
119141
settingsRequest.setGlobalSettingsFile(globalSettingsFile);
142+
settingsRequest.setProjectSettingsFile(projectSettingsFile);
120143
settingsRequest.setUserSettingsFile(userSettingsFile);
121144
settingsRequest.setSystemProperties(cliRequest.getSystemProperties());
122-
settingsRequest.setUserProperties(cliRequest.getUserProperties());
145+
Properties props = cliRequest.getUserProperties();
146+
if (cliRequest.getRootDirectory() != null) {
147+
props = new Properties();
148+
props.putAll(cliRequest.getUserProperties());
149+
props.put("session.rootDirectory", cliRequest.getRootDirectory().toString());
150+
}
151+
settingsRequest.setUserProperties(props);
123152

124153
if (request.getEventSpyDispatcher() != null) {
125154
request.getEventSpyDispatcher().onEvent(settingsRequest);
@@ -128,6 +157,9 @@ public void process(CliRequest cliRequest) throws Exception {
128157
LOGGER.debug(
129158
"Reading global settings from '{}'",
130159
getLocation(settingsRequest.getGlobalSettingsSource(), settingsRequest.getGlobalSettingsFile()));
160+
LOGGER.debug(
161+
"Reading project settings from '{}'",
162+
getLocation(settingsRequest.getProjectSettingsSource(), settingsRequest.getProjectSettingsFile()));
131163
LOGGER.debug(
132164
"Reading user settings from '{}'",
133165
getLocation(settingsRequest.getUserSettingsSource(), settingsRequest.getUserSettingsFile()));

maven-settings-builder/pom.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,13 @@ under the License.
7878
<plugin>
7979
<groupId>com.github.siom79.japicmp</groupId>
8080
<artifactId>japicmp-maven-plugin</artifactId>
81-
<configuration />
81+
<configuration>
82+
<parameter>
83+
<excludes>
84+
<exclude>org.apache.maven.settings.validation.SettingsValidator#validate(org.apache.maven.settings.Settings,boolean,org.apache.maven.settings.building.SettingsProblemCollector):METHOD_NEW_DEFAULT</exclude>
85+
</excludes>
86+
</parameter>
87+
</configuration>
8288
</plugin>
8389
</plugins>
8490
</build>

0 commit comments

Comments
 (0)