mirror of https://github.com/apache/maven.git
[MNG-7914] Provide a single entry point for configuration (#1595)
* [MNG-7914] Provide a single entry point for configuration * [MNG-7914] Rename global -> installation * [MNG-7914] Include time zone in Maven build timestamp * [MNG-7914] Use a single place to document all maven properties
This commit is contained in:
parent
6668da3219
commit
6ac914d6f9
|
@ -1,6 +1,7 @@
|
||||||
main is org.apache.maven.cli.MavenCli from plexus.core
|
main is org.apache.maven.cli.MavenCli from plexus.core
|
||||||
|
|
||||||
set maven.conf default ${maven.home}/conf
|
set maven.conf default ${maven.home}/conf
|
||||||
|
set maven.installation.conf default ${maven.conf}
|
||||||
|
|
||||||
[plexus.core]
|
[plexus.core]
|
||||||
load ${maven.conf}/logging
|
load ${maven.conf}/logging
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
#
|
||||||
|
# Maven user properties
|
||||||
|
#
|
||||||
|
|
||||||
|
maven.installation.conf = ${maven.home}/conf
|
||||||
|
maven.user.conf = ${user.home}/.m2
|
||||||
|
maven.project.conf = ${session.rootDirectory}/.mvn
|
||||||
|
|
||||||
|
# Comma-separated list of files to include.
|
||||||
|
# Each item may be enclosed in quotes to gracefully include spaces. Items are trimmed before being loaded.
|
||||||
|
# If the first character of an item is a question mark, the load will silently fail if the file does not exist.
|
||||||
|
${includes} = ?"${maven.user.conf}/maven.properties", \
|
||||||
|
?"${maven.project.conf}/maven.properties"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Settings
|
||||||
|
#
|
||||||
|
# Define the default three levels for settings.
|
||||||
|
# The '-is' flag will override the 'maven.installation.settings' property.
|
||||||
|
# The '-ps' flag will override the 'maven.project.settings' property.
|
||||||
|
# The '-s' flag will override the 'maven.user.settings' property.
|
||||||
|
maven.installation.settings = ${maven.installation.conf}/settings.xml
|
||||||
|
maven.project.settings = ${maven.project.conf}/settings.xml
|
||||||
|
maven.user.settings = ${maven.user.conf}/settings.xml
|
||||||
|
|
||||||
|
#
|
||||||
|
# Toolchains
|
||||||
|
#
|
||||||
|
# Define the default three levels for toolchains.
|
||||||
|
# The '-it' flag will override the 'maven.installation.toolchains' property.
|
||||||
|
# The '-t' flag will override the 'maven.user.toolchains' property.
|
||||||
|
maven.installation.toolchains = ${maven.installation.conf}/toolchains.xml
|
||||||
|
maven.user.toolchains = ${maven.user.conf}/toolchains.xml
|
||||||
|
|
||||||
|
#
|
||||||
|
# Extensions
|
||||||
|
#
|
||||||
|
maven.installation.extensions = ${maven.installation.conf}/extensions.xml
|
||||||
|
maven.project.extensions = ${maven.project.conf}/extensions.xml
|
||||||
|
maven.user.extensions = ${maven.user.conf}/extensions.xml
|
|
@ -29,14 +29,15 @@ under the License.
|
||||||
|
|
|
|
||||||
| -s /path/to/user/settings.xml
|
| -s /path/to/user/settings.xml
|
||||||
|
|
|
|
||||||
| 2. Global Level. This settings.xml file provides configuration for all Maven
|
| 2. Installation Level.
|
||||||
|
| This settings.xml file provides configuration for all Maven
|
||||||
| users on a machine (assuming they're all using the same Maven
|
| users on a machine (assuming they're all using the same Maven
|
||||||
| installation). It's normally provided in
|
| installation). It's normally provided in
|
||||||
| ${maven.conf}/settings.xml.
|
| ${maven.installation.conf}/settings.xml.
|
||||||
|
|
|
|
||||||
| NOTE: This location can be overridden with the CLI option:
|
| NOTE: This location can be overridden with the CLI option:
|
||||||
|
|
|
|
||||||
| -gs /path/to/global/settings.xml
|
| -is /path/to/installation/settings.xml
|
||||||
|
|
|
|
||||||
| The sections in this sample file are intended to give you a running start at
|
| The sections in this sample file are intended to give you a running start at
|
||||||
| getting the most out of your Maven installation. Where appropriate, the default
|
| getting the most out of your Maven installation. Where appropriate, the default
|
||||||
|
|
|
@ -29,14 +29,15 @@ under the License.
|
||||||
|
|
|
|
||||||
| -t /path/to/user/toolchains.xml
|
| -t /path/to/user/toolchains.xml
|
||||||
|
|
|
|
||||||
| 2. Global Level. This toolchains.xml file provides configuration for all Maven
|
| 2. Installation Level.
|
||||||
|
| This toolchains.xml file provides configuration for all Maven
|
||||||
| users on a machine (assuming they're all using the same Maven
|
| users on a machine (assuming they're all using the same Maven
|
||||||
| installation). It's normally provided in
|
| installation). It's normally provided in
|
||||||
| ${maven.conf}/toolchains.xml.
|
| ${maven.installation.conf}/toolchains.xml.
|
||||||
|
|
|
|
||||||
| NOTE: This location can be overridden with the CLI option:
|
| NOTE: This location can be overridden with the CLI option:
|
||||||
|
|
|
|
||||||
| -gt /path/to/global/toolchains.xml
|
| -it /path/to/installation/toolchains.xml
|
||||||
|
|
|
|
||||||
| The sections in this sample file are intended to give you a running start at
|
| The sections in this sample file are intended to give you a running start at
|
||||||
| getting the most out of your Maven installation.
|
| getting the most out of your Maven installation.
|
||||||
|
|
|
@ -29,10 +29,10 @@ import org.junit.jupiter.api.Test;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that the global settings.xml shipped with the distribution is in good state.
|
* Tests that the installation settings.xml shipped with the distribution is in good state.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class GlobalSettingsTest {
|
class InstallationSettingsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testValidGlobalSettings() throws Exception {
|
void testValidGlobalSettings() throws Exception {
|
|
@ -0,0 +1,267 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.maven.api;
|
||||||
|
|
||||||
|
import org.apache.maven.api.annotations.Config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration constants.
|
||||||
|
*/
|
||||||
|
public final class Constants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maven home.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
@Config(readOnly = true)
|
||||||
|
public static final String MAVEN_HOME = "maven.home";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maven installation configuration directory.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "${maven.home}/conf")
|
||||||
|
public static final String MAVEN_INSTALLATION_CONF = "maven.installation.conf";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maven user configuration directory.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "${user.home}/.m2")
|
||||||
|
public static final String MAVEN_USER_CONF = "maven.user.conf";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maven project configuration directory.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "${session.rootDirectory}/.mvn")
|
||||||
|
public static final String MAVEN_PROJECT_CONF = "maven.project.conf";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maven local repository.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "${maven.user.conf}/repository")
|
||||||
|
public static final String MAVEN_REPO_LOCAL = "maven.repo.local";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maven installation settings.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "${maven.installation.conf}/settings.xml")
|
||||||
|
public static final String MAVEN_INSTALLATION_SETTINGS = "maven.installation.settings";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maven user settings.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "${maven.user.conf}/settings.xml")
|
||||||
|
public static final String MAVEN_USER_SETTINGS = "maven.user.settings";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maven project settings.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "${maven.project.conf}/settings.xml")
|
||||||
|
public static final String MAVEN_PROJECT_SETTINGS = "maven.project.settings";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maven installation extensions.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "${maven.installation.conf}/extensions.xml")
|
||||||
|
public static final String MAVEN_INSTALLATION_EXTENSIONS = "maven.installation.extensions";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maven user extensions.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "${maven.user.conf}/extensions.xml")
|
||||||
|
public static final String MAVEN_USER_EXTENSIONS = "maven.user.extensions";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maven project extensions.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "${maven.project.conf}/extensions.xml")
|
||||||
|
public static final String MAVEN_PROJECT_EXTENSIONS = "maven.project.extensions";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maven installation toolchains.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "${maven.installation.conf}/toolchains.xml")
|
||||||
|
public static final String MAVEN_INSTALLATION_TOOLCHAINS = "maven.installation.toolchains";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maven user toolchains.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "${maven.user.home}/toolchains.xml")
|
||||||
|
public static final String MAVEN_USER_TOOLCHAINS = "maven.user.toolchains";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extensions class path.
|
||||||
|
*/
|
||||||
|
@Config
|
||||||
|
public static final String MAVEN_EXT_CLASS_PATH = "maven.ext.class.path";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maven output color mode.
|
||||||
|
* Allowed values are <code>auto</code>, <code>always</code>, <code>never</code>.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "auto")
|
||||||
|
public static final String MAVEN_STYLE_COLOR_PROPERTY = "maven.style.color";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build timestamp format.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
@Config(source = Config.Source.MODEL, defaultValue = "yyyy-MM-dd'T'HH:mm:ssXXX")
|
||||||
|
public static final String MAVEN_BUILD_TIMESTAMP_FORMAT = "maven.build.timestamp.format";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User controlled relocations.
|
||||||
|
* This property is a comma separated list of entries with the syntax <code>GAV>GAV</code>.
|
||||||
|
* The first <code>GAV</code> can contain <code>*</code> for any elem (so <code>*:*:*</code> would mean ALL, something
|
||||||
|
* you don't want). The second <code>GAV</code> is either fully specified, or also can contain <code>*</code>,
|
||||||
|
* then it behaves as "ordinary relocation": the coordinate is preserved from relocated artifact.
|
||||||
|
* Finally, if right hand <code>GAV</code> is absent (line looks like <code>GAV></code>), the left hand matching
|
||||||
|
* <code>GAV</code> is banned fully (from resolving).
|
||||||
|
* <br/>
|
||||||
|
* Note: the <code>></code> means project level, while <code>>></code> means global (whole session level,
|
||||||
|
* so even plugins will get relocated artifacts) relocation.
|
||||||
|
* <br/>
|
||||||
|
* For example,
|
||||||
|
* <pre>maven.relocations.entries = org.foo:*:*>, \\<br/> org.here:*:*>org.there:*:*, \\<br/> javax.inject:javax.inject:1>>jakarta.inject:jakarta.inject:1.0.5</pre>
|
||||||
|
* means: 3 entries, ban <code>org.foo group</code> (exactly, so <code>org.foo.bar</code> is allowed),
|
||||||
|
* relocate <code>org.here</code> to <code>org.there</code> and finally globally relocate (see <code>>></code> above)
|
||||||
|
* <code>javax.inject:javax.inject:1</code> to <code>jakarta.inject:jakarta.inject:1.0.5</code>.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config
|
||||||
|
public static final String MAVEN_RELOCATIONS_ENTRIES = "maven.relocations.entries";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User property for version filters expression, a semicolon separated list of filters to apply. By default, no version
|
||||||
|
* filter is applied (like in Maven 3).
|
||||||
|
* <br/>
|
||||||
|
* Supported filters:
|
||||||
|
* <ul>
|
||||||
|
* <li>"h" or "h(num)" - highest version or top list of highest ones filter</li>
|
||||||
|
* <li>"l" or "l(num)" - lowest version or bottom list of lowest ones filter</li>
|
||||||
|
* <li>"s" - contextual snapshot filter</li>
|
||||||
|
* <li>"e(G:A:V)" - predicate filter (leaves out G:A:V from range, if hit, V can be range)</li>
|
||||||
|
* </ul>
|
||||||
|
* Example filter expression: <code>"h(5);s;e(org.foo:bar:1)</code> will cause: ranges are filtered for "top 5" (instead
|
||||||
|
* full range), snapshots are banned if root project is not a snapshot, and if range for <code>org.foo:bar</code> is
|
||||||
|
* being processed, version 1 is omitted.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config
|
||||||
|
public static final String MAVEN_VERSION_FILTERS = "maven.versionFilters";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User property for chained LRM: list of "tail" local repository paths (separated by comma), to be used with
|
||||||
|
* {@code org.eclipse.aether.util.repository.ChainedLocalRepositoryManager}.
|
||||||
|
* Default value: <code>null</code>, no chained LRM is used.
|
||||||
|
*
|
||||||
|
* @since 3.9.0
|
||||||
|
*/
|
||||||
|
@Config
|
||||||
|
public static final String MAVEN_REPO_LOCAL_TAIL = "maven.repo.local.tail";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User property for reverse dependency tree. If enabled, Maven will record ".tracking" directory into local
|
||||||
|
* repository with "reverse dependency tree", essentially explaining WHY given artifact is present in local
|
||||||
|
* repository.
|
||||||
|
* Default: <code>false</code>, will not record anything.
|
||||||
|
*
|
||||||
|
* @since 3.9.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "false")
|
||||||
|
public static final String MAVEN_REPO_LOCAL_RECORD_REVERSE_TREE = "maven.repo.local.recordReverseTree";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User property for selecting dependency manager behaviour regarding transitive dependencies and dependency
|
||||||
|
* management entries in their POMs. Maven 3 targeted full backward compatibility with Maven2, hence it ignored
|
||||||
|
* dependency management entries in transitive dependency POMs. Maven 4 enables "transitivity" by default, hence
|
||||||
|
* unlike Maven2, obeys dependency management entries deep in dependency graph as well.
|
||||||
|
* <br/>
|
||||||
|
* Default: <code>"true"</code>.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "true")
|
||||||
|
public static final String MAVEN_RESOLVER_DEPENDENCY_MANAGER_TRANSITIVITY =
|
||||||
|
"maven.resolver.dependencyManagerTransitivity";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolver transport to use.
|
||||||
|
* Can be <code>default</code>, <code>wagon</code>, <code>apache</code>, <code>jdk</code> or <code>auto</code>.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "default")
|
||||||
|
public static final String MAVEN_RESOLVER_TRANSPORT = "maven.resolver.transport";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin validation level.
|
||||||
|
*
|
||||||
|
* @since 3.9.2
|
||||||
|
*/
|
||||||
|
@Config(defaultValue = "inline")
|
||||||
|
public static final String MAVEN_PLUGIN_VALIDATION = "maven.plugin.validation";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin validation exclusions.
|
||||||
|
*
|
||||||
|
* @since 3.9.6
|
||||||
|
*/
|
||||||
|
@Config
|
||||||
|
public static final String MAVEN_PLUGIN_VALIDATION_EXCLUDES = "maven.plugin.validation.excludes";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProjectBuilder parallelism.
|
||||||
|
*
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
@Config(type = "java.lang.Integer", defaultValue = "cores/2 + 1")
|
||||||
|
public static final String MAVEN_PROJECT_BUILDER_PARALLELISM = "maven.projectBuilder.parallelism";
|
||||||
|
|
||||||
|
private Constants() {}
|
||||||
|
}
|
|
@ -28,7 +28,7 @@ import org.apache.maven.api.annotations.Nonnull;
|
||||||
import org.apache.maven.api.settings.Settings;
|
import org.apache.maven.api.settings.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the effective settings from a user settings file and/or a global settings file.
|
* Builds the effective settings from a user settings file and/or a installation settings file.
|
||||||
*
|
*
|
||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
|
@ -53,8 +53,8 @@ public interface SettingsBuilder extends Service {
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
default SettingsBuilderResult build(
|
default SettingsBuilderResult build(
|
||||||
@Nonnull Session session, @Nonnull Source globalSettingsSource, @Nonnull Source userSettingsSource) {
|
@Nonnull Session session, @Nonnull Source installationSettingsSource, @Nonnull Source userSettingsSource) {
|
||||||
return build(session, globalSettingsSource, null, userSettingsSource);
|
return build(session, installationSettingsSource, null, userSettingsSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,8 +65,8 @@ public interface SettingsBuilder extends Service {
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
default SettingsBuilderResult build(
|
default SettingsBuilderResult build(
|
||||||
@Nonnull Session session, @Nonnull Path globalSettingsPath, @Nonnull Path userSettingsPath) {
|
@Nonnull Session session, @Nonnull Path installationSettingsPath, @Nonnull Path userSettingsPath) {
|
||||||
return build(session, globalSettingsPath, null, userSettingsPath);
|
return build(session, installationSettingsPath, null, userSettingsPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,11 +78,11 @@ public interface SettingsBuilder extends Service {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
default SettingsBuilderResult build(
|
default SettingsBuilderResult build(
|
||||||
@Nonnull Session session,
|
@Nonnull Session session,
|
||||||
@Nonnull Source globalSettingsSource,
|
@Nonnull Source installationSettingsSource,
|
||||||
@Nonnull Source projectSettingsSource,
|
@Nonnull Source projectSettingsSource,
|
||||||
@Nonnull Source userSettingsSource) {
|
@Nonnull Source userSettingsSource) {
|
||||||
return build(
|
return build(SettingsBuilderRequest.build(
|
||||||
SettingsBuilderRequest.build(session, globalSettingsSource, projectSettingsSource, userSettingsSource));
|
session, installationSettingsSource, projectSettingsSource, userSettingsSource));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,10 +94,11 @@ public interface SettingsBuilder extends Service {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
default SettingsBuilderResult build(
|
default SettingsBuilderResult build(
|
||||||
@Nonnull Session session,
|
@Nonnull Session session,
|
||||||
@Nonnull Path globalSettingsPath,
|
@Nonnull Path installationSettingsPath,
|
||||||
@Nonnull Path projectSettingsPath,
|
@Nonnull Path projectSettingsPath,
|
||||||
@Nonnull Path userSettingsPath) {
|
@Nonnull Path userSettingsPath) {
|
||||||
return build(SettingsBuilderRequest.build(session, globalSettingsPath, projectSettingsPath, userSettingsPath));
|
return build(
|
||||||
|
SettingsBuilderRequest.build(session, installationSettingsPath, projectSettingsPath, userSettingsPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -115,7 +116,7 @@ public interface SettingsBuilder extends Service {
|
||||||
* Validate the specified settings.
|
* Validate the specified settings.
|
||||||
*
|
*
|
||||||
* @param settings The settings to validate, must not be {@code null}.
|
* @param settings The settings to validate, must not be {@code null}.
|
||||||
* @param isProjectSettings Boolean indicating if the validation is for project settings or user / global settings.
|
* @param isProjectSettings Boolean indicating if the validation is for project settings or user / installation settings.
|
||||||
* @return The list of problems that were encountered, must not be {@code null}.
|
* @return The list of problems that were encountered, must not be {@code null}.
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
|
|
@ -42,12 +42,12 @@ public interface SettingsBuilderRequest {
|
||||||
Session getSession();
|
Session getSession();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the global settings source.
|
* Gets the installation settings source.
|
||||||
*
|
*
|
||||||
* @return the global settings source or {@code null} if none
|
* @return the installation settings source or {@code null} if none
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
Optional<Source> getGlobalSettingsSource();
|
Optional<Source> getInstallationSettingsSource();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the project settings source.
|
* Gets the project settings source.
|
||||||
|
@ -67,25 +67,25 @@ public interface SettingsBuilderRequest {
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
static SettingsBuilderRequest build(
|
static SettingsBuilderRequest build(
|
||||||
@Nonnull Session session, @Nonnull Source globalSettingsSource, @Nonnull Source userSettingsSource) {
|
@Nonnull Session session, @Nonnull Source installationSettingsSource, @Nonnull Source userSettingsSource) {
|
||||||
return build(session, globalSettingsSource, null, userSettingsSource);
|
return build(session, installationSettingsSource, null, userSettingsSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
static SettingsBuilderRequest build(
|
static SettingsBuilderRequest build(
|
||||||
@Nonnull Session session, @Nonnull Path globalSettingsPath, @Nonnull Path userSettingsPath) {
|
@Nonnull Session session, @Nonnull Path installationSettingsPath, @Nonnull Path userSettingsPath) {
|
||||||
return build(session, Source.fromPath(globalSettingsPath), null, Source.fromPath(userSettingsPath));
|
return build(session, Source.fromPath(installationSettingsPath), null, Source.fromPath(userSettingsPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
static SettingsBuilderRequest build(
|
static SettingsBuilderRequest build(
|
||||||
@Nonnull Session session,
|
@Nonnull Session session,
|
||||||
@Nullable Source globalSettingsSource,
|
@Nullable Source installationSettingsSource,
|
||||||
@Nullable Source projectSettingsSource,
|
@Nullable Source projectSettingsSource,
|
||||||
@Nullable Source userSettingsSource) {
|
@Nullable Source userSettingsSource) {
|
||||||
return builder()
|
return builder()
|
||||||
.session(nonNull(session, "session cannot be null"))
|
.session(nonNull(session, "session cannot be null"))
|
||||||
.globalSettingsSource(globalSettingsSource)
|
.installationSettingsSource(installationSettingsSource)
|
||||||
.projectSettingsSource(projectSettingsSource)
|
.projectSettingsSource(projectSettingsSource)
|
||||||
.userSettingsSource(userSettingsSource)
|
.userSettingsSource(userSettingsSource)
|
||||||
.build();
|
.build();
|
||||||
|
@ -94,14 +94,14 @@ public interface SettingsBuilderRequest {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
static SettingsBuilderRequest build(
|
static SettingsBuilderRequest build(
|
||||||
@Nonnull Session session,
|
@Nonnull Session session,
|
||||||
@Nullable Path globalSettingsPath,
|
@Nullable Path installationSettingsPath,
|
||||||
@Nullable Path projectSettingsPath,
|
@Nullable Path projectSettingsPath,
|
||||||
@Nullable Path userSettingsPath) {
|
@Nullable Path userSettingsPath) {
|
||||||
return builder()
|
return builder()
|
||||||
.session(nonNull(session, "session cannot be null"))
|
.session(nonNull(session, "session cannot be null"))
|
||||||
.globalSettingsSource(
|
.installationSettingsSource(
|
||||||
globalSettingsPath != null && Files.exists(globalSettingsPath)
|
installationSettingsPath != null && Files.exists(installationSettingsPath)
|
||||||
? Source.fromPath(globalSettingsPath)
|
? Source.fromPath(installationSettingsPath)
|
||||||
: null)
|
: null)
|
||||||
.projectSettingsSource(
|
.projectSettingsSource(
|
||||||
projectSettingsPath != null && Files.exists(projectSettingsPath)
|
projectSettingsPath != null && Files.exists(projectSettingsPath)
|
||||||
|
@ -122,7 +122,7 @@ public interface SettingsBuilderRequest {
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
class SettingsBuilderRequestBuilder {
|
class SettingsBuilderRequestBuilder {
|
||||||
Session session;
|
Session session;
|
||||||
Source globalSettingsSource;
|
Source installationSettingsSource;
|
||||||
Source projectSettingsSource;
|
Source projectSettingsSource;
|
||||||
Source userSettingsSource;
|
Source userSettingsSource;
|
||||||
|
|
||||||
|
@ -131,8 +131,8 @@ public interface SettingsBuilderRequest {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SettingsBuilderRequestBuilder globalSettingsSource(Source globalSettingsSource) {
|
public SettingsBuilderRequestBuilder installationSettingsSource(Source installationSettingsSource) {
|
||||||
this.globalSettingsSource = globalSettingsSource;
|
this.installationSettingsSource = installationSettingsSource;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,30 +148,30 @@ public interface SettingsBuilderRequest {
|
||||||
|
|
||||||
public SettingsBuilderRequest build() {
|
public SettingsBuilderRequest build() {
|
||||||
return new DefaultSettingsBuilderRequest(
|
return new DefaultSettingsBuilderRequest(
|
||||||
session, globalSettingsSource, projectSettingsSource, userSettingsSource);
|
session, installationSettingsSource, projectSettingsSource, userSettingsSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DefaultSettingsBuilderRequest extends BaseRequest implements SettingsBuilderRequest {
|
private static class DefaultSettingsBuilderRequest extends BaseRequest implements SettingsBuilderRequest {
|
||||||
private final Source globalSettingsSource;
|
private final Source installationSettingsSource;
|
||||||
private final Source projectSettingsSource;
|
private final Source projectSettingsSource;
|
||||||
private final Source userSettingsSource;
|
private final Source userSettingsSource;
|
||||||
|
|
||||||
@SuppressWarnings("checkstyle:ParameterNumber")
|
@SuppressWarnings("checkstyle:ParameterNumber")
|
||||||
DefaultSettingsBuilderRequest(
|
DefaultSettingsBuilderRequest(
|
||||||
@Nonnull Session session,
|
@Nonnull Session session,
|
||||||
@Nullable Source globalSettingsSource,
|
@Nullable Source installationSettingsSource,
|
||||||
@Nullable Source projectSettingsSource,
|
@Nullable Source projectSettingsSource,
|
||||||
@Nullable Source userSettingsSource) {
|
@Nullable Source userSettingsSource) {
|
||||||
super(session);
|
super(session);
|
||||||
this.globalSettingsSource = globalSettingsSource;
|
this.installationSettingsSource = installationSettingsSource;
|
||||||
this.projectSettingsSource = projectSettingsSource;
|
this.projectSettingsSource = projectSettingsSource;
|
||||||
this.userSettingsSource = userSettingsSource;
|
this.userSettingsSource = userSettingsSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Optional<Source> getGlobalSettingsSource() {
|
public Optional<Source> getInstallationSettingsSource() {
|
||||||
return Optional.ofNullable(globalSettingsSource);
|
return Optional.ofNullable(installationSettingsSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
|
|
@ -24,7 +24,7 @@ import org.apache.maven.api.annotations.Experimental;
|
||||||
import org.apache.maven.api.annotations.Nonnull;
|
import org.apache.maven.api.annotations.Nonnull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the effective toolchains from a user toolchains file and/or a global toolchains file.
|
* Builds the effective toolchains from a user toolchains file and/or an installation toolchains file.
|
||||||
*
|
*
|
||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
|
@ -44,7 +44,7 @@ public interface ToolchainsBuilder extends Service {
|
||||||
* Builds the effective toolchains for the specified toolchains sources.
|
* Builds the effective toolchains for the specified toolchains sources.
|
||||||
*
|
*
|
||||||
* @param session the {@link Session}, must not be {@code null}
|
* @param session the {@link Session}, must not be {@code null}
|
||||||
* @param globalToolchainsSource The {@link Source} pointing to the global toolchains, must not be {@code null}
|
* @param installationToolchainsFile The {@link Source} pointing to the installation toolchains, must not be {@code null}
|
||||||
* @param userToolchainsSource The {@link Source} pointing to the user toolchains, must not be {@code null}
|
* @param userToolchainsSource The {@link Source} pointing to the user toolchains, must not be {@code null}
|
||||||
* @throws ToolchainsBuilderException if the project cannot be created
|
* @throws ToolchainsBuilderException if the project cannot be created
|
||||||
* @throws IllegalArgumentException if an argument is {@code null} or invalid
|
* @throws IllegalArgumentException if an argument is {@code null} or invalid
|
||||||
|
@ -52,7 +52,9 @@ public interface ToolchainsBuilder extends Service {
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
default ToolchainsBuilderResult build(
|
default ToolchainsBuilderResult build(
|
||||||
@Nonnull Session session, @Nonnull Source globalToolchainsSource, @Nonnull Source userToolchainsSource) {
|
@Nonnull Session session,
|
||||||
return build(ToolchainsBuilderRequest.build(session, globalToolchainsSource, userToolchainsSource));
|
@Nonnull Source installationToolchainsFile,
|
||||||
|
@Nonnull Source userToolchainsSource) {
|
||||||
|
return build(ToolchainsBuilderRequest.build(session, installationToolchainsFile, userToolchainsSource));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,12 @@ public interface ToolchainsBuilderRequest {
|
||||||
Session getSession();
|
Session getSession();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the global Toolchains source.
|
* Gets the installation Toolchains source.
|
||||||
*
|
*
|
||||||
* @return the global Toolchains source or {@code null} if none
|
* @return the installation Toolchains source or {@code null} if none
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
Optional<Source> getGlobalToolchainsSource();
|
Optional<Source> getInstallationToolchainsSource();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the user Toolchains source.
|
* Gets the user Toolchains source.
|
||||||
|
@ -57,22 +57,24 @@ public interface ToolchainsBuilderRequest {
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
static ToolchainsBuilderRequest build(
|
static ToolchainsBuilderRequest build(
|
||||||
@Nonnull Session session, @Nullable Source globalToolchainsSource, @Nullable Source userToolchainsSource) {
|
@Nonnull Session session,
|
||||||
|
@Nullable Source installationToolchainsFile,
|
||||||
|
@Nullable Source userToolchainsSource) {
|
||||||
return builder()
|
return builder()
|
||||||
.session(nonNull(session, "session cannot be null"))
|
.session(nonNull(session, "session cannot be null"))
|
||||||
.globalToolchainsSource(globalToolchainsSource)
|
.installationToolchainsSource(installationToolchainsFile)
|
||||||
.userToolchainsSource(userToolchainsSource)
|
.userToolchainsSource(userToolchainsSource)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
static ToolchainsBuilderRequest build(
|
static ToolchainsBuilderRequest build(
|
||||||
@Nonnull Session session, @Nullable Path globalToolchainsPath, @Nullable Path userToolchainsPath) {
|
@Nonnull Session session, @Nullable Path installationToolchainsFile, @Nullable Path userToolchainsPath) {
|
||||||
return builder()
|
return builder()
|
||||||
.session(nonNull(session, "session cannot be null"))
|
.session(nonNull(session, "session cannot be null"))
|
||||||
.globalToolchainsSource(
|
.installationToolchainsSource(
|
||||||
globalToolchainsPath != null && Files.exists(globalToolchainsPath)
|
installationToolchainsFile != null && Files.exists(installationToolchainsFile)
|
||||||
? Source.fromPath(globalToolchainsPath)
|
? Source.fromPath(installationToolchainsFile)
|
||||||
: null)
|
: null)
|
||||||
.userToolchainsSource(
|
.userToolchainsSource(
|
||||||
userToolchainsPath != null && Files.exists(userToolchainsPath)
|
userToolchainsPath != null && Files.exists(userToolchainsPath)
|
||||||
|
@ -89,7 +91,7 @@ public interface ToolchainsBuilderRequest {
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
class ToolchainsBuilderRequestBuilder {
|
class ToolchainsBuilderRequestBuilder {
|
||||||
Session session;
|
Session session;
|
||||||
Source globalToolchainsSource;
|
Source installationToolchainsSource;
|
||||||
Source userToolchainsSource;
|
Source userToolchainsSource;
|
||||||
|
|
||||||
public ToolchainsBuilderRequestBuilder session(Session session) {
|
public ToolchainsBuilderRequestBuilder session(Session session) {
|
||||||
|
@ -97,8 +99,8 @@ public interface ToolchainsBuilderRequest {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ToolchainsBuilderRequestBuilder globalToolchainsSource(Source globalToolchainsSource) {
|
public ToolchainsBuilderRequestBuilder installationToolchainsSource(Source installationToolchainsSource) {
|
||||||
this.globalToolchainsSource = globalToolchainsSource;
|
this.installationToolchainsSource = installationToolchainsSource;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,27 +111,27 @@ public interface ToolchainsBuilderRequest {
|
||||||
|
|
||||||
public ToolchainsBuilderRequest build() {
|
public ToolchainsBuilderRequest build() {
|
||||||
return new ToolchainsBuilderRequestBuilder.DefaultToolchainsBuilderRequest(
|
return new ToolchainsBuilderRequestBuilder.DefaultToolchainsBuilderRequest(
|
||||||
session, globalToolchainsSource, userToolchainsSource);
|
session, installationToolchainsSource, userToolchainsSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DefaultToolchainsBuilderRequest extends BaseRequest implements ToolchainsBuilderRequest {
|
private static class DefaultToolchainsBuilderRequest extends BaseRequest implements ToolchainsBuilderRequest {
|
||||||
private final Source globalToolchainsSource;
|
private final Source installationToolchainsSource;
|
||||||
private final Source userToolchainsSource;
|
private final Source userToolchainsSource;
|
||||||
|
|
||||||
@SuppressWarnings("checkstyle:ParameterNumber")
|
@SuppressWarnings("checkstyle:ParameterNumber")
|
||||||
DefaultToolchainsBuilderRequest(
|
DefaultToolchainsBuilderRequest(
|
||||||
@Nonnull Session session,
|
@Nonnull Session session,
|
||||||
@Nullable Source globalToolchainsSource,
|
@Nullable Source installationToolchainsSource,
|
||||||
@Nullable Source userToolchainsSource) {
|
@Nullable Source userToolchainsSource) {
|
||||||
super(session);
|
super(session);
|
||||||
this.globalToolchainsSource = globalToolchainsSource;
|
this.installationToolchainsSource = installationToolchainsSource;
|
||||||
this.userToolchainsSource = userToolchainsSource;
|
this.userToolchainsSource = userToolchainsSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Optional<Source> getGlobalToolchainsSource() {
|
public Optional<Source> getInstallationToolchainsSource() {
|
||||||
return Optional.ofNullable(globalToolchainsSource);
|
return Optional.ofNullable(installationToolchainsSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.maven.api.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Experimental
|
||||||
|
@Documented
|
||||||
|
@Retention(RetentionPolicy.CLASS)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface Config {
|
||||||
|
|
||||||
|
Source source() default Source.USER_PROPERTIES;
|
||||||
|
|
||||||
|
String type() default "java.lang.String";
|
||||||
|
|
||||||
|
String defaultValue() default "";
|
||||||
|
|
||||||
|
boolean readOnly() default false;
|
||||||
|
|
||||||
|
enum Source {
|
||||||
|
USER_PROPERTIES,
|
||||||
|
MODEL
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,8 +44,7 @@
|
||||||
<name>TrackableBase</name>
|
<name>TrackableBase</name>
|
||||||
<version>1.0.0+</version>
|
<version>1.0.0+</version>
|
||||||
<description>
|
<description>
|
||||||
common base class that contains code to track the source for
|
Common base class that contains code to track the source for this instance.
|
||||||
this instance (USER|GLOBAL)
|
|
||||||
</description>
|
</description>
|
||||||
<codeSegments>
|
<codeSegments>
|
||||||
<codeSegment>
|
<codeSegment>
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
<name>TrackableBase</name>
|
<name>TrackableBase</name>
|
||||||
<version>1.1.0+</version>
|
<version>1.1.0+</version>
|
||||||
<description>
|
<description>
|
||||||
Common base class that contains code to track the source for this instance (USER|GLOBAL)
|
Common base class that contains code to track the source for this instance.
|
||||||
</description>
|
</description>
|
||||||
<codeSegments>
|
<codeSegments>
|
||||||
<codeSegment>
|
<codeSegment>
|
||||||
|
|
|
@ -66,8 +66,8 @@ public class DefaultSettingsBuilder implements SettingsBuilder {
|
||||||
public SettingsBuilderResult build(SettingsBuilderRequest request) throws SettingsBuilderException {
|
public SettingsBuilderResult build(SettingsBuilderRequest request) throws SettingsBuilderException {
|
||||||
List<BuilderProblem> problems = new ArrayList<>();
|
List<BuilderProblem> problems = new ArrayList<>();
|
||||||
|
|
||||||
Source globalSource = request.getGlobalSettingsSource().orElse(null);
|
Source installationSource = request.getInstallationSettingsSource().orElse(null);
|
||||||
Settings global = readSettings(globalSource, false, request, problems);
|
Settings installation = readSettings(installationSource, false, request, problems);
|
||||||
|
|
||||||
Source projectSource = request.getProjectSettingsSource().orElse(null);
|
Source projectSource = request.getProjectSettingsSource().orElse(null);
|
||||||
Settings project = readSettings(projectSource, true, request, problems);
|
Settings project = readSettings(projectSource, true, request, problems);
|
||||||
|
@ -76,7 +76,7 @@ public class DefaultSettingsBuilder implements SettingsBuilder {
|
||||||
Settings user = readSettings(userSource, false, request, problems);
|
Settings user = readSettings(userSource, false, request, problems);
|
||||||
|
|
||||||
Settings effective =
|
Settings effective =
|
||||||
settingsMerger.merge(user, settingsMerger.merge(project, global, false, null), false, null);
|
settingsMerger.merge(user, settingsMerger.merge(project, installation, false, null), false, null);
|
||||||
|
|
||||||
// If no repository is defined in the user/global settings,
|
// If no repository is defined in the user/global settings,
|
||||||
// it means that we have "old" settings (as those are new in 4.0)
|
// it means that we have "old" settings (as those are new in 4.0)
|
||||||
|
|
|
@ -57,13 +57,13 @@ public class DefaultToolchainsBuilder implements ToolchainsBuilder {
|
||||||
public ToolchainsBuilderResult build(ToolchainsBuilderRequest request) throws ToolchainsBuilderException {
|
public ToolchainsBuilderResult build(ToolchainsBuilderRequest request) throws ToolchainsBuilderException {
|
||||||
List<BuilderProblem> problems = new ArrayList<>();
|
List<BuilderProblem> problems = new ArrayList<>();
|
||||||
|
|
||||||
Source globalSource = request.getGlobalToolchainsSource().orElse(null);
|
Source installationSource = request.getInstallationToolchainsSource().orElse(null);
|
||||||
PersistedToolchains global = readToolchains(globalSource, request, problems);
|
PersistedToolchains installation = readToolchains(installationSource, request, problems);
|
||||||
|
|
||||||
Source userSource = request.getUserToolchainsSource().orElse(null);
|
Source userSource = request.getUserToolchainsSource().orElse(null);
|
||||||
PersistedToolchains user = readToolchains(userSource, request, problems);
|
PersistedToolchains user = readToolchains(userSource, request, problems);
|
||||||
|
|
||||||
PersistedToolchains effective = toolchainsMerger.merge(user, global, false, null);
|
PersistedToolchains effective = toolchainsMerger.merge(user, installation, false, null);
|
||||||
|
|
||||||
if (hasErrors(problems)) {
|
if (hasErrors(problems)) {
|
||||||
throw new ToolchainsBuilderException("Error building toolchains", problems);
|
throw new ToolchainsBuilderException("Error building toolchains", problems);
|
||||||
|
|
|
@ -26,18 +26,18 @@ import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.apache.maven.api.Constants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MavenBuildTimestamp
|
* MavenBuildTimestamp
|
||||||
*/
|
*/
|
||||||
public class MavenBuildTimestamp {
|
public class MavenBuildTimestamp {
|
||||||
// ISO 8601-compliant timestamp for machine readability
|
// ISO 8601-compliant timestamp for machine readability
|
||||||
public static final String DEFAULT_BUILD_TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
|
public static final String DEFAULT_BUILD_TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX";
|
||||||
|
|
||||||
public static final String BUILD_TIMESTAMP_FORMAT_PROPERTY = "maven.build.timestamp.format";
|
|
||||||
|
|
||||||
public static final TimeZone DEFAULT_BUILD_TIME_ZONE = TimeZone.getTimeZone("Etc/UTC");
|
public static final TimeZone DEFAULT_BUILD_TIME_ZONE = TimeZone.getTimeZone("Etc/UTC");
|
||||||
|
|
||||||
private String formattedTimestamp;
|
private final String formattedTimestamp;
|
||||||
|
|
||||||
public MavenBuildTimestamp() {
|
public MavenBuildTimestamp() {
|
||||||
this(Instant.now());
|
this(Instant.now());
|
||||||
|
@ -48,7 +48,7 @@ public class MavenBuildTimestamp {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MavenBuildTimestamp(Instant time, Map<String, String> properties) {
|
public MavenBuildTimestamp(Instant time, Map<String, String> properties) {
|
||||||
this(time, properties != null ? properties.get(BUILD_TIMESTAMP_FORMAT_PROPERTY) : null);
|
this(time, properties != null ? properties.get(Constants.MAVEN_BUILD_TIMESTAMP_FORMAT) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,7 +58,7 @@ public class MavenBuildTimestamp {
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public MavenBuildTimestamp(Instant time, Properties properties) {
|
public MavenBuildTimestamp(Instant time, Properties properties) {
|
||||||
this(time, properties != null ? properties.getProperty(BUILD_TIMESTAMP_FORMAT_PROPERTY) : null);
|
this(time, properties != null ? properties.getProperty(Constants.MAVEN_BUILD_TIMESTAMP_FORMAT) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MavenBuildTimestamp(Instant time, String timestampFormat) {
|
public MavenBuildTimestamp(Instant time, String timestampFormat) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.apache.maven.api.Constants;
|
||||||
import org.apache.maven.api.di.Named;
|
import org.apache.maven.api.di.Named;
|
||||||
import org.apache.maven.api.di.Priority;
|
import org.apache.maven.api.di.Priority;
|
||||||
import org.apache.maven.api.di.Singleton;
|
import org.apache.maven.api.di.Singleton;
|
||||||
|
@ -51,8 +52,6 @@ public final class UserPropertiesArtifactRelocationSource implements MavenArtifa
|
||||||
public static final String NAME = "userProperties";
|
public static final String NAME = "userProperties";
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(UserPropertiesArtifactRelocationSource.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(UserPropertiesArtifactRelocationSource.class);
|
||||||
|
|
||||||
private static final String CONFIG_PROP_RELOCATIONS_ENTRIES = "maven.relocations.entries";
|
|
||||||
|
|
||||||
private static final Artifact SENTINEL = new DefaultArtifact("org.apache.maven.banned:user-relocation:1.0");
|
private static final Artifact SENTINEL = new DefaultArtifact("org.apache.maven.banned:user-relocation:1.0");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -153,7 +152,7 @@ public final class UserPropertiesArtifactRelocationSource implements MavenArtifa
|
||||||
}
|
}
|
||||||
|
|
||||||
private Relocations parseRelocations(RepositorySystemSession session) {
|
private Relocations parseRelocations(RepositorySystemSession session) {
|
||||||
String relocationsEntries = (String) session.getConfigProperties().get(CONFIG_PROP_RELOCATIONS_ENTRIES);
|
String relocationsEntries = (String) session.getConfigProperties().get(Constants.MAVEN_RELOCATIONS_ENTRIES);
|
||||||
if (relocationsEntries == null) {
|
if (relocationsEntries == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,11 +97,11 @@ public class DefaultMavenExecutionRequest implements MavenExecutionRequest {
|
||||||
|
|
||||||
private File projectSettingsFile;
|
private File projectSettingsFile;
|
||||||
|
|
||||||
private File globalSettingsFile;
|
private File installationSettingsFile;
|
||||||
|
|
||||||
private File userToolchainsFile;
|
private File userToolchainsFile;
|
||||||
|
|
||||||
private File globalToolchainsFile;
|
private File installationToolchainsFile;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Request
|
// Request
|
||||||
|
@ -190,9 +190,9 @@ public class DefaultMavenExecutionRequest implements MavenExecutionRequest {
|
||||||
copy.setPluginGroups(original.getPluginGroups());
|
copy.setPluginGroups(original.getPluginGroups());
|
||||||
copy.setProjectPresent(original.isProjectPresent());
|
copy.setProjectPresent(original.isProjectPresent());
|
||||||
copy.setUserSettingsFile(original.getUserSettingsFile());
|
copy.setUserSettingsFile(original.getUserSettingsFile());
|
||||||
copy.setGlobalSettingsFile(original.getGlobalSettingsFile());
|
copy.setInstallationSettingsFile(original.getInstallationSettingsFile());
|
||||||
copy.setUserToolchainsFile(original.getUserToolchainsFile());
|
copy.setUserToolchainsFile(original.getUserToolchainsFile());
|
||||||
copy.setGlobalToolchainsFile(original.getGlobalToolchainsFile());
|
copy.setInstallationToolchainsFile(original.getInstallationToolchainsFile());
|
||||||
copy.setBaseDirectory((original.getBaseDirectory() != null) ? new File(original.getBaseDirectory()) : null);
|
copy.setBaseDirectory((original.getBaseDirectory() != null) ? new File(original.getBaseDirectory()) : null);
|
||||||
copy.setGoals(original.getGoals());
|
copy.setGoals(original.getGoals());
|
||||||
copy.setRecursive(original.isRecursive());
|
copy.setRecursive(original.isRecursive());
|
||||||
|
@ -866,13 +866,25 @@ public class DefaultMavenExecutionRequest implements MavenExecutionRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public File getGlobalSettingsFile() {
|
public File getGlobalSettingsFile() {
|
||||||
return globalSettingsFile;
|
return getInstallationSettingsFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public MavenExecutionRequest setGlobalSettingsFile(File globalSettingsFile) {
|
public MavenExecutionRequest setGlobalSettingsFile(File globalSettingsFile) {
|
||||||
this.globalSettingsFile = globalSettingsFile;
|
return setInstallationSettingsFile(globalSettingsFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getInstallationSettingsFile() {
|
||||||
|
return installationSettingsFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MavenExecutionRequest setInstallationSettingsFile(File installationSettingsFile) {
|
||||||
|
this.installationSettingsFile = installationSettingsFile;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -890,13 +902,26 @@ public class DefaultMavenExecutionRequest implements MavenExecutionRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public File getGlobalToolchainsFile() {
|
public File getGlobalToolchainsFile() {
|
||||||
return globalToolchainsFile;
|
return installationToolchainsFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MavenExecutionRequest setGlobalToolchainsFile(File globalToolchainsFile) {
|
@Deprecated
|
||||||
this.globalToolchainsFile = globalToolchainsFile;
|
public MavenExecutionRequest setGlobalToolchainsFile(File installationToolchainsFile) {
|
||||||
|
this.installationToolchainsFile = installationToolchainsFile;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getInstallationToolchainsFile() {
|
||||||
|
return installationToolchainsFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MavenExecutionRequest setInstallationToolchainsFile(File installationToolchainsFile) {
|
||||||
|
this.installationToolchainsFile = installationToolchainsFile;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.maven.api.Constants;
|
||||||
import org.apache.maven.artifact.InvalidRepositoryException;
|
import org.apache.maven.artifact.InvalidRepositoryException;
|
||||||
import org.apache.maven.artifact.repository.ArtifactRepository;
|
import org.apache.maven.artifact.repository.ArtifactRepository;
|
||||||
import org.apache.maven.bridge.MavenRepositorySystem;
|
import org.apache.maven.bridge.MavenRepositorySystem;
|
||||||
|
@ -125,7 +126,11 @@ public class DefaultMavenExecutionRequestPopulator implements MavenExecutionRequ
|
||||||
}
|
}
|
||||||
|
|
||||||
if (localRepositoryPath == null || localRepositoryPath.isEmpty()) {
|
if (localRepositoryPath == null || localRepositoryPath.isEmpty()) {
|
||||||
localRepositoryPath = new File(System.getProperty("user.home"), ".m2/repository").getAbsolutePath();
|
String path = request.getUserProperties().getProperty(Constants.MAVEN_USER_CONF);
|
||||||
|
if (path == null) {
|
||||||
|
path = request.getSystemProperties().getProperty("user.home") + File.separator + ".m2";
|
||||||
|
}
|
||||||
|
localRepositoryPath = new File(path, "repository").getAbsolutePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -426,10 +426,16 @@ public interface MavenExecutionRequest {
|
||||||
|
|
||||||
MavenExecutionRequest setProjectSettingsFile(File projectSettingsFile);
|
MavenExecutionRequest setProjectSettingsFile(File projectSettingsFile);
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
File getGlobalSettingsFile();
|
File getGlobalSettingsFile();
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
MavenExecutionRequest setGlobalSettingsFile(File globalSettingsFile);
|
MavenExecutionRequest setGlobalSettingsFile(File globalSettingsFile);
|
||||||
|
|
||||||
|
File getInstallationSettingsFile();
|
||||||
|
|
||||||
|
MavenExecutionRequest setInstallationSettingsFile(File installationSettingsFile);
|
||||||
|
|
||||||
MavenExecutionRequest addRemoteRepository(ArtifactRepository repository);
|
MavenExecutionRequest addRemoteRepository(ArtifactRepository repository);
|
||||||
|
|
||||||
MavenExecutionRequest addPluginArtifactRepository(ArtifactRepository repository);
|
MavenExecutionRequest addPluginArtifactRepository(ArtifactRepository repository);
|
||||||
|
@ -467,7 +473,9 @@ public interface MavenExecutionRequest {
|
||||||
*
|
*
|
||||||
* @return the global toolchains file
|
* @return the global toolchains file
|
||||||
* @since 3.3.0
|
* @since 3.3.0
|
||||||
|
* @deprecated use {@link #getInstallationToolchainsFile()}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
File getGlobalToolchainsFile();
|
File getGlobalToolchainsFile();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -475,9 +483,27 @@ public interface MavenExecutionRequest {
|
||||||
* @param globalToolchainsFile the global toolchains file
|
* @param globalToolchainsFile the global toolchains file
|
||||||
* @return this request
|
* @return this request
|
||||||
* @since 3.3.0
|
* @since 3.3.0
|
||||||
|
* @deprecated use {@link #setInstallationToolchainsFile(File)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
MavenExecutionRequest setGlobalToolchainsFile(File globalToolchainsFile);
|
MavenExecutionRequest setGlobalToolchainsFile(File globalToolchainsFile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return the installation toolchains file
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
File getInstallationToolchainsFile();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param installationToolchainsFile the installation toolchains file
|
||||||
|
* @return this request
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
|
MavenExecutionRequest setInstallationToolchainsFile(File installationToolchainsFile);
|
||||||
|
|
||||||
ExecutionListener getExecutionListener();
|
ExecutionListener getExecutionListener();
|
||||||
|
|
||||||
MavenExecutionRequest setExecutionListener(ExecutionListener executionListener);
|
MavenExecutionRequest setExecutionListener(ExecutionListener executionListener);
|
||||||
|
|
|
@ -30,6 +30,7 @@ import java.util.Map;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.maven.api.Constants;
|
||||||
import org.apache.maven.api.di.Inject;
|
import org.apache.maven.api.di.Inject;
|
||||||
import org.apache.maven.api.di.Named;
|
import org.apache.maven.api.di.Named;
|
||||||
import org.apache.maven.api.di.Singleton;
|
import org.apache.maven.api.di.Singleton;
|
||||||
|
@ -68,7 +69,6 @@ import org.eclipse.aether.util.graph.version.LowestVersionFilter;
|
||||||
import org.eclipse.aether.util.graph.version.PredicateVersionFilter;
|
import org.eclipse.aether.util.graph.version.PredicateVersionFilter;
|
||||||
import org.eclipse.aether.util.listener.ChainedRepositoryListener;
|
import org.eclipse.aether.util.listener.ChainedRepositoryListener;
|
||||||
import org.eclipse.aether.util.repository.AuthenticationBuilder;
|
import org.eclipse.aether.util.repository.AuthenticationBuilder;
|
||||||
import org.eclipse.aether.util.repository.ChainedLocalRepositoryManager;
|
|
||||||
import org.eclipse.aether.util.repository.DefaultAuthenticationSelector;
|
import org.eclipse.aether.util.repository.DefaultAuthenticationSelector;
|
||||||
import org.eclipse.aether.util.repository.DefaultMirrorSelector;
|
import org.eclipse.aether.util.repository.DefaultMirrorSelector;
|
||||||
import org.eclipse.aether.util.repository.DefaultProxySelector;
|
import org.eclipse.aether.util.repository.DefaultProxySelector;
|
||||||
|
@ -89,66 +89,14 @@ import static java.util.Objects.requireNonNull;
|
||||||
@Named
|
@Named
|
||||||
@Singleton
|
@Singleton
|
||||||
public class DefaultRepositorySystemSessionFactory implements RepositorySystemSessionFactory {
|
public class DefaultRepositorySystemSessionFactory implements RepositorySystemSessionFactory {
|
||||||
/**
|
|
||||||
* User property for version filters expression, a semicolon separated list of filters to apply. By default, no version
|
|
||||||
* filter is applied (like in Maven 3).
|
|
||||||
* <p>
|
|
||||||
* Supported filters:
|
|
||||||
* <ul>
|
|
||||||
* <li>"h" or "h(num)" - highest version or top list of highest ones filter</li>
|
|
||||||
* <li>"l" or "l(num)" - lowest version or bottom list of lowest ones filter</li>
|
|
||||||
* <li>"s" - contextual snapshot filter</li>
|
|
||||||
* <li>"e(G:A:V)" - predicate filter (leaves out G:A:V from range, if hit, V can be range)</li>
|
|
||||||
* </ul>
|
|
||||||
* Example filter expression: {@code "h(5);s;e(org.foo:bar:1)} will cause: ranges are filtered for "top 5" (instead
|
|
||||||
* full range), snapshots are banned if root project is not a snapshot, and if range for {@code org.foo:bar} is
|
|
||||||
* being processed, version 1 is omitted.
|
|
||||||
*
|
|
||||||
* @since 4.0.0
|
|
||||||
*/
|
|
||||||
private static final String MAVEN_VERSION_FILTERS = "maven.versionFilters";
|
|
||||||
|
|
||||||
/**
|
public static final String MAVEN_RESOLVER_TRANSPORT_DEFAULT = "default";
|
||||||
* User property for chained LRM: list of "tail" local repository paths (separated by comma), to be used with
|
|
||||||
* {@link ChainedLocalRepositoryManager}.
|
|
||||||
* Default value: {@code null}, no chained LRM is used.
|
|
||||||
*
|
|
||||||
* @since 3.9.0
|
|
||||||
*/
|
|
||||||
private static final String MAVEN_REPO_LOCAL_TAIL = "maven.repo.local.tail";
|
|
||||||
|
|
||||||
/**
|
public static final String MAVEN_RESOLVER_TRANSPORT_WAGON = "wagon";
|
||||||
* User property for reverse dependency tree. If enabled, Maven will record ".tracking" directory into local
|
|
||||||
* repository with "reverse dependency tree", essentially explaining WHY given artifact is present in local
|
|
||||||
* repository.
|
|
||||||
* Default: {@code false}, will not record anything.
|
|
||||||
*
|
|
||||||
* @since 3.9.0
|
|
||||||
*/
|
|
||||||
private static final String MAVEN_REPO_LOCAL_RECORD_REVERSE_TREE = "maven.repo.local.recordReverseTree";
|
|
||||||
|
|
||||||
/**
|
public static final String MAVEN_RESOLVER_TRANSPORT_APACHE = "apache";
|
||||||
* User property for selecting dependency manager behaviour regarding transitive dependencies and dependency
|
|
||||||
* management entries in their POMs. Maven 3 targeted full backward compatibility with Maven2, hence it ignored
|
|
||||||
* dependency management entries in transitive dependency POMs. Maven 4 enables "transitivity" by default, hence
|
|
||||||
* unlike Maven2, obeys dependency management entries deep in dependency graph as well.
|
|
||||||
* <p>
|
|
||||||
* Default: {@code "true"}.
|
|
||||||
*
|
|
||||||
* @since 4.0.0
|
|
||||||
*/
|
|
||||||
private static final String MAVEN_RESOLVER_DEPENDENCY_MANAGER_TRANSITIVITY_KEY =
|
|
||||||
"maven.resolver.dependencyManagerTransitivity";
|
|
||||||
|
|
||||||
private static final String MAVEN_RESOLVER_TRANSPORT_KEY = "maven.resolver.transport";
|
public static final String MAVEN_RESOLVER_TRANSPORT_JDK = "jdk";
|
||||||
|
|
||||||
private static final String MAVEN_RESOLVER_TRANSPORT_DEFAULT = "default";
|
|
||||||
|
|
||||||
private static final String MAVEN_RESOLVER_TRANSPORT_WAGON = "wagon";
|
|
||||||
|
|
||||||
private static final String MAVEN_RESOLVER_TRANSPORT_APACHE = "apache";
|
|
||||||
|
|
||||||
private static final String MAVEN_RESOLVER_TRANSPORT_JDK = "jdk";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This name for Apache HttpClient transport is deprecated.
|
* This name for Apache HttpClient transport is deprecated.
|
||||||
|
@ -158,7 +106,7 @@ public class DefaultRepositorySystemSessionFactory implements RepositorySystemSe
|
||||||
@Deprecated
|
@Deprecated
|
||||||
private static final String MAVEN_RESOLVER_TRANSPORT_NATIVE = "native";
|
private static final String MAVEN_RESOLVER_TRANSPORT_NATIVE = "native";
|
||||||
|
|
||||||
private static final String MAVEN_RESOLVER_TRANSPORT_AUTO = "auto";
|
public static final String MAVEN_RESOLVER_TRANSPORT_AUTO = "auto";
|
||||||
|
|
||||||
private static final String WAGON_TRANSPORTER_PRIORITY_KEY = "aether.priority.WagonTransporterFactory";
|
private static final String WAGON_TRANSPORTER_PRIORITY_KEY = "aether.priority.WagonTransporterFactory";
|
||||||
|
|
||||||
|
@ -257,7 +205,7 @@ public class DefaultRepositorySystemSessionFactory implements RepositorySystemSe
|
||||||
sessionBuilder.setArtifactDescriptorPolicy(new SimpleArtifactDescriptorPolicy(
|
sessionBuilder.setArtifactDescriptorPolicy(new SimpleArtifactDescriptorPolicy(
|
||||||
request.isIgnoreMissingArtifactDescriptor(), request.isIgnoreInvalidArtifactDescriptor()));
|
request.isIgnoreMissingArtifactDescriptor(), request.isIgnoreInvalidArtifactDescriptor()));
|
||||||
|
|
||||||
VersionFilter versionFilter = buildVersionFilter(mergedProps.get(MAVEN_VERSION_FILTERS));
|
VersionFilter versionFilter = buildVersionFilter(mergedProps.get(Constants.MAVEN_VERSION_FILTERS));
|
||||||
if (versionFilter != null) {
|
if (versionFilter != null) {
|
||||||
sessionBuilder.setVersionFilter(versionFilter);
|
sessionBuilder.setVersionFilter(versionFilter);
|
||||||
}
|
}
|
||||||
|
@ -390,7 +338,8 @@ public class DefaultRepositorySystemSessionFactory implements RepositorySystemSe
|
||||||
}
|
}
|
||||||
sessionBuilder.setAuthenticationSelector(authSelector);
|
sessionBuilder.setAuthenticationSelector(authSelector);
|
||||||
|
|
||||||
Object transport = mergedProps.getOrDefault(MAVEN_RESOLVER_TRANSPORT_KEY, MAVEN_RESOLVER_TRANSPORT_DEFAULT);
|
Object transport =
|
||||||
|
mergedProps.getOrDefault(Constants.MAVEN_RESOLVER_TRANSPORT, MAVEN_RESOLVER_TRANSPORT_DEFAULT);
|
||||||
if (MAVEN_RESOLVER_TRANSPORT_DEFAULT.equals(transport)) {
|
if (MAVEN_RESOLVER_TRANSPORT_DEFAULT.equals(transport)) {
|
||||||
// The "default" mode (user did not set anything) from now on defaults to AUTO
|
// The "default" mode (user did not set anything) from now on defaults to AUTO
|
||||||
} else if (MAVEN_RESOLVER_TRANSPORT_JDK.equals(transport)) {
|
} else if (MAVEN_RESOLVER_TRANSPORT_JDK.equals(transport)) {
|
||||||
|
@ -425,21 +374,21 @@ public class DefaultRepositorySystemSessionFactory implements RepositorySystemSe
|
||||||
RepositoryListener repositoryListener = eventSpyDispatcher.chainListener(new LoggingRepositoryListener(logger));
|
RepositoryListener repositoryListener = eventSpyDispatcher.chainListener(new LoggingRepositoryListener(logger));
|
||||||
|
|
||||||
boolean recordReverseTree = Boolean.parseBoolean(
|
boolean recordReverseTree = Boolean.parseBoolean(
|
||||||
mergedProps.getOrDefault(MAVEN_REPO_LOCAL_RECORD_REVERSE_TREE, Boolean.FALSE.toString()));
|
mergedProps.getOrDefault(Constants.MAVEN_REPO_LOCAL_RECORD_REVERSE_TREE, Boolean.FALSE.toString()));
|
||||||
if (recordReverseTree) {
|
if (recordReverseTree) {
|
||||||
repositoryListener = new ChainedRepositoryListener(repositoryListener, new ReverseTreeRepositoryListener());
|
repositoryListener = new ChainedRepositoryListener(repositoryListener, new ReverseTreeRepositoryListener());
|
||||||
}
|
}
|
||||||
sessionBuilder.setRepositoryListener(repositoryListener);
|
sessionBuilder.setRepositoryListener(repositoryListener);
|
||||||
|
|
||||||
// may be overridden
|
// may be overridden
|
||||||
String resolverDependencyManagerTransitivity =
|
String resolverDependencyManagerTransitivity = mergedProps.getOrDefault(
|
||||||
mergedProps.getOrDefault(MAVEN_RESOLVER_DEPENDENCY_MANAGER_TRANSITIVITY_KEY, Boolean.TRUE.toString());
|
Constants.MAVEN_RESOLVER_DEPENDENCY_MANAGER_TRANSITIVITY, Boolean.TRUE.toString());
|
||||||
sessionBuilder.setDependencyManager(
|
sessionBuilder.setDependencyManager(
|
||||||
supplier.getDependencyManager(Boolean.parseBoolean(resolverDependencyManagerTransitivity)));
|
supplier.getDependencyManager(Boolean.parseBoolean(resolverDependencyManagerTransitivity)));
|
||||||
|
|
||||||
ArrayList<Path> paths = new ArrayList<>();
|
ArrayList<Path> paths = new ArrayList<>();
|
||||||
paths.add(Paths.get(request.getLocalRepository().getBasedir()));
|
paths.add(Paths.get(request.getLocalRepository().getBasedir()));
|
||||||
String localRepoTail = mergedProps.get(MAVEN_REPO_LOCAL_TAIL);
|
String localRepoTail = mergedProps.get(Constants.MAVEN_REPO_LOCAL_TAIL);
|
||||||
if (localRepoTail != null) {
|
if (localRepoTail != null) {
|
||||||
Arrays.stream(localRepoTail.split(","))
|
Arrays.stream(localRepoTail.split(","))
|
||||||
.filter(p -> p != null && !p.trim().isEmpty())
|
.filter(p -> p != null && !p.trim().isEmpty())
|
||||||
|
|
|
@ -38,6 +38,7 @@ import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.maven.api.Constants;
|
||||||
import org.apache.maven.eventspy.AbstractEventSpy;
|
import org.apache.maven.eventspy.AbstractEventSpy;
|
||||||
import org.apache.maven.execution.ExecutionEvent;
|
import org.apache.maven.execution.ExecutionEvent;
|
||||||
import org.apache.maven.execution.MavenSession;
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
@ -66,11 +67,7 @@ public final class DefaultPluginValidationManager extends AbstractEventSpy imple
|
||||||
|
|
||||||
private static final String PLUGIN_EXCLUDES_KEY = DefaultPluginValidationManager.class.getName() + ".excludes";
|
private static final String PLUGIN_EXCLUDES_KEY = DefaultPluginValidationManager.class.getName() + ".excludes";
|
||||||
|
|
||||||
private static final String MAVEN_PLUGIN_VALIDATION_KEY = "maven.plugin.validation";
|
public static final ValidationReportLevel DEFAULT_VALIDATION_LEVEL = ValidationReportLevel.INLINE;
|
||||||
|
|
||||||
private static final String MAVEN_PLUGIN_VALIDATION_EXCLUDES_KEY = "maven.plugin.validation.excludes";
|
|
||||||
|
|
||||||
private static final ValidationReportLevel DEFAULT_VALIDATION_LEVEL = ValidationReportLevel.INLINE;
|
|
||||||
|
|
||||||
private static final Collection<ValidationReportLevel> INLINE_VALIDATION_LEVEL = Collections.unmodifiableCollection(
|
private static final Collection<ValidationReportLevel> INLINE_VALIDATION_LEVEL = Collections.unmodifiableCollection(
|
||||||
Arrays.asList(ValidationReportLevel.INLINE, ValidationReportLevel.BRIEF));
|
Arrays.asList(ValidationReportLevel.INLINE, ValidationReportLevel.BRIEF));
|
||||||
|
@ -106,7 +103,7 @@ public final class DefaultPluginValidationManager extends AbstractEventSpy imple
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> parsePluginExcludes(RepositorySystemSession session) {
|
private List<String> parsePluginExcludes(RepositorySystemSession session) {
|
||||||
String excludes = ConfigUtils.getString(session, null, MAVEN_PLUGIN_VALIDATION_EXCLUDES_KEY);
|
String excludes = ConfigUtils.getString(session, null, Constants.MAVEN_PLUGIN_VALIDATION_EXCLUDES);
|
||||||
if (excludes == null || excludes.isEmpty()) {
|
if (excludes == null || excludes.isEmpty()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
@ -122,7 +119,7 @@ public final class DefaultPluginValidationManager extends AbstractEventSpy imple
|
||||||
}
|
}
|
||||||
|
|
||||||
private ValidationReportLevel parseValidationReportLevel(RepositorySystemSession session) {
|
private ValidationReportLevel parseValidationReportLevel(RepositorySystemSession session) {
|
||||||
String level = ConfigUtils.getString(session, null, MAVEN_PLUGIN_VALIDATION_KEY);
|
String level = ConfigUtils.getString(session, null, Constants.MAVEN_PLUGIN_VALIDATION);
|
||||||
if (level == null || level.isEmpty()) {
|
if (level == null || level.isEmpty()) {
|
||||||
return DEFAULT_VALIDATION_LEVEL;
|
return DEFAULT_VALIDATION_LEVEL;
|
||||||
}
|
}
|
||||||
|
@ -131,7 +128,7 @@ public final class DefaultPluginValidationManager extends AbstractEventSpy imple
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
"Invalid value specified for property {}: '{}'. Supported values are (case insensitive): {}",
|
"Invalid value specified for property {}: '{}'. Supported values are (case insensitive): {}",
|
||||||
MAVEN_PLUGIN_VALIDATION_KEY,
|
Constants.MAVEN_PLUGIN_VALIDATION,
|
||||||
level,
|
level,
|
||||||
Arrays.toString(ValidationReportLevel.values()));
|
Arrays.toString(ValidationReportLevel.values()));
|
||||||
return DEFAULT_VALIDATION_LEVEL;
|
return DEFAULT_VALIDATION_LEVEL;
|
||||||
|
|
|
@ -57,6 +57,7 @@ import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.apache.maven.ProjectCycleException;
|
import org.apache.maven.ProjectCycleException;
|
||||||
import org.apache.maven.RepositoryUtils;
|
import org.apache.maven.RepositoryUtils;
|
||||||
|
import org.apache.maven.api.Constants;
|
||||||
import org.apache.maven.api.Session;
|
import org.apache.maven.api.Session;
|
||||||
import org.apache.maven.api.SessionData;
|
import org.apache.maven.api.SessionData;
|
||||||
import org.apache.maven.api.feature.Features;
|
import org.apache.maven.api.feature.Features;
|
||||||
|
@ -118,7 +119,7 @@ import org.slf4j.LoggerFactory;
|
||||||
@Named
|
@Named
|
||||||
@Singleton
|
@Singleton
|
||||||
public class DefaultProjectBuilder implements ProjectBuilder {
|
public class DefaultProjectBuilder implements ProjectBuilder {
|
||||||
public static final String BUILDER_PARALLELISM = "maven.projectBuilder.parallelism";
|
|
||||||
public static final int DEFAULT_BUILDER_PARALLELISM = Runtime.getRuntime().availableProcessors() / 2 + 1;
|
public static final int DEFAULT_BUILDER_PARALLELISM = Runtime.getRuntime().availableProcessors() / 2 + 1;
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
@ -382,10 +383,7 @@ public class DefaultProjectBuilder implements ProjectBuilder {
|
||||||
private int getParallelism(ProjectBuildingRequest request) {
|
private int getParallelism(ProjectBuildingRequest request) {
|
||||||
int parallelism = DEFAULT_BUILDER_PARALLELISM;
|
int parallelism = DEFAULT_BUILDER_PARALLELISM;
|
||||||
try {
|
try {
|
||||||
String str = request.getUserProperties().getProperty(BUILDER_PARALLELISM);
|
String str = request.getUserProperties().getProperty(Constants.MAVEN_PROJECT_BUILDER_PARALLELISM);
|
||||||
if (str == null) {
|
|
||||||
str = request.getSystemProperties().getProperty(BUILDER_PARALLELISM);
|
|
||||||
}
|
|
||||||
if (str != null) {
|
if (str != null) {
|
||||||
parallelism = Integer.parseInt(str);
|
parallelism = Integer.parseInt(str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.apache.maven</groupId>
|
||||||
|
<artifactId>maven</artifactId>
|
||||||
|
<version>4.0.0-beta-4-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>maven-docgen</artifactId>
|
||||||
|
|
||||||
|
<name>Maven Documentation Generator</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.deploy.skip>true</maven.deploy.skip>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- all needed maven module: list them here as this module must run LAST -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.maven</groupId>
|
||||||
|
<artifactId>maven-api-impl</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.maven</groupId>
|
||||||
|
<artifactId>maven-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.maven</groupId>
|
||||||
|
<artifactId>maven-embedder</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.ow2.asm</groupId>
|
||||||
|
<artifactId>asm</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.forge.roaster</groupId>
|
||||||
|
<artifactId>roaster-api</artifactId>
|
||||||
|
<version>2.29.0.Final</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.forge.roaster</groupId>
|
||||||
|
<artifactId>roaster-jdt</artifactId>
|
||||||
|
<version>2.29.0.Final</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.velocity</groupId>
|
||||||
|
<artifactId>velocity-engine-core</artifactId>
|
||||||
|
<version>2.3</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.codehaus.plexus</groupId>
|
||||||
|
<artifactId>plexus-utils</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Not needed during compile -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-simple</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.14.0</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>3.3.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>render-configuration-page</id>
|
||||||
|
<goals>
|
||||||
|
<goal>java</goal>
|
||||||
|
</goals>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>org.apache.maven.tools.CollectConfiguration</mainClass>
|
||||||
|
<arguments>
|
||||||
|
<argument>${basedir}/..</argument>
|
||||||
|
<argument>${basedir}/../src/site/markdown/configuration.md</argument>
|
||||||
|
</arguments>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,363 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.maven.tools;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.io.UncheckedIOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.spi.ToolProvider;
|
||||||
|
|
||||||
|
import org.apache.maven.api.annotations.Config;
|
||||||
|
import org.apache.velocity.VelocityContext;
|
||||||
|
import org.apache.velocity.app.VelocityEngine;
|
||||||
|
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
|
||||||
|
import org.codehaus.plexus.util.io.CachingWriter;
|
||||||
|
import org.jboss.forge.roaster.Roaster;
|
||||||
|
import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.AST;
|
||||||
|
import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.ASTNode;
|
||||||
|
import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.Javadoc;
|
||||||
|
import org.jboss.forge.roaster.model.JavaDocCapable;
|
||||||
|
import org.jboss.forge.roaster.model.JavaDocTag;
|
||||||
|
import org.jboss.forge.roaster.model.JavaType;
|
||||||
|
import org.jboss.forge.roaster.model.impl.JavaDocImpl;
|
||||||
|
import org.jboss.forge.roaster.model.source.FieldSource;
|
||||||
|
import org.jboss.forge.roaster.model.source.JavaClassSource;
|
||||||
|
import org.jboss.forge.roaster.model.source.JavaDocSource;
|
||||||
|
import org.objectweb.asm.AnnotationVisitor;
|
||||||
|
import org.objectweb.asm.ClassReader;
|
||||||
|
import org.objectweb.asm.ClassVisitor;
|
||||||
|
import org.objectweb.asm.FieldVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
|
public class CollectConfiguration {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
try {
|
||||||
|
Path start = Paths.get(args.length > 0 ? args[0] : ".");
|
||||||
|
Path output = Paths.get(args.length > 1 ? args[1] : "output");
|
||||||
|
|
||||||
|
TreeMap<String, ConfigurationKey> discoveredKeys = new TreeMap<>();
|
||||||
|
|
||||||
|
Files.walk(start)
|
||||||
|
.map(Path::toAbsolutePath)
|
||||||
|
.filter(p -> p.getFileName().toString().endsWith(".class"))
|
||||||
|
.filter(p -> p.toString().contains("/target/classes/"))
|
||||||
|
.forEach(p -> {
|
||||||
|
processClass(p, discoveredKeys);
|
||||||
|
});
|
||||||
|
|
||||||
|
VelocityEngine velocityEngine = new VelocityEngine();
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty("resource.loaders", "classpath");
|
||||||
|
properties.setProperty("resource.loader.classpath.class", ClasspathResourceLoader.class.getName());
|
||||||
|
velocityEngine.init(properties);
|
||||||
|
|
||||||
|
VelocityContext context = new VelocityContext();
|
||||||
|
context.put("keys", discoveredKeys.values());
|
||||||
|
|
||||||
|
try (Writer fileWriter = new CachingWriter(output, StandardCharsets.UTF_8)) {
|
||||||
|
velocityEngine.getTemplate("page.vm").merge(context, fileWriter);
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processClass(Path path, Map<String, ConfigurationKey> discoveredKeys) {
|
||||||
|
try {
|
||||||
|
ClassReader classReader = new ClassReader(Files.newInputStream(path));
|
||||||
|
classReader.accept(
|
||||||
|
new ClassVisitor(Opcodes.ASM9) {
|
||||||
|
@Override
|
||||||
|
public FieldVisitor visitField(
|
||||||
|
int fieldAccess,
|
||||||
|
String fieldName,
|
||||||
|
String fieldDescriptor,
|
||||||
|
String fieldSignature,
|
||||||
|
Object fieldValue) {
|
||||||
|
return new FieldVisitor(Opcodes.ASM9) {
|
||||||
|
@Override
|
||||||
|
public AnnotationVisitor visitAnnotation(
|
||||||
|
String annotationDescriptor, boolean annotationVisible) {
|
||||||
|
if (annotationDescriptor.equals("Lorg/apache/maven/api/annotations/Config;")) {
|
||||||
|
return new AnnotationVisitor(Opcodes.ASM9) {
|
||||||
|
Map<String, Object> values = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(String name, Object value) {
|
||||||
|
values.put(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitEnum(String name, String descriptor, String value) {
|
||||||
|
values.put(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitEnd() {
|
||||||
|
JavaType<?> jtype = parse(Paths.get(path.toString()
|
||||||
|
.replace("/target/classes/", "/src/main/java/")
|
||||||
|
.replace(".class", ".java")));
|
||||||
|
FieldSource<JavaClassSource> f =
|
||||||
|
((JavaClassSource) jtype).getField(fieldName);
|
||||||
|
|
||||||
|
String fqName = null;
|
||||||
|
String desc = cloneJavadoc(f.getJavaDoc())
|
||||||
|
.removeAllTags()
|
||||||
|
.getFullText()
|
||||||
|
.replace("*", "\\*");
|
||||||
|
String since = getSince(f);
|
||||||
|
String source =
|
||||||
|
switch ((values.get("source") != null
|
||||||
|
? (String) values.get("source")
|
||||||
|
: Config.Source.USER_PROPERTIES.toString())
|
||||||
|
.toLowerCase()) {
|
||||||
|
case "model" -> "Model properties";
|
||||||
|
case "user_properties" -> "User properties";
|
||||||
|
default -> throw new IllegalStateException();
|
||||||
|
};
|
||||||
|
String type =
|
||||||
|
switch ((values.get("type") != null
|
||||||
|
? (String) values.get("type")
|
||||||
|
: "java.lang.String")) {
|
||||||
|
case "java.lang.String" -> "String";
|
||||||
|
case "java.lang.Integer" -> "Integer";
|
||||||
|
default -> throw new IllegalStateException();
|
||||||
|
};
|
||||||
|
discoveredKeys.put(
|
||||||
|
fieldValue.toString(),
|
||||||
|
new ConfigurationKey(
|
||||||
|
fieldValue.toString(),
|
||||||
|
values.get("defaultValue") != null
|
||||||
|
? values.get("defaultValue")
|
||||||
|
.toString()
|
||||||
|
: null,
|
||||||
|
fqName,
|
||||||
|
desc,
|
||||||
|
since,
|
||||||
|
source,
|
||||||
|
type));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
0);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static JavaDocSource<Object> cloneJavadoc(JavaDocSource<?> javaDoc) {
|
||||||
|
Javadoc jd = (Javadoc) javaDoc.getInternal();
|
||||||
|
return new JavaDocImpl(javaDoc.getOrigin(), (Javadoc)
|
||||||
|
ASTNode.copySubtree(AST.newAST(jd.getAST().apiLevel()), jd));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String unquote(String s) {
|
||||||
|
return (s.startsWith("\"") && s.endsWith("\"")) ? s.substring(1, s.length() - 1) : s;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JavaType<?> parse(Path path) {
|
||||||
|
try {
|
||||||
|
return Roaster.parse(path.toFile());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new UncheckedIOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean toBoolean(String value) {
|
||||||
|
return ("yes".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Would be record, but... Velocity have no idea what it is nor how to handle it.
|
||||||
|
*/
|
||||||
|
public static class ConfigurationKey {
|
||||||
|
private final String key;
|
||||||
|
private final String defaultValue;
|
||||||
|
private final String fqName;
|
||||||
|
private final String description;
|
||||||
|
private final String since;
|
||||||
|
private final String configurationSource;
|
||||||
|
private final String configurationType;
|
||||||
|
|
||||||
|
@SuppressWarnings("checkstyle:parameternumber")
|
||||||
|
public ConfigurationKey(
|
||||||
|
String key,
|
||||||
|
String defaultValue,
|
||||||
|
String fqName,
|
||||||
|
String description,
|
||||||
|
String since,
|
||||||
|
String configurationSource,
|
||||||
|
String configurationType) {
|
||||||
|
this.key = key;
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
this.fqName = fqName;
|
||||||
|
this.description = description;
|
||||||
|
this.since = since;
|
||||||
|
this.configurationSource = configurationSource;
|
||||||
|
this.configurationType = configurationType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDefaultValue() {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFqName() {
|
||||||
|
return fqName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSince() {
|
||||||
|
return since;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConfigurationSource() {
|
||||||
|
return configurationSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConfigurationType() {
|
||||||
|
return configurationType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String nvl(String string, String def) {
|
||||||
|
return string == null ? def : string;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasConfigurationSource(JavaDocCapable<?> javaDocCapable) {
|
||||||
|
return getTag(javaDocCapable, "@configurationSource") != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getConfigurationType(JavaDocCapable<?> javaDocCapable) {
|
||||||
|
String type = getTag(javaDocCapable, "@configurationType");
|
||||||
|
if (type != null) {
|
||||||
|
String linkPrefix = "{@link ";
|
||||||
|
String linkSuffix = "}";
|
||||||
|
if (type.startsWith(linkPrefix) && type.endsWith(linkSuffix)) {
|
||||||
|
type = type.substring(linkPrefix.length(), type.length() - linkSuffix.length());
|
||||||
|
}
|
||||||
|
String javaLangPackage = "java.lang.";
|
||||||
|
if (type.startsWith(javaLangPackage)) {
|
||||||
|
type = type.substring(javaLangPackage.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nvl(type, "n/a");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getConfigurationSource(JavaDocCapable<?> javaDocCapable) {
|
||||||
|
String source = getTag(javaDocCapable, "@configurationSource");
|
||||||
|
if ("{@link RepositorySystemSession#getConfigProperties()}".equals(source)) {
|
||||||
|
return "Session Configuration";
|
||||||
|
} else if ("{@link System#getProperty(String,String)}".equals(source)) {
|
||||||
|
return "Java System Properties";
|
||||||
|
} else if ("{@link org.apache.maven.api.model.Model#getProperties()}".equals(source)) {
|
||||||
|
return "Model Properties";
|
||||||
|
} else if ("{@link Session#getUserProperties()}".equals(source)) {
|
||||||
|
return "Session Properties";
|
||||||
|
} else {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getSince(JavaDocCapable<?> javaDocCapable) {
|
||||||
|
List<JavaDocTag> tags;
|
||||||
|
if (javaDocCapable != null) {
|
||||||
|
if (javaDocCapable instanceof FieldSource<?> fieldSource) {
|
||||||
|
tags = fieldSource.getJavaDoc().getTags("@since");
|
||||||
|
if (tags.isEmpty()) {
|
||||||
|
return getSince(fieldSource.getOrigin());
|
||||||
|
} else {
|
||||||
|
return tags.get(0).getValue();
|
||||||
|
}
|
||||||
|
} else if (javaDocCapable instanceof JavaClassSource classSource) {
|
||||||
|
tags = classSource.getJavaDoc().getTags("@since");
|
||||||
|
if (!tags.isEmpty()) {
|
||||||
|
return tags.get(0).getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getTag(JavaDocCapable<?> javaDocCapable, String tagName) {
|
||||||
|
List<JavaDocTag> tags;
|
||||||
|
if (javaDocCapable != null) {
|
||||||
|
if (javaDocCapable instanceof FieldSource<?> fieldSource) {
|
||||||
|
tags = fieldSource.getJavaDoc().getTags(tagName);
|
||||||
|
if (tags.isEmpty()) {
|
||||||
|
return getTag(fieldSource.getOrigin(), tagName);
|
||||||
|
} else {
|
||||||
|
return tags.get(0).getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Pattern CONSTANT_PATTERN = Pattern.compile(".*static final.* ([A-Z_]+) = (.*);");
|
||||||
|
|
||||||
|
private static final ToolProvider JAVAP = ToolProvider.findFirst("javap").orElseThrow();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds "constant table" for one single class.
|
||||||
|
*
|
||||||
|
* Limitations:
|
||||||
|
* - works only for single class (no inherited constants)
|
||||||
|
* - does not work for fields that are Enum.name()
|
||||||
|
* - more to come
|
||||||
|
*/
|
||||||
|
private static Map<String, String> extractConstants(Path file) {
|
||||||
|
StringWriter out = new StringWriter();
|
||||||
|
JAVAP.run(new PrintWriter(out), new PrintWriter(System.err), "-constants", file.toString());
|
||||||
|
Map<String, String> result = new HashMap<>();
|
||||||
|
out.getBuffer().toString().lines().forEach(l -> {
|
||||||
|
Matcher matcher = CONSTANT_PATTERN.matcher(l);
|
||||||
|
if (matcher.matches()) {
|
||||||
|
result.put(matcher.group(1), matcher.group(2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
##
|
||||||
|
## Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
## or more contributor license agreements. See the NOTICE file
|
||||||
|
## distributed with this work for additional information
|
||||||
|
## regarding copyright ownership. The ASF licenses this file
|
||||||
|
## to you under the Apache License, Version 2.0 (the
|
||||||
|
## "License"); you may not use this file except in compliance
|
||||||
|
## with the License. You may obtain a copy of the License at
|
||||||
|
##
|
||||||
|
## http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
##
|
||||||
|
## Unless required by applicable law or agreed to in writing,
|
||||||
|
## software distributed under the License is distributed on an
|
||||||
|
## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
## KIND, either express or implied. See the License for the
|
||||||
|
## specific language governing permissions and limitations
|
||||||
|
## under the License.
|
||||||
|
##
|
||||||
|
#[[
|
||||||
|
# Configuration Options
|
||||||
|
<!--
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
]]#
|
||||||
|
|
||||||
|
#macro(yesno $val)
|
||||||
|
#if ($val) Yes #else No #end
|
||||||
|
#end
|
||||||
|
|
||||||
|
#macro(value $val)
|
||||||
|
#if ($val) `$val` #else - #end
|
||||||
|
#end
|
||||||
|
|
||||||
|
| No | Key | Type | Description | Default Value | Since | Source |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
#foreach($key in $keys)
|
||||||
|
| $foreach.count. | `$key.key` | `$key.configurationType` | $key.description | #value( $key.defaultValue ) | $key.since | $key.configurationSource |
|
||||||
|
#end
|
||||||
|
|
|
@ -167,6 +167,12 @@ under the License.
|
||||||
<artifactId>mockito-core</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.jimfs</groupId>
|
||||||
|
<artifactId>jimfs</artifactId>
|
||||||
|
<version>1.3.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -79,12 +79,18 @@ public class CLIManager {
|
||||||
|
|
||||||
public static final String ALTERNATE_PROJECT_SETTINGS = "ps";
|
public static final String ALTERNATE_PROJECT_SETTINGS = "ps";
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static final String ALTERNATE_GLOBAL_SETTINGS = "gs";
|
public static final String ALTERNATE_GLOBAL_SETTINGS = "gs";
|
||||||
|
|
||||||
|
public static final String ALTERNATE_INSTALLATION_SETTINGS = "is";
|
||||||
|
|
||||||
public static final char ALTERNATE_USER_TOOLCHAINS = 't';
|
public static final char ALTERNATE_USER_TOOLCHAINS = 't';
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static final String ALTERNATE_GLOBAL_TOOLCHAINS = "gt";
|
public static final String ALTERNATE_GLOBAL_TOOLCHAINS = "gt";
|
||||||
|
|
||||||
|
public static final String ALTERNATE_INSTALLATION_TOOLCHAINS = "it";
|
||||||
|
|
||||||
public static final String FAIL_FAST = "ff";
|
public static final String FAIL_FAST = "ff";
|
||||||
|
|
||||||
public static final String FAIL_ON_SEVERITY = "fos";
|
public static final String FAIL_ON_SEVERITY = "fos";
|
||||||
|
@ -222,6 +228,12 @@ public class CLIManager {
|
||||||
.desc("Alternate path for the global settings file")
|
.desc("Alternate path for the global settings file")
|
||||||
.hasArg()
|
.hasArg()
|
||||||
.build());
|
.build());
|
||||||
|
options.addOption(Option.builder(ALTERNATE_INSTALLATION_SETTINGS)
|
||||||
|
.longOpt("install-settings")
|
||||||
|
.desc("Alternate path for the installation settings file")
|
||||||
|
.hasArg()
|
||||||
|
.deprecated()
|
||||||
|
.build());
|
||||||
options.addOption(Option.builder(Character.toString(ALTERNATE_USER_TOOLCHAINS))
|
options.addOption(Option.builder(Character.toString(ALTERNATE_USER_TOOLCHAINS))
|
||||||
.longOpt("toolchains")
|
.longOpt("toolchains")
|
||||||
.desc("Alternate path for the user toolchains file")
|
.desc("Alternate path for the user toolchains file")
|
||||||
|
@ -232,6 +244,12 @@ public class CLIManager {
|
||||||
.desc("Alternate path for the global toolchains file")
|
.desc("Alternate path for the global toolchains file")
|
||||||
.hasArg()
|
.hasArg()
|
||||||
.build());
|
.build());
|
||||||
|
options.addOption(Option.builder(ALTERNATE_INSTALLATION_TOOLCHAINS)
|
||||||
|
.longOpt("install-toolchains")
|
||||||
|
.desc("Alternate path for the installation toolchains file")
|
||||||
|
.hasArg()
|
||||||
|
.deprecated()
|
||||||
|
.build());
|
||||||
options.addOption(Option.builder(FAIL_ON_SEVERITY)
|
options.addOption(Option.builder(FAIL_ON_SEVERITY)
|
||||||
.longOpt("fail-on-severity")
|
.longOpt("fail-on-severity")
|
||||||
.desc("Configure which severity of logging should cause the build to fail")
|
.desc("Configure which severity of logging should cause the build to fail")
|
||||||
|
|
|
@ -28,9 +28,10 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.file.FileSystem;
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -43,6 +44,7 @@ import java.util.Properties;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -55,6 +57,7 @@ import org.apache.commons.cli.UnrecognizedOptionException;
|
||||||
import org.apache.maven.BuildAbort;
|
import org.apache.maven.BuildAbort;
|
||||||
import org.apache.maven.InternalErrorException;
|
import org.apache.maven.InternalErrorException;
|
||||||
import org.apache.maven.Maven;
|
import org.apache.maven.Maven;
|
||||||
|
import org.apache.maven.api.Constants;
|
||||||
import org.apache.maven.api.services.MessageBuilder;
|
import org.apache.maven.api.services.MessageBuilder;
|
||||||
import org.apache.maven.api.services.MessageBuilderFactory;
|
import org.apache.maven.api.services.MessageBuilderFactory;
|
||||||
import org.apache.maven.building.FileSource;
|
import org.apache.maven.building.FileSource;
|
||||||
|
@ -71,6 +74,7 @@ import org.apache.maven.cli.logging.Slf4jConfiguration;
|
||||||
import org.apache.maven.cli.logging.Slf4jConfigurationFactory;
|
import org.apache.maven.cli.logging.Slf4jConfigurationFactory;
|
||||||
import org.apache.maven.cli.logging.Slf4jLoggerManager;
|
import org.apache.maven.cli.logging.Slf4jLoggerManager;
|
||||||
import org.apache.maven.cli.logging.Slf4jStdoutLogger;
|
import org.apache.maven.cli.logging.Slf4jStdoutLogger;
|
||||||
|
import org.apache.maven.cli.props.MavenPropertiesLoader;
|
||||||
import org.apache.maven.cli.transfer.ConsoleMavenTransferListener;
|
import org.apache.maven.cli.transfer.ConsoleMavenTransferListener;
|
||||||
import org.apache.maven.cli.transfer.QuietMavenTransferListener;
|
import org.apache.maven.cli.transfer.QuietMavenTransferListener;
|
||||||
import org.apache.maven.cli.transfer.SimplexTransferListener;
|
import org.apache.maven.cli.transfer.SimplexTransferListener;
|
||||||
|
@ -131,6 +135,8 @@ import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
|
||||||
import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;
|
import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;
|
||||||
|
|
||||||
import static java.util.Comparator.comparing;
|
import static java.util.Comparator.comparing;
|
||||||
|
import static org.apache.maven.api.Constants.MAVEN_HOME;
|
||||||
|
import static org.apache.maven.api.Constants.MAVEN_INSTALLATION_CONF;
|
||||||
import static org.apache.maven.cli.CLIManager.BATCH_MODE;
|
import static org.apache.maven.cli.CLIManager.BATCH_MODE;
|
||||||
import static org.apache.maven.cli.CLIManager.COLOR;
|
import static org.apache.maven.cli.CLIManager.COLOR;
|
||||||
import static org.apache.maven.cli.CLIManager.FORCE_INTERACTIVE;
|
import static org.apache.maven.cli.CLIManager.FORCE_INTERACTIVE;
|
||||||
|
@ -142,29 +148,11 @@ import static org.apache.maven.cli.ResolveFile.resolveFile;
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class MavenCli {
|
public class MavenCli {
|
||||||
public static final String LOCAL_REPO_PROPERTY = "maven.repo.local";
|
|
||||||
|
|
||||||
public static final String MULTIMODULE_PROJECT_DIRECTORY = "maven.multiModuleProjectDirectory";
|
public static final String MULTIMODULE_PROJECT_DIRECTORY = "maven.multiModuleProjectDirectory";
|
||||||
|
|
||||||
public static final String USER_HOME = System.getProperty("user.home");
|
|
||||||
|
|
||||||
public static final File USER_MAVEN_CONFIGURATION_HOME = new File(USER_HOME, ".m2");
|
|
||||||
|
|
||||||
public static final File DEFAULT_USER_TOOLCHAINS_FILE = new File(USER_MAVEN_CONFIGURATION_HOME, "toolchains.xml");
|
|
||||||
|
|
||||||
public static final File DEFAULT_GLOBAL_TOOLCHAINS_FILE =
|
|
||||||
new File(System.getProperty("maven.conf"), "toolchains.xml");
|
|
||||||
|
|
||||||
private static final String EXT_CLASS_PATH = "maven.ext.class.path";
|
|
||||||
|
|
||||||
private static final String EXTENSIONS_FILENAME = "extensions.xml";
|
|
||||||
|
|
||||||
private static final String MVN_EXTENSIONS_FILENAME = ".mvn/" + EXTENSIONS_FILENAME;
|
|
||||||
|
|
||||||
private static final String MVN_MAVEN_CONFIG = ".mvn/maven.config";
|
private static final String MVN_MAVEN_CONFIG = ".mvn/maven.config";
|
||||||
|
|
||||||
public static final String STYLE_COLOR_PROPERTY = "style.color";
|
|
||||||
|
|
||||||
private ClassWorld classWorld;
|
private ClassWorld classWorld;
|
||||||
|
|
||||||
private LoggerManager plexusLoggerManager;
|
private LoggerManager plexusLoggerManager;
|
||||||
|
@ -191,6 +179,8 @@ public class MavenCli {
|
||||||
|
|
||||||
private MessageBuilderFactory messageBuilderFactory;
|
private MessageBuilderFactory messageBuilderFactory;
|
||||||
|
|
||||||
|
private FileSystem fileSystem = FileSystems.getDefault();
|
||||||
|
|
||||||
private static final Pattern NEXT_LINE = Pattern.compile("\r?\n");
|
private static final Pattern NEXT_LINE = Pattern.compile("\r?\n");
|
||||||
|
|
||||||
public MavenCli() {
|
public MavenCli() {
|
||||||
|
@ -340,7 +330,7 @@ public class MavenCli {
|
||||||
// We need to locate the top level project which may be pointed at using
|
// We need to locate the top level project which may be pointed at using
|
||||||
// the -f/--file option. However, the command line isn't parsed yet, so
|
// the -f/--file option. However, the command line isn't parsed yet, so
|
||||||
// we need to iterate through the args to find it and act upon it.
|
// we need to iterate through the args to find it and act upon it.
|
||||||
Path topDirectory = Paths.get(cliRequest.workingDirectory);
|
Path topDirectory = fileSystem.getPath(cliRequest.workingDirectory);
|
||||||
boolean isAltFile = false;
|
boolean isAltFile = false;
|
||||||
for (String arg : cliRequest.args) {
|
for (String arg : cliRequest.args) {
|
||||||
if (isAltFile) {
|
if (isAltFile) {
|
||||||
|
@ -380,10 +370,12 @@ public class MavenCli {
|
||||||
// Make sure the Maven home directory is an absolute path to save us from confusion with say drive-relative
|
// Make sure the Maven home directory is an absolute path to save us from confusion with say drive-relative
|
||||||
// Windows paths.
|
// Windows paths.
|
||||||
//
|
//
|
||||||
String mavenHome = System.getProperty("maven.home");
|
String mavenHome = System.getProperty(Constants.MAVEN_HOME);
|
||||||
|
|
||||||
if (mavenHome != null) {
|
if (mavenHome != null) {
|
||||||
System.setProperty("maven.home", new File(mavenHome).getAbsolutePath());
|
System.setProperty(
|
||||||
|
Constants.MAVEN_HOME,
|
||||||
|
getCanonicalPath(fileSystem.getPath(mavenHome)).toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,7 +502,8 @@ public class MavenCli {
|
||||||
cliRequest.showErrors = cliRequest.verbose || commandLine.hasOption(CLIManager.ERRORS);
|
cliRequest.showErrors = cliRequest.verbose || commandLine.hasOption(CLIManager.ERRORS);
|
||||||
|
|
||||||
// LOG COLOR
|
// LOG COLOR
|
||||||
String styleColor = cliRequest.getUserProperties().getProperty(STYLE_COLOR_PROPERTY, "auto");
|
String styleColor = cliRequest.getUserProperties().getProperty("style.color", "auto");
|
||||||
|
styleColor = cliRequest.getUserProperties().getProperty(Constants.MAVEN_STYLE_COLOR_PROPERTY, styleColor);
|
||||||
styleColor = commandLine.getOptionValue(COLOR, styleColor);
|
styleColor = commandLine.getOptionValue(COLOR, styleColor);
|
||||||
if ("always".equals(styleColor) || "yes".equals(styleColor) || "force".equals(styleColor)) {
|
if ("always".equals(styleColor) || "yes".equals(styleColor) || "force".equals(styleColor)) {
|
||||||
MessageUtils.setColorEnabled(true);
|
MessageUtils.setColorEnabled(true);
|
||||||
|
@ -763,16 +756,17 @@ public class MavenCli {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
File extensionsFile = new File(cliRequest.multiModuleProjectDirectory, MVN_EXTENSIONS_FILENAME);
|
|
||||||
File userHomeExtensionsFile = new File(USER_MAVEN_CONFIGURATION_HOME, EXTENSIONS_FILENAME);
|
|
||||||
|
|
||||||
List<CoreExtension> extensions = new ArrayList<>();
|
List<CoreExtension> extensions = new ArrayList<>();
|
||||||
if (extensionsFile.isFile()) {
|
|
||||||
extensions.addAll(readCoreExtensionsDescriptor(extensionsFile));
|
String installationExtensionsFile =
|
||||||
}
|
cliRequest.getUserProperties().getProperty(Constants.MAVEN_INSTALLATION_EXTENSIONS);
|
||||||
if (userHomeExtensionsFile.isFile()) {
|
extensions.addAll(readCoreExtensionsDescriptor(installationExtensionsFile));
|
||||||
extensions.addAll(readCoreExtensionsDescriptor(userHomeExtensionsFile));
|
|
||||||
}
|
String projectExtensionsFile = cliRequest.getUserProperties().getProperty(Constants.MAVEN_PROJECT_EXTENSIONS);
|
||||||
|
extensions.addAll(readCoreExtensionsDescriptor(projectExtensionsFile));
|
||||||
|
|
||||||
|
String userExtensionsFile = cliRequest.getUserProperties().getProperty(Constants.MAVEN_USER_EXTENSIONS);
|
||||||
|
extensions.addAll(readCoreExtensionsDescriptor(userExtensionsFile));
|
||||||
|
|
||||||
if (extensions.isEmpty()) {
|
if (extensions.isEmpty()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
@ -824,14 +818,18 @@ public class MavenCli {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<CoreExtension> readCoreExtensionsDescriptor(File extensionsFile)
|
private List<CoreExtension> readCoreExtensionsDescriptor(String extensionsFile)
|
||||||
throws IOException, XMLStreamException {
|
throws IOException, XMLStreamException {
|
||||||
CoreExtensionsStaxReader parser = new CoreExtensionsStaxReader();
|
if (extensionsFile != null) {
|
||||||
|
Path extensionsPath = Path.of(extensionsFile);
|
||||||
try (InputStream is = Files.newInputStream(extensionsFile.toPath())) {
|
if (Files.exists(extensionsPath)) {
|
||||||
return parser.read(is, true).getExtensions();
|
try (InputStream is = Files.newInputStream(extensionsPath)) {
|
||||||
|
return new CoreExtensionsStaxReader().read(is, true).getExtensions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
private ClassRealm setupContainerRealm(
|
private ClassRealm setupContainerRealm(
|
||||||
ClassWorld classWorld, ClassRealm coreRealm, List<File> extClassPath, List<CoreExtensionEntry> extensions)
|
ClassWorld classWorld, ClassRealm coreRealm, List<File> extClassPath, List<CoreExtensionEntry> extensions)
|
||||||
|
@ -874,9 +872,16 @@ public class MavenCli {
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<File> parseExtClasspath(CliRequest cliRequest) {
|
private List<File> parseExtClasspath(CliRequest cliRequest) {
|
||||||
String extClassPath = cliRequest.userProperties.getProperty(EXT_CLASS_PATH);
|
String extClassPath = cliRequest.userProperties.getProperty(Constants.MAVEN_EXT_CLASS_PATH);
|
||||||
if (extClassPath == null) {
|
if (extClassPath == null) {
|
||||||
extClassPath = cliRequest.systemProperties.getProperty(EXT_CLASS_PATH);
|
extClassPath = cliRequest.systemProperties.getProperty(Constants.MAVEN_EXT_CLASS_PATH);
|
||||||
|
if (extClassPath != null) {
|
||||||
|
slf4jLogger.warn(
|
||||||
|
"The property '{}' has been set using a JVM system property which is deprecated. "
|
||||||
|
+ "The property can be passed as a Maven argument or in the Maven project configuration file,"
|
||||||
|
+ "usually located at ${session.rootDirectory}/.mvn/maven.properties.",
|
||||||
|
Constants.MAVEN_EXT_CLASS_PATH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<File> jars = new ArrayList<>();
|
List<File> jars = new ArrayList<>();
|
||||||
|
@ -1193,7 +1198,7 @@ public class MavenCli {
|
||||||
}
|
}
|
||||||
|
|
||||||
void toolchains(CliRequest cliRequest) throws Exception {
|
void toolchains(CliRequest cliRequest) throws Exception {
|
||||||
File userToolchainsFile;
|
File userToolchainsFile = null;
|
||||||
|
|
||||||
if (cliRequest.commandLine.hasOption(CLIManager.ALTERNATE_USER_TOOLCHAINS)) {
|
if (cliRequest.commandLine.hasOption(CLIManager.ALTERNATE_USER_TOOLCHAINS)) {
|
||||||
userToolchainsFile = new File(cliRequest.commandLine.getOptionValue(CLIManager.ALTERNATE_USER_TOOLCHAINS));
|
userToolchainsFile = new File(cliRequest.commandLine.getOptionValue(CLIManager.ALTERNATE_USER_TOOLCHAINS));
|
||||||
|
@ -1204,40 +1209,57 @@ public class MavenCli {
|
||||||
"The specified user toolchains file does not exist: " + userToolchainsFile);
|
"The specified user toolchains file does not exist: " + userToolchainsFile);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
userToolchainsFile = DEFAULT_USER_TOOLCHAINS_FILE;
|
String userToolchainsFileStr = cliRequest.getUserProperties().getProperty(Constants.MAVEN_USER_TOOLCHAINS);
|
||||||
|
if (userToolchainsFileStr != null) {
|
||||||
|
userToolchainsFile = new File(userToolchainsFileStr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File globalToolchainsFile;
|
File installationToolchainsFile = null;
|
||||||
|
|
||||||
if (cliRequest.commandLine.hasOption(CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS)) {
|
if (cliRequest.commandLine.hasOption(CLIManager.ALTERNATE_INSTALLATION_TOOLCHAINS)) {
|
||||||
globalToolchainsFile =
|
installationToolchainsFile =
|
||||||
new File(cliRequest.commandLine.getOptionValue(CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS));
|
new File(cliRequest.commandLine.getOptionValue(CLIManager.ALTERNATE_INSTALLATION_TOOLCHAINS));
|
||||||
globalToolchainsFile = resolveFile(globalToolchainsFile, cliRequest.workingDirectory);
|
installationToolchainsFile = resolveFile(installationToolchainsFile, cliRequest.workingDirectory);
|
||||||
|
|
||||||
if (!globalToolchainsFile.isFile()) {
|
if (!installationToolchainsFile.isFile()) {
|
||||||
throw new FileNotFoundException(
|
throw new FileNotFoundException(
|
||||||
"The specified global toolchains file does not exist: " + globalToolchainsFile);
|
"The specified installation toolchains file does not exist: " + installationToolchainsFile);
|
||||||
|
}
|
||||||
|
} else if (cliRequest.commandLine.hasOption(CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS)) {
|
||||||
|
installationToolchainsFile =
|
||||||
|
new File(cliRequest.commandLine.getOptionValue(CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS));
|
||||||
|
installationToolchainsFile = resolveFile(installationToolchainsFile, cliRequest.workingDirectory);
|
||||||
|
|
||||||
|
if (!installationToolchainsFile.isFile()) {
|
||||||
|
throw new FileNotFoundException(
|
||||||
|
"The specified installation toolchains file does not exist: " + installationToolchainsFile);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
globalToolchainsFile = DEFAULT_GLOBAL_TOOLCHAINS_FILE;
|
String installationToolchainsFileStr =
|
||||||
|
cliRequest.getUserProperties().getProperty(Constants.MAVEN_INSTALLATION_TOOLCHAINS);
|
||||||
|
if (installationToolchainsFileStr != null) {
|
||||||
|
installationToolchainsFile = new File(installationToolchainsFileStr);
|
||||||
|
installationToolchainsFile = resolveFile(installationToolchainsFile, cliRequest.workingDirectory);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cliRequest.request.setGlobalToolchainsFile(globalToolchainsFile);
|
cliRequest.request.setInstallationToolchainsFile(installationToolchainsFile);
|
||||||
cliRequest.request.setUserToolchainsFile(userToolchainsFile);
|
cliRequest.request.setUserToolchainsFile(userToolchainsFile);
|
||||||
|
|
||||||
DefaultToolchainsBuildingRequest toolchainsRequest = new DefaultToolchainsBuildingRequest();
|
DefaultToolchainsBuildingRequest toolchainsRequest = new DefaultToolchainsBuildingRequest();
|
||||||
if (globalToolchainsFile.isFile()) {
|
if (installationToolchainsFile != null && installationToolchainsFile.isFile()) {
|
||||||
toolchainsRequest.setGlobalToolchainsSource(new FileSource(globalToolchainsFile));
|
toolchainsRequest.setGlobalToolchainsSource(new FileSource(installationToolchainsFile));
|
||||||
}
|
}
|
||||||
if (userToolchainsFile.isFile()) {
|
if (userToolchainsFile != null && userToolchainsFile.isFile()) {
|
||||||
toolchainsRequest.setUserToolchainsSource(new FileSource(userToolchainsFile));
|
toolchainsRequest.setUserToolchainsSource(new FileSource(userToolchainsFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
eventSpyDispatcher.onEvent(toolchainsRequest);
|
eventSpyDispatcher.onEvent(toolchainsRequest);
|
||||||
|
|
||||||
slf4jLogger.debug(
|
slf4jLogger.debug(
|
||||||
"Reading global toolchains from '{}'",
|
"Reading installation toolchains from '{}'",
|
||||||
getLocation(toolchainsRequest.getGlobalToolchainsSource(), globalToolchainsFile));
|
getLocation(toolchainsRequest.getGlobalToolchainsSource(), installationToolchainsFile));
|
||||||
slf4jLogger.debug(
|
slf4jLogger.debug(
|
||||||
"Reading user toolchains from '{}'",
|
"Reading user toolchains from '{}'",
|
||||||
getLocation(toolchainsRequest.getUserToolchainsSource(), userToolchainsFile));
|
getLocation(toolchainsRequest.getUserToolchainsSource(), userToolchainsFile));
|
||||||
|
@ -1380,14 +1402,18 @@ public class MavenCli {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String determineLocalRepositoryPath(final MavenExecutionRequest request) {
|
private String determineLocalRepositoryPath(final MavenExecutionRequest request) {
|
||||||
String userDefinedLocalRepo = request.getUserProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY);
|
String userDefinedLocalRepo = request.getUserProperties().getProperty(Constants.MAVEN_REPO_LOCAL);
|
||||||
|
if (userDefinedLocalRepo == null) {
|
||||||
|
userDefinedLocalRepo = request.getSystemProperties().getProperty(Constants.MAVEN_REPO_LOCAL);
|
||||||
if (userDefinedLocalRepo != null) {
|
if (userDefinedLocalRepo != null) {
|
||||||
return userDefinedLocalRepo;
|
slf4jLogger.warn(
|
||||||
|
"The property '{}' has been set using a JVM system property which is deprecated. "
|
||||||
|
+ "The property can be passed as a Maven argument or in the Maven project configuration file,"
|
||||||
|
+ "usually located at ${session.rootDirectory}/.mvn/maven.properties.",
|
||||||
|
Constants.MAVEN_REPO_LOCAL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// TODO Investigate why this can also be a Java system property and not just a Maven user property like
|
return userDefinedLocalRepo;
|
||||||
// other properties
|
|
||||||
return request.getSystemProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private File determinePom(final CommandLine commandLine, final String workingDirectory, final File baseDirectory) {
|
private File determinePom(final CommandLine commandLine, final String workingDirectory, final File baseDirectory) {
|
||||||
|
@ -1601,20 +1627,15 @@ public class MavenCli {
|
||||||
// Properties handling
|
// Properties handling
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
static void populateProperties(
|
void populateProperties(
|
||||||
CommandLine commandLine, Properties paths, Properties systemProperties, Properties userProperties)
|
CommandLine commandLine, Properties paths, Properties systemProperties, Properties userProperties)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Load environment and system properties
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
EnvironmentUtils.addEnvVars(systemProperties);
|
EnvironmentUtils.addEnvVars(systemProperties);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Options that are set on the command line become system properties
|
|
||||||
// and therefore are set in the session properties. System properties
|
|
||||||
// are most dominant.
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
final Properties userSpecifiedProperties =
|
|
||||||
commandLine.getOptionProperties(String.valueOf(CLIManager.SET_USER_PROPERTY));
|
|
||||||
|
|
||||||
SystemProperties.addSystemProperties(systemProperties);
|
SystemProperties.addSystemProperties(systemProperties);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
@ -1630,20 +1651,65 @@ public class MavenCli {
|
||||||
String mavenBuildVersion = CLIReportingUtils.createMavenVersionString(buildProperties);
|
String mavenBuildVersion = CLIReportingUtils.createMavenVersionString(buildProperties);
|
||||||
systemProperties.setProperty("maven.build.version", mavenBuildVersion);
|
systemProperties.setProperty("maven.build.version", mavenBuildVersion);
|
||||||
|
|
||||||
BasicInterpolator interpolator =
|
// ----------------------------------------------------------------------
|
||||||
createInterpolator(paths, systemProperties, userProperties, userSpecifiedProperties);
|
// Options that are set on the command line become system properties
|
||||||
for (Map.Entry<Object, Object> e : userSpecifiedProperties.entrySet()) {
|
// and therefore are set in the session properties. System properties
|
||||||
String name = (String) e.getKey();
|
// are most dominant.
|
||||||
String value = interpolator.interpolate((String) e.getValue());
|
// ----------------------------------------------------------------------
|
||||||
userProperties.setProperty(name, value);
|
|
||||||
|
Properties userSpecifiedProperties =
|
||||||
|
commandLine.getOptionProperties(String.valueOf(CLIManager.SET_USER_PROPERTY));
|
||||||
|
userProperties.putAll(userSpecifiedProperties);
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Load config files
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
Function<String, String> callback =
|
||||||
|
or(paths::getProperty, prefix("cli.", commandLine::getOptionValue), systemProperties::getProperty);
|
||||||
|
|
||||||
|
Path mavenConf;
|
||||||
|
if (systemProperties.getProperty(MAVEN_INSTALLATION_CONF) != null) {
|
||||||
|
mavenConf = fileSystem.getPath(systemProperties.getProperty(MAVEN_INSTALLATION_CONF));
|
||||||
|
} else if (systemProperties.getProperty("maven.conf") != null) {
|
||||||
|
mavenConf = fileSystem.getPath(systemProperties.getProperty("maven.conf"));
|
||||||
|
} else if (systemProperties.getProperty(MAVEN_HOME) != null) {
|
||||||
|
mavenConf = fileSystem.getPath(systemProperties.getProperty(MAVEN_HOME), "conf");
|
||||||
|
} else {
|
||||||
|
mavenConf = fileSystem.getPath("");
|
||||||
|
}
|
||||||
|
Path propertiesFile = mavenConf.resolve("maven.properties");
|
||||||
|
MavenPropertiesLoader.loadProperties(userProperties, propertiesFile, callback, false);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// I'm leaving the setting of system properties here as not to break
|
// I'm leaving the setting of system properties here as not to break
|
||||||
// the SystemPropertyProfileActivator. This won't harm embedding. jvz.
|
// the SystemPropertyProfileActivator. This won't harm embedding. jvz.
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
if (System.getProperty(name) == null) {
|
Set<String> sys = SystemProperties.getSystemProperties().stringPropertyNames();
|
||||||
System.setProperty(name, value);
|
userProperties.stringPropertyNames().stream()
|
||||||
|
.filter(k -> !sys.contains(k))
|
||||||
|
.forEach(k -> System.setProperty(k, userProperties.getProperty(k)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Function<String, String> prefix(String prefix, Function<String, String> cb) {
|
||||||
|
return s -> {
|
||||||
|
String v = null;
|
||||||
|
if (s.startsWith(prefix)) {
|
||||||
|
v = cb.apply(s.substring(prefix.length()));
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Function<String, String> or(Function<String, String>... callbacks) {
|
||||||
|
return s -> {
|
||||||
|
for (Function<String, String> cb : callbacks) {
|
||||||
|
String r = cb.apply(s);
|
||||||
|
if (r != null) {
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BasicInterpolator createInterpolator(Properties... properties) {
|
private static BasicInterpolator createInterpolator(Properties... properties) {
|
||||||
|
@ -1709,4 +1775,8 @@ public class MavenCli {
|
||||||
protected ModelProcessor createModelProcessor(PlexusContainer container) throws ComponentLookupException {
|
protected ModelProcessor createModelProcessor(PlexusContainer container) throws ComponentLookupException {
|
||||||
return container.lookup(ModelProcessor.class);
|
return container.lookup(ModelProcessor.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFileSystem(FileSystem fileSystem) {
|
||||||
|
this.fileSystem = fileSystem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,8 @@ public class SettingsXmlConfigurationProcessor implements ConfigurationProcessor
|
||||||
|
|
||||||
public static final File DEFAULT_PROJECT_SETTINGS_FILE = new File(".mvn", "settings.xml");
|
public static final File DEFAULT_PROJECT_SETTINGS_FILE = new File(".mvn", "settings.xml");
|
||||||
|
|
||||||
public static final File DEFAULT_GLOBAL_SETTINGS_FILE = new File(System.getProperty("maven.conf"), "settings.xml");
|
public static final File DEFAULT_INSTALLATION_SETTINGS_FILE =
|
||||||
|
new File(System.getProperty("maven.conf"), "settings.xml");
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(SettingsXmlConfigurationProcessor.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(SettingsXmlConfigurationProcessor.class);
|
||||||
|
|
||||||
|
@ -119,26 +120,34 @@ public class SettingsXmlConfigurationProcessor implements ConfigurationProcessor
|
||||||
projectSettingsFile = null;
|
projectSettingsFile = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
File globalSettingsFile;
|
File installationSettingsFile;
|
||||||
|
|
||||||
if (commandLine.hasOption(CLIManager.ALTERNATE_GLOBAL_SETTINGS)) {
|
if (commandLine.hasOption(CLIManager.ALTERNATE_INSTALLATION_SETTINGS)) {
|
||||||
globalSettingsFile = new File(commandLine.getOptionValue(CLIManager.ALTERNATE_GLOBAL_SETTINGS));
|
installationSettingsFile = new File(commandLine.getOptionValue(CLIManager.ALTERNATE_INSTALLATION_SETTINGS));
|
||||||
globalSettingsFile = resolveFile(globalSettingsFile, workingDirectory);
|
installationSettingsFile = resolveFile(installationSettingsFile, workingDirectory);
|
||||||
|
|
||||||
if (!globalSettingsFile.isFile()) {
|
if (!installationSettingsFile.isFile()) {
|
||||||
throw new FileNotFoundException(
|
throw new FileNotFoundException(
|
||||||
"The specified global settings file does not exist: " + globalSettingsFile);
|
"The specified installation settings file does not exist: " + installationSettingsFile);
|
||||||
|
}
|
||||||
|
} else if (commandLine.hasOption(CLIManager.ALTERNATE_GLOBAL_SETTINGS)) {
|
||||||
|
installationSettingsFile = new File(commandLine.getOptionValue(CLIManager.ALTERNATE_GLOBAL_SETTINGS));
|
||||||
|
installationSettingsFile = resolveFile(installationSettingsFile, workingDirectory);
|
||||||
|
|
||||||
|
if (!installationSettingsFile.isFile()) {
|
||||||
|
throw new FileNotFoundException(
|
||||||
|
"The specified installation settings file does not exist: " + installationSettingsFile);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
globalSettingsFile = DEFAULT_GLOBAL_SETTINGS_FILE;
|
installationSettingsFile = DEFAULT_INSTALLATION_SETTINGS_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
request.setGlobalSettingsFile(globalSettingsFile);
|
request.setInstallationSettingsFile(installationSettingsFile);
|
||||||
request.setProjectSettingsFile(projectSettingsFile);
|
request.setProjectSettingsFile(projectSettingsFile);
|
||||||
request.setUserSettingsFile(userSettingsFile);
|
request.setUserSettingsFile(userSettingsFile);
|
||||||
|
|
||||||
SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
|
SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
|
||||||
settingsRequest.setGlobalSettingsFile(globalSettingsFile);
|
settingsRequest.setGlobalSettingsFile(installationSettingsFile);
|
||||||
settingsRequest.setProjectSettingsFile(projectSettingsFile);
|
settingsRequest.setProjectSettingsFile(projectSettingsFile);
|
||||||
settingsRequest.setUserSettingsFile(userSettingsFile);
|
settingsRequest.setUserSettingsFile(userSettingsFile);
|
||||||
settingsRequest.setSystemProperties(cliRequest.getSystemProperties());
|
settingsRequest.setSystemProperties(cliRequest.getSystemProperties());
|
||||||
|
@ -155,7 +164,7 @@ public class SettingsXmlConfigurationProcessor implements ConfigurationProcessor
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.debug(
|
LOGGER.debug(
|
||||||
"Reading global settings from '{}'",
|
"Reading installation settings from '{}'",
|
||||||
getLocation(settingsRequest.getGlobalSettingsSource(), settingsRequest.getGlobalSettingsFile()));
|
getLocation(settingsRequest.getGlobalSettingsSource(), settingsRequest.getGlobalSettingsFile()));
|
||||||
LOGGER.debug(
|
LOGGER.debug(
|
||||||
"Reading project settings from '{}'",
|
"Reading project settings from '{}'",
|
||||||
|
|
|
@ -0,0 +1,309 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.maven.cli.props;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class InterpolationHelper {
|
||||||
|
|
||||||
|
private InterpolationHelper() {}
|
||||||
|
|
||||||
|
private static final char ESCAPE_CHAR = '\\';
|
||||||
|
private static final String DELIM_START = "${";
|
||||||
|
private static final String DELIM_STOP = "}";
|
||||||
|
private static final String MARKER = "$__";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform substitution on a property set
|
||||||
|
*
|
||||||
|
* @param properties the property set to perform substitution on
|
||||||
|
* @param callback Callback for substitution
|
||||||
|
*/
|
||||||
|
public static void performSubstitution(Map<String, String> properties, Function<String, String> callback) {
|
||||||
|
performSubstitution(properties, callback, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform substitution on a property set
|
||||||
|
*
|
||||||
|
* @param properties the property set to perform substitution on
|
||||||
|
* @param callback the callback to obtain substitution values
|
||||||
|
* @param substituteFromConfig If substitute from configuration
|
||||||
|
* @param defaultsToEmptyString sets an empty string if a replacement value is not found, leaves intact otherwise
|
||||||
|
*/
|
||||||
|
public static void performSubstitution(
|
||||||
|
Map<String, String> properties,
|
||||||
|
Function<String, String> callback,
|
||||||
|
boolean substituteFromConfig,
|
||||||
|
boolean defaultsToEmptyString) {
|
||||||
|
Map<String, String> org = new HashMap<>(properties);
|
||||||
|
for (String name : properties.keySet()) {
|
||||||
|
properties.compute(
|
||||||
|
name,
|
||||||
|
(k, value) ->
|
||||||
|
substVars(value, name, null, org, callback, substituteFromConfig, defaultsToEmptyString));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* This method performs property variable substitution on the
|
||||||
|
* specified value. If the specified value contains the syntax
|
||||||
|
* {@code ${<prop-name>}}, where {@code <prop-name>}
|
||||||
|
* refers to either a configuration property or a system property,
|
||||||
|
* then the corresponding property value is substituted for the variable
|
||||||
|
* placeholder. Multiple variable placeholders may exist in the
|
||||||
|
* specified value as well as nested variable placeholders, which
|
||||||
|
* are substituted from inner most to outer most. Configuration
|
||||||
|
* properties override system properties.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param val The string on which to perform property substitution.
|
||||||
|
* @param currentKey The key of the property being evaluated used to
|
||||||
|
* detect cycles.
|
||||||
|
* @param cycleMap Map of variable references used to detect nested cycles.
|
||||||
|
* @param configProps Set of configuration properties.
|
||||||
|
* @return The value of the specified string after system property substitution.
|
||||||
|
* @throws IllegalArgumentException If there was a syntax error in the
|
||||||
|
* property placeholder syntax or a recursive variable reference.
|
||||||
|
**/
|
||||||
|
public static String substVars(
|
||||||
|
String val, String currentKey, Map<String, String> cycleMap, Map<String, String> configProps) {
|
||||||
|
return substVars(val, currentKey, cycleMap, configProps, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* This method performs property variable substitution on the
|
||||||
|
* specified value. If the specified value contains the syntax
|
||||||
|
* {@code ${<prop-name>}}, where {@code <prop-name>}
|
||||||
|
* refers to either a configuration property or a system property,
|
||||||
|
* then the corresponding property value is substituted for the variable
|
||||||
|
* placeholder. Multiple variable placeholders may exist in the
|
||||||
|
* specified value as well as nested variable placeholders, which
|
||||||
|
* are substituted from inner most to outer most. Configuration
|
||||||
|
* properties override system properties.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param val The string on which to perform property substitution.
|
||||||
|
* @param currentKey The key of the property being evaluated used to
|
||||||
|
* detect cycles.
|
||||||
|
* @param cycleMap Map of variable references used to detect nested cycles.
|
||||||
|
* @param configProps Set of configuration properties.
|
||||||
|
* @param callback the callback to obtain substitution values
|
||||||
|
* @return The value of the specified string after system property substitution.
|
||||||
|
* @throws IllegalArgumentException If there was a syntax error in the
|
||||||
|
* property placeholder syntax or a recursive variable reference.
|
||||||
|
**/
|
||||||
|
public static String substVars(
|
||||||
|
String val,
|
||||||
|
String currentKey,
|
||||||
|
Map<String, String> cycleMap,
|
||||||
|
Map<String, String> configProps,
|
||||||
|
Function<String, String> callback) {
|
||||||
|
return substVars(val, currentKey, cycleMap, configProps, callback, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* This method performs property variable substitution on the
|
||||||
|
* specified value. If the specified value contains the syntax
|
||||||
|
* {@code ${<prop-name>}}, where {@code <prop-name>}
|
||||||
|
* refers to either a configuration property or a system property,
|
||||||
|
* then the corresponding property value is substituted for the variable
|
||||||
|
* placeholder. Multiple variable placeholders may exist in the
|
||||||
|
* specified value as well as nested variable placeholders, which
|
||||||
|
* are substituted from inner most to outer most. Configuration
|
||||||
|
* properties override system properties.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param val The string on which to perform property substitution.
|
||||||
|
* @param currentKey The key of the property being evaluated used to
|
||||||
|
* detect cycles.
|
||||||
|
* @param cycleMap Map of variable references used to detect nested cycles.
|
||||||
|
* @param configProps Set of configuration properties.
|
||||||
|
* @param callback the callback to obtain substitution values
|
||||||
|
* @param substituteFromConfig If substitute from configuration
|
||||||
|
* @param defaultsToEmptyString sets an empty string if a replacement value is not found, leaves intact otherwise
|
||||||
|
* @return The value of the specified string after system property substitution.
|
||||||
|
* @throws IllegalArgumentException If there was a syntax error in the
|
||||||
|
* property placeholder syntax or a recursive variable reference.
|
||||||
|
**/
|
||||||
|
public static String substVars(
|
||||||
|
String val,
|
||||||
|
String currentKey,
|
||||||
|
Map<String, String> cycleMap,
|
||||||
|
Map<String, String> configProps,
|
||||||
|
Function<String, String> callback,
|
||||||
|
boolean substituteFromConfig,
|
||||||
|
boolean defaultsToEmptyString) {
|
||||||
|
return unescape(doSubstVars(
|
||||||
|
val, currentKey, cycleMap, configProps, callback, substituteFromConfig, defaultsToEmptyString));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String doSubstVars(
|
||||||
|
String val,
|
||||||
|
String currentKey,
|
||||||
|
Map<String, String> cycleMap,
|
||||||
|
Map<String, String> configProps,
|
||||||
|
Function<String, String> callback,
|
||||||
|
boolean substituteFromConfig,
|
||||||
|
boolean defaultsToEmptyString) {
|
||||||
|
if (cycleMap == null) {
|
||||||
|
cycleMap = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put the current key in the cycle map.
|
||||||
|
cycleMap.put(currentKey, currentKey);
|
||||||
|
|
||||||
|
// Assume we have a value that is something like:
|
||||||
|
// "leading ${foo.${bar}} middle ${baz} trailing"
|
||||||
|
|
||||||
|
// Find the first ending '}' variable delimiter, which
|
||||||
|
// will correspond to the first deepest nested variable
|
||||||
|
// placeholder.
|
||||||
|
int startDelim;
|
||||||
|
int stopDelim = -1;
|
||||||
|
do {
|
||||||
|
stopDelim = val.indexOf(DELIM_STOP, stopDelim + 1);
|
||||||
|
while (stopDelim > 0 && val.charAt(stopDelim - 1) == ESCAPE_CHAR) {
|
||||||
|
stopDelim = val.indexOf(DELIM_STOP, stopDelim + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the matching starting "${" variable delimiter
|
||||||
|
// by looping until we find a start delimiter that is
|
||||||
|
// greater than the stop delimiter we have found.
|
||||||
|
startDelim = val.indexOf(DELIM_START);
|
||||||
|
while (stopDelim >= 0) {
|
||||||
|
int idx = val.indexOf(DELIM_START, startDelim + DELIM_START.length());
|
||||||
|
if ((idx < 0) || (idx > stopDelim)) {
|
||||||
|
break;
|
||||||
|
} else if (idx < stopDelim) {
|
||||||
|
startDelim = idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (startDelim >= 0 && stopDelim >= 0 && stopDelim < startDelim + DELIM_START.length());
|
||||||
|
|
||||||
|
// If we do not have a start or stop delimiter, then just
|
||||||
|
// return the existing value.
|
||||||
|
if ((startDelim < 0) || (stopDelim < 0)) {
|
||||||
|
cycleMap.remove(currentKey);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point, we have found a variable placeholder so
|
||||||
|
// we must perform a variable substitution on it.
|
||||||
|
// Using the start and stop delimiter indices, extract
|
||||||
|
// the first, deepest nested variable placeholder.
|
||||||
|
String variable = val.substring(startDelim + DELIM_START.length(), stopDelim);
|
||||||
|
String org = variable;
|
||||||
|
|
||||||
|
// Strip expansion modifiers
|
||||||
|
int idx1 = variable.lastIndexOf(":-");
|
||||||
|
int idx2 = variable.lastIndexOf(":+");
|
||||||
|
int idx = idx1 >= 0 && idx2 >= 0 ? Math.min(idx1, idx2) : idx1 >= 0 ? idx1 : idx2;
|
||||||
|
String op = null;
|
||||||
|
if (idx >= 0) {
|
||||||
|
op = variable.substring(idx);
|
||||||
|
variable = variable.substring(0, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that this is not a recursive variable reference.
|
||||||
|
if (cycleMap.get(variable) != null) {
|
||||||
|
throw new IllegalArgumentException("recursive variable reference: " + variable);
|
||||||
|
}
|
||||||
|
|
||||||
|
String substValue = null;
|
||||||
|
// Get the value of the deepest nested variable placeholder.
|
||||||
|
// Try to configuration properties first.
|
||||||
|
if (substituteFromConfig && configProps != null) {
|
||||||
|
substValue = configProps.get(variable);
|
||||||
|
}
|
||||||
|
if (substValue == null) {
|
||||||
|
if (!variable.isEmpty()) {
|
||||||
|
if (callback != null) {
|
||||||
|
substValue = callback.apply(variable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op != null) {
|
||||||
|
if (op.startsWith(":-")) {
|
||||||
|
if (substValue == null || substValue.isEmpty()) {
|
||||||
|
substValue = op.substring(":-".length());
|
||||||
|
}
|
||||||
|
} else if (op.startsWith(":+")) {
|
||||||
|
if (substValue != null && !substValue.isEmpty()) {
|
||||||
|
substValue = op.substring(":+".length());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Bad substitution: ${" + org + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (substValue == null) {
|
||||||
|
if (defaultsToEmptyString) {
|
||||||
|
substValue = "";
|
||||||
|
} else {
|
||||||
|
// alters the original token to avoid infinite recursion
|
||||||
|
// altered tokens are reverted in substVarsPreserveUnresolved()
|
||||||
|
substValue = MARKER + "{" + variable + "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the found variable from the cycle map, since
|
||||||
|
// it may appear more than once in the value and we don't
|
||||||
|
// want such situations to appear as a recursive reference.
|
||||||
|
cycleMap.remove(variable);
|
||||||
|
|
||||||
|
// Append the leading characters, the substituted value of
|
||||||
|
// the variable, and the trailing characters to get the new
|
||||||
|
// value.
|
||||||
|
val = val.substring(0, startDelim) + substValue + val.substring(stopDelim + DELIM_STOP.length());
|
||||||
|
|
||||||
|
// Now perform substitution again, since there could still
|
||||||
|
// be substitutions to make.
|
||||||
|
val = doSubstVars(
|
||||||
|
val, currentKey, cycleMap, configProps, callback, substituteFromConfig, defaultsToEmptyString);
|
||||||
|
|
||||||
|
cycleMap.remove(currentKey);
|
||||||
|
|
||||||
|
// Return the value.
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String escape(String val) {
|
||||||
|
return val.replace("$", MARKER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String unescape(String val) {
|
||||||
|
val = val.replaceAll("\\" + MARKER, "\\$");
|
||||||
|
int escape = val.indexOf(ESCAPE_CHAR);
|
||||||
|
while (escape >= 0 && escape < val.length() - 1) {
|
||||||
|
char c = val.charAt(escape + 1);
|
||||||
|
if (c == '{' || c == '}' || c == ESCAPE_CHAR) {
|
||||||
|
val = val.substring(0, escape) + val.substring(escape + 1);
|
||||||
|
}
|
||||||
|
escape = val.indexOf(ESCAPE_CHAR, escape + 1);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.maven.cli.props;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static org.apache.maven.cli.props.InterpolationHelper.substVars;
|
||||||
|
|
||||||
|
public class MavenPropertiesLoader {
|
||||||
|
|
||||||
|
public static final String INCLUDES_PROPERTY = "${includes}"; // includes
|
||||||
|
|
||||||
|
public static final String OVERRIDE_PREFIX =
|
||||||
|
"maven.override."; // prefix that marks that system property should override defaults.
|
||||||
|
|
||||||
|
public static void loadProperties(
|
||||||
|
java.util.Properties properties, Path path, Function<String, String> callback, boolean escape)
|
||||||
|
throws IOException {
|
||||||
|
MavenProperties sp = new MavenProperties(false);
|
||||||
|
if (Files.exists(path)) {
|
||||||
|
sp.load(path);
|
||||||
|
}
|
||||||
|
properties.forEach(
|
||||||
|
(k, v) -> sp.put(k.toString(), escape ? InterpolationHelper.escape(v.toString()) : v.toString()));
|
||||||
|
loadIncludes(path, sp, callback);
|
||||||
|
substitute(sp, callback);
|
||||||
|
sp.forEach(properties::setProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void substitute(MavenProperties props, Function<String, String> callback) {
|
||||||
|
for (Enumeration<?> e = props.propertyNames(); e.hasMoreElements(); ) {
|
||||||
|
String name = (String) e.nextElement();
|
||||||
|
String value = props.getProperty(name);
|
||||||
|
if (value == null) {
|
||||||
|
value = callback.apply(name);
|
||||||
|
}
|
||||||
|
if (name.startsWith(OVERRIDE_PREFIX)) {
|
||||||
|
String overrideName = name.substring(OVERRIDE_PREFIX.length());
|
||||||
|
props.put(overrideName, substVars(value, name, null, props, callback));
|
||||||
|
} else {
|
||||||
|
props.put(name, substVars(value, name, null, props, callback));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
props.keySet().removeIf(k -> k.startsWith(OVERRIDE_PREFIX));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MavenProperties loadPropertiesFile(
|
||||||
|
Path path, boolean failIfNotFound, Function<String, String> callback) throws IOException {
|
||||||
|
MavenProperties configProps = new MavenProperties(null, false);
|
||||||
|
if (Files.exists(path) || failIfNotFound) {
|
||||||
|
configProps.load(path);
|
||||||
|
loadIncludes(path, configProps, callback);
|
||||||
|
trimValues(configProps);
|
||||||
|
}
|
||||||
|
return configProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void loadIncludes(Path configProp, MavenProperties configProps, Function<String, String> callback)
|
||||||
|
throws IOException {
|
||||||
|
String includes = configProps.get(INCLUDES_PROPERTY);
|
||||||
|
if (includes != null) {
|
||||||
|
includes = substVars(includes, INCLUDES_PROPERTY, null, configProps, callback);
|
||||||
|
StringTokenizer st = new StringTokenizer(includes, "?\",", true);
|
||||||
|
if (st.countTokens() > 0) {
|
||||||
|
String location;
|
||||||
|
do {
|
||||||
|
location = nextLocation(st);
|
||||||
|
if (location != null) {
|
||||||
|
boolean mandatory = true;
|
||||||
|
if (location.startsWith("?")) {
|
||||||
|
mandatory = false;
|
||||||
|
location = location.substring(1);
|
||||||
|
}
|
||||||
|
Path path = configProp.resolveSibling(location);
|
||||||
|
MavenProperties props = loadPropertiesFile(path, mandatory, s -> {
|
||||||
|
var v = callback.apply(s);
|
||||||
|
return v != null ? v : configProps.getProperty(s);
|
||||||
|
});
|
||||||
|
configProps.putAll(props);
|
||||||
|
}
|
||||||
|
} while (location != null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
configProps.remove(INCLUDES_PROPERTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void trimValues(MavenProperties configProps) {
|
||||||
|
configProps.replaceAll((k, v) -> v.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String nextLocation(StringTokenizer st) {
|
||||||
|
boolean optional = false;
|
||||||
|
String retVal = null;
|
||||||
|
|
||||||
|
if (st.countTokens() > 0) {
|
||||||
|
String tokenList = "?\",";
|
||||||
|
StringBuilder tokBuf = new StringBuilder(10);
|
||||||
|
String tok;
|
||||||
|
boolean inQuote = false;
|
||||||
|
boolean tokStarted = false;
|
||||||
|
boolean exit = false;
|
||||||
|
while ((st.hasMoreTokens()) && (!exit)) {
|
||||||
|
tok = st.nextToken(tokenList);
|
||||||
|
switch (tok) {
|
||||||
|
case "\"":
|
||||||
|
inQuote = !inQuote;
|
||||||
|
if (inQuote) {
|
||||||
|
tokenList = "\"";
|
||||||
|
} else {
|
||||||
|
tokenList = "\" ";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ",":
|
||||||
|
if (tokStarted) {
|
||||||
|
retVal = tokBuf.toString();
|
||||||
|
tokStarted = false;
|
||||||
|
tokBuf = new StringBuilder(10);
|
||||||
|
exit = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "?":
|
||||||
|
optional = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
tokStarted = true;
|
||||||
|
tokBuf.append(tok.trim());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle case where end of token stream and
|
||||||
|
// still got data
|
||||||
|
if ((!exit) && (tokStarted)) {
|
||||||
|
retVal = tokBuf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return optional ? "?" + retVal : retVal;
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,12 +22,16 @@ import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.FileSystem;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import com.google.common.jimfs.Configuration;
|
||||||
|
import com.google.common.jimfs.Jimfs;
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
import org.apache.commons.cli.CommandLineParser;
|
import org.apache.commons.cli.CommandLineParser;
|
||||||
import org.apache.commons.cli.DefaultParser;
|
import org.apache.commons.cli.DefaultParser;
|
||||||
|
@ -35,6 +39,7 @@ import org.apache.commons.cli.Option;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.apache.maven.Maven;
|
import org.apache.maven.Maven;
|
||||||
|
import org.apache.maven.api.Constants;
|
||||||
import org.apache.maven.cli.transfer.ConsoleMavenTransferListener;
|
import org.apache.maven.cli.transfer.ConsoleMavenTransferListener;
|
||||||
import org.apache.maven.cli.transfer.QuietMavenTransferListener;
|
import org.apache.maven.cli.transfer.QuietMavenTransferListener;
|
||||||
import org.apache.maven.cli.transfer.SimplexTransferListener;
|
import org.apache.maven.cli.transfer.SimplexTransferListener;
|
||||||
|
@ -51,6 +56,7 @@ import org.apache.maven.toolchain.building.ToolchainsBuildingResult;
|
||||||
import org.codehaus.plexus.DefaultPlexusContainer;
|
import org.codehaus.plexus.DefaultPlexusContainer;
|
||||||
import org.codehaus.plexus.PlexusContainer;
|
import org.codehaus.plexus.PlexusContainer;
|
||||||
import org.eclipse.aether.transfer.TransferListener;
|
import org.eclipse.aether.transfer.TransferListener;
|
||||||
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -453,24 +459,25 @@ class MavenCliTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void verifyLocalRepositoryPath() {
|
void verifyLocalRepositoryPath() throws Exception {
|
||||||
MavenCli cli = new MavenCli();
|
MavenCli cli = new MavenCli();
|
||||||
CliRequest request = new CliRequest(new String[] {}, null);
|
CliRequest request = new CliRequest(new String[] {}, null);
|
||||||
request.commandLine = new CommandLine.Builder().build();
|
request.commandLine = new CommandLine.Builder().build();
|
||||||
MavenExecutionRequest executionRequest;
|
MavenExecutionRequest executionRequest;
|
||||||
|
|
||||||
// Use default
|
// Use default
|
||||||
|
cli.cli(request);
|
||||||
executionRequest = cli.populateRequest(request);
|
executionRequest = cli.populateRequest(request);
|
||||||
assertThat(executionRequest.getLocalRepositoryPath(), is(nullValue()));
|
assertThat(executionRequest.getLocalRepositoryPath(), is(nullValue()));
|
||||||
|
|
||||||
// System-properties override default
|
// System-properties override default
|
||||||
request.getSystemProperties().setProperty(MavenCli.LOCAL_REPO_PROPERTY, "." + File.separatorChar + "custom1");
|
request.getSystemProperties().setProperty(Constants.MAVEN_REPO_LOCAL, "." + File.separatorChar + "custom1");
|
||||||
executionRequest = cli.populateRequest(request);
|
executionRequest = cli.populateRequest(request);
|
||||||
assertThat(executionRequest.getLocalRepositoryPath(), is(notNullValue()));
|
assertThat(executionRequest.getLocalRepositoryPath(), is(notNullValue()));
|
||||||
assertThat(executionRequest.getLocalRepositoryPath().toString(), is("." + File.separatorChar + "custom1"));
|
assertThat(executionRequest.getLocalRepositoryPath().toString(), is("." + File.separatorChar + "custom1"));
|
||||||
|
|
||||||
// User-properties override system properties
|
// User-properties override system properties
|
||||||
request.getUserProperties().setProperty(MavenCli.LOCAL_REPO_PROPERTY, "." + File.separatorChar + "custom2");
|
request.getUserProperties().setProperty(Constants.MAVEN_REPO_LOCAL, "." + File.separatorChar + "custom2");
|
||||||
executionRequest = cli.populateRequest(request);
|
executionRequest = cli.populateRequest(request);
|
||||||
assertThat(executionRequest.getLocalRepositoryPath(), is(notNullValue()));
|
assertThat(executionRequest.getLocalRepositoryPath(), is(notNullValue()));
|
||||||
assertThat(executionRequest.getLocalRepositoryPath().toString(), is("." + File.separatorChar + "custom2"));
|
assertThat(executionRequest.getLocalRepositoryPath().toString(), is("." + File.separatorChar + "custom2"));
|
||||||
|
@ -578,9 +585,27 @@ class MavenCliTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPropertiesInterpolation() throws Exception {
|
public void testPropertiesInterpolation() throws Exception {
|
||||||
|
FileSystem fs = Jimfs.newFileSystem(Configuration.windows());
|
||||||
|
|
||||||
|
Path mavenHome = fs.getPath("C:\\maven");
|
||||||
|
Files.createDirectories(mavenHome);
|
||||||
|
Path mavenConf = mavenHome.resolve("conf");
|
||||||
|
Files.createDirectories(mavenConf);
|
||||||
|
Path mavenUserProps = mavenConf.resolve("maven.properties");
|
||||||
|
Files.writeString(mavenUserProps, "${includes} = ?${session.rootDirectory}/.mvn/maven.properties\n");
|
||||||
|
Path rootDirectory = fs.getPath("C:\\myRootDirectory");
|
||||||
|
Path topDirectory = rootDirectory.resolve("myTopDirectory");
|
||||||
|
Path mvn = rootDirectory.resolve(".mvn");
|
||||||
|
Files.createDirectories(mvn);
|
||||||
|
Files.writeString(
|
||||||
|
mvn.resolve("maven.properties"),
|
||||||
|
"${includes} = env-${envName}.properties\nfro = ${bar}z\n" + "bar = chti${java.version}\n");
|
||||||
|
Files.writeString(mvn.resolve("env-test.properties"), "\n");
|
||||||
|
|
||||||
// Arrange
|
// Arrange
|
||||||
CliRequest request = new CliRequest(
|
CliRequest request = new CliRequest(
|
||||||
new String[] {
|
new String[] {
|
||||||
|
"-DenvName=test",
|
||||||
"-Dfoo=bar",
|
"-Dfoo=bar",
|
||||||
"-DvalFound=s${foo}i",
|
"-DvalFound=s${foo}i",
|
||||||
"-DvalNotFound=s${foz}i",
|
"-DvalNotFound=s${foz}i",
|
||||||
|
@ -592,20 +617,28 @@ class MavenCliTest {
|
||||||
"validate"
|
"validate"
|
||||||
},
|
},
|
||||||
null);
|
null);
|
||||||
request.rootDirectory = Paths.get("myRootDirectory");
|
request.rootDirectory = rootDirectory;
|
||||||
request.topDirectory = Paths.get("myTopDirectory");
|
request.topDirectory = topDirectory;
|
||||||
|
System.setProperty("maven.installation.conf", mavenConf.toString());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
cli.setFileSystem(fs);
|
||||||
cli.cli(request);
|
cli.cli(request);
|
||||||
cli.properties(request);
|
cli.properties(request);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
assertThat(request.getUserProperties().getProperty("fro"), CoreMatchers.startsWith("chti"));
|
||||||
assertThat(request.getUserProperties().getProperty("valFound"), is("sbari"));
|
assertThat(request.getUserProperties().getProperty("valFound"), is("sbari"));
|
||||||
assertThat(request.getUserProperties().getProperty("valNotFound"), is("s${foz}i"));
|
assertThat(request.getUserProperties().getProperty("valNotFound"), is("s${foz}i"));
|
||||||
assertThat(request.getUserProperties().getProperty("valRootDirectory"), is("myRootDirectory/.mvn/foo"));
|
assertThat(request.getUserProperties().getProperty("valRootDirectory"), is("C:\\myRootDirectory/.mvn/foo"));
|
||||||
assertThat(request.getUserProperties().getProperty("valTopDirectory"), is("myTopDirectory/pom.xml"));
|
assertThat(
|
||||||
assertThat(request.getCommandLine().getOptionValue('f'), is("myRootDirectory/my-child"));
|
request.getUserProperties().getProperty("valTopDirectory"),
|
||||||
|
is("C:\\myRootDirectory\\myTopDirectory/pom.xml"));
|
||||||
|
assertThat(request.getCommandLine().getOptionValue('f'), is("C:\\myRootDirectory/my-child"));
|
||||||
assertThat(request.getCommandLine().getArgs(), equalTo(new String[] {"prefix:3.0.0:bar", "validate"}));
|
assertThat(request.getCommandLine().getArgs(), equalTo(new String[] {"prefix:3.0.0:bar", "validate"}));
|
||||||
|
|
||||||
|
Path p = fs.getPath(request.getUserProperties().getProperty("valTopDirectory"));
|
||||||
|
assertThat(p.toString(), is("C:\\myRootDirectory\\myTopDirectory\\pom.xml"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.maven.cli.props;
|
||||||
|
|
||||||
|
import java.nio.file.FileSystem;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.NoSuchFileException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import com.google.common.jimfs.Configuration;
|
||||||
|
import com.google.common.jimfs.Jimfs;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
class MavenPropertiesLoaderTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIncludes() throws Exception {
|
||||||
|
FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
|
||||||
|
|
||||||
|
Path mavenHome = fs.getPath("/maven");
|
||||||
|
Files.createDirectories(mavenHome);
|
||||||
|
Path mavenConf = mavenHome.resolve("conf");
|
||||||
|
Files.createDirectories(mavenConf);
|
||||||
|
Path mavenUserProps = mavenConf.resolve("maven.properties");
|
||||||
|
Files.writeString(mavenUserProps, "${includes} = ?\"/user/ma ven.properties\", ?/foo/bar\n");
|
||||||
|
Path userDirectory = fs.getPath("/user");
|
||||||
|
Files.createDirectories(userDirectory);
|
||||||
|
Path propsPath = userDirectory.resolve("ma ven.properties");
|
||||||
|
Files.writeString(propsPath, "${includes} = another.properties\nfro = ${bar}z\n");
|
||||||
|
|
||||||
|
Properties p = new Properties();
|
||||||
|
p.put("java.version", "11");
|
||||||
|
assertThrows(
|
||||||
|
NoSuchFileException.class, () -> MavenPropertiesLoader.loadProperties(p, mavenUserProps, null, false));
|
||||||
|
|
||||||
|
Path another = propsPath.resolveSibling("another.properties");
|
||||||
|
Files.writeString(another, "bar = chti${java.version}\n");
|
||||||
|
MavenPropertiesLoader.loadProperties(p, mavenUserProps, null, false);
|
||||||
|
assertEquals("chti11z", p.getProperty("fro"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIncludes3() throws Exception {
|
||||||
|
FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
|
||||||
|
|
||||||
|
Path mavenHome = fs.getPath("/maven");
|
||||||
|
Files.createDirectories(mavenHome);
|
||||||
|
Path mavenConf = mavenHome.resolve("conf");
|
||||||
|
Files.createDirectories(mavenConf);
|
||||||
|
Path mavenUserProps = mavenConf.resolve("maven.properties");
|
||||||
|
Files.writeString(mavenUserProps, "${includes} = ?\"${user.home}/maven.properties\"\n");
|
||||||
|
Path userDirectory = fs.getPath("/user");
|
||||||
|
Files.createDirectories(userDirectory);
|
||||||
|
Path propsPath = userDirectory.resolve("maven.properties");
|
||||||
|
Files.writeString(propsPath, "${includes} = default.properties,?env-${env.envName}.properties\n");
|
||||||
|
Path defPath = userDirectory.resolve("default.properties");
|
||||||
|
Files.writeString(defPath, "foo=bar");
|
||||||
|
Path envPath = userDirectory.resolve("env-ci.properties");
|
||||||
|
Files.writeString(envPath, "foo=bar-env\nfoo-env=bar\n");
|
||||||
|
|
||||||
|
Properties p = new Properties();
|
||||||
|
p.put("user.home", userDirectory.toString());
|
||||||
|
MavenPropertiesLoader.loadProperties(p, mavenUserProps, p::getProperty, false);
|
||||||
|
assertEquals("bar", p.getProperty("foo"));
|
||||||
|
assertNull(p.getProperty("foo-env"));
|
||||||
|
|
||||||
|
p = new Properties();
|
||||||
|
p.put("user.home", userDirectory.toString());
|
||||||
|
p.put("env.envName", "ci");
|
||||||
|
MavenPropertiesLoader.loadProperties(p, mavenUserProps, p::getProperty, false);
|
||||||
|
assertEquals("bar-env", p.getProperty("foo"));
|
||||||
|
assertEquals("bar", p.getProperty("foo-env"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,428 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.maven.cli.props;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests on <code>MavenProperties</code>.
|
||||||
|
*/
|
||||||
|
public class MavenPropertiesTest {
|
||||||
|
|
||||||
|
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
|
||||||
|
private static final String COMMENT = "# comment";
|
||||||
|
private static final String KEY1 = "mvn:foo/bar";
|
||||||
|
private static final String KEY1A = "mvn\\:foo/bar";
|
||||||
|
private static final String KEY2 = "foo:bar:version:type:classifier";
|
||||||
|
private static final String KEY2A = "foo\\:bar\\:version\\:type\\:classifier";
|
||||||
|
private static final String VALUE1 = "value";
|
||||||
|
|
||||||
|
private MavenProperties properties;
|
||||||
|
|
||||||
|
static final String TEST_PROPERTIES =
|
||||||
|
"""
|
||||||
|
#
|
||||||
|
# test.properties
|
||||||
|
# Used in the PropertiesTest
|
||||||
|
#
|
||||||
|
test=test
|
||||||
|
""";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see junit.framework.TestCase#setUp()
|
||||||
|
*/
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
properties = new MavenProperties();
|
||||||
|
properties.load(new StringReader(TEST_PROPERTIES));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSpaces() throws Exception {
|
||||||
|
String config = "\n" + "\n"
|
||||||
|
+ " \n"
|
||||||
|
+ " \n"
|
||||||
|
+ " \\ \\r \\n \\t \\f\n"
|
||||||
|
+ " \n"
|
||||||
|
+ " \n"
|
||||||
|
+ "! dshfjklahfjkldashgjl;as\n"
|
||||||
|
+ " #jdfagdfjagkdjfghksdajfd\n"
|
||||||
|
+ " \n"
|
||||||
|
+ "!!properties\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "a=a\n"
|
||||||
|
+ "b bb as,dn \n"
|
||||||
|
+ "c\\r\\ \\t\\nu =:: cu\n"
|
||||||
|
+ "bu= b\\\n"
|
||||||
|
+ " u\n"
|
||||||
|
+ "d=d\\r\\ne=e\n"
|
||||||
|
+ "f :f\\\n"
|
||||||
|
+ "f\\\n"
|
||||||
|
+ " f\n"
|
||||||
|
+ "g g\n"
|
||||||
|
+ "h\\u0020h\n"
|
||||||
|
+ "\\ i=i\n"
|
||||||
|
+ "j=\\ j\n"
|
||||||
|
+ "space=\\ c\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "dblbackslash=\\\\\n"
|
||||||
|
+ " \n";
|
||||||
|
|
||||||
|
java.util.Properties props1 = new java.util.Properties();
|
||||||
|
props1.load(new StringReader(config));
|
||||||
|
|
||||||
|
MavenProperties props2 = new MavenProperties();
|
||||||
|
props2.load(new StringReader(config));
|
||||||
|
|
||||||
|
String s325 = props1.getProperty(" \r");
|
||||||
|
assertEquals("\n \t \f", s325, "1");
|
||||||
|
String s324 = props1.getProperty("a");
|
||||||
|
assertEquals("a", s324, "2");
|
||||||
|
String s323 = props1.getProperty("b");
|
||||||
|
assertEquals("bb as,dn ", s323, "3");
|
||||||
|
String s322 = props1.getProperty("c\r \t\nu");
|
||||||
|
assertEquals(":: cu", s322, "4");
|
||||||
|
String s321 = props1.getProperty("bu");
|
||||||
|
assertEquals("bu", s321, "5");
|
||||||
|
String s320 = props1.getProperty("d");
|
||||||
|
assertEquals("d\r\ne=e", s320, "6");
|
||||||
|
String s319 = props1.getProperty("f");
|
||||||
|
assertEquals("fff", s319, "7");
|
||||||
|
String s318 = props1.getProperty("g");
|
||||||
|
assertEquals("g", s318, "8");
|
||||||
|
String s317 = props1.getProperty("h h");
|
||||||
|
assertEquals("", s317, "9");
|
||||||
|
String s316 = props1.getProperty(" ");
|
||||||
|
assertEquals("i=i", s316, "10");
|
||||||
|
String s315 = props1.getProperty("j");
|
||||||
|
assertEquals(" j", s315, "11");
|
||||||
|
String s314 = props1.getProperty("space");
|
||||||
|
assertEquals(" c", s314, "12");
|
||||||
|
String s313 = props1.getProperty("dblbackslash");
|
||||||
|
assertEquals("\\", s313, "13");
|
||||||
|
|
||||||
|
String s312 = props2.getProperty(" \r");
|
||||||
|
assertEquals("\n \t \f", s312, "1");
|
||||||
|
String s311 = props2.getProperty("a");
|
||||||
|
assertEquals("a", s311, "2");
|
||||||
|
String s310 = props2.getProperty("b");
|
||||||
|
assertEquals("bb as,dn ", s310, "3");
|
||||||
|
String s39 = props2.getProperty("c\r \t\nu");
|
||||||
|
assertEquals(":: cu", s39, "4");
|
||||||
|
String s38 = props2.getProperty("bu");
|
||||||
|
assertEquals("bu", s38, "5");
|
||||||
|
String s37 = props2.getProperty("d");
|
||||||
|
assertEquals("d\r\ne=e", s37, "6");
|
||||||
|
String s36 = props2.getProperty("f");
|
||||||
|
assertEquals("fff", s36, "7");
|
||||||
|
String s35 = props2.getProperty("g");
|
||||||
|
assertEquals("g", s35, "8");
|
||||||
|
String s34 = props2.getProperty("h h");
|
||||||
|
assertEquals("", s34, "9");
|
||||||
|
String s33 = props2.getProperty(" ");
|
||||||
|
assertEquals("i=i", s33, "10");
|
||||||
|
String s32 = props2.getProperty("j");
|
||||||
|
assertEquals(" j", s32, "11");
|
||||||
|
String s31 = props2.getProperty("space");
|
||||||
|
assertEquals(" c", s31, "12");
|
||||||
|
String s3 = props2.getProperty("dblbackslash");
|
||||||
|
assertEquals("\\", s3, "13");
|
||||||
|
assertEquals(props1, props2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConfigInterpolation() throws IOException {
|
||||||
|
String config = "a=$\\\\\\\\{var}\n" + "ab=${a}b\n" + "abc=${ab}c";
|
||||||
|
|
||||||
|
java.util.Properties props1 = new java.util.Properties();
|
||||||
|
props1.load(new StringReader(config));
|
||||||
|
InterpolationHelper.performSubstitution((Map) props1, null);
|
||||||
|
|
||||||
|
MavenProperties props2 = new MavenProperties();
|
||||||
|
props2.load(new StringReader(config));
|
||||||
|
|
||||||
|
assertEquals(props1, props2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Test getting property.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGettingProperty() throws Exception {
|
||||||
|
Object o2 = properties.get("test");
|
||||||
|
assertEquals("test", o2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoadSave() throws IOException {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
pw.println("# ");
|
||||||
|
pw.println("# The Main ");
|
||||||
|
pw.println("# ");
|
||||||
|
pw.println("# Comment ");
|
||||||
|
pw.println("# ");
|
||||||
|
pw.println("");
|
||||||
|
pw.println("# Another comment");
|
||||||
|
pw.println("");
|
||||||
|
pw.println("# A value comment");
|
||||||
|
pw.println("key1 = val1");
|
||||||
|
pw.println("");
|
||||||
|
pw.println("# Another value comment");
|
||||||
|
pw.println("key2 = ${key1}/foo");
|
||||||
|
pw.println("");
|
||||||
|
pw.println("# A third comment");
|
||||||
|
pw.println("key3 = val3");
|
||||||
|
pw.println("");
|
||||||
|
|
||||||
|
MavenProperties props = new MavenProperties();
|
||||||
|
props.load(new StringReader(sw.toString()));
|
||||||
|
props.save(System.err);
|
||||||
|
System.err.println("=====");
|
||||||
|
|
||||||
|
props.put("key2", props.get("key2"));
|
||||||
|
props.put("key3", "foo");
|
||||||
|
props.save(System.err);
|
||||||
|
System.err.println("=====");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJavaUtilPropertiesCompatibility() throws Exception {
|
||||||
|
MavenProperties properties = new MavenProperties();
|
||||||
|
properties.load(new StringReader(TEST_PROPERTIES));
|
||||||
|
|
||||||
|
String test = properties.getProperty("test");
|
||||||
|
assertEquals(test, "test");
|
||||||
|
|
||||||
|
String defaultValue = properties.getProperty("notfound", "default");
|
||||||
|
assertEquals(defaultValue, "default");
|
||||||
|
|
||||||
|
properties.setProperty("another", "another");
|
||||||
|
Object o1 = properties.getProperty("another");
|
||||||
|
assertEquals(o1, "another");
|
||||||
|
|
||||||
|
properties.store(System.err, null);
|
||||||
|
System.err.println("====");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String RESULT1 = COMMENT + LINE_SEPARATOR + KEY1A + " = " + VALUE1 + LINE_SEPARATOR;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaveComment1() throws Exception {
|
||||||
|
properties.put(KEY1, COMMENT, VALUE1);
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
properties.save(sw);
|
||||||
|
String msg = sw.toString();
|
||||||
|
assertTrue(sw.toString().endsWith(RESULT1), msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String RESULT1A = COMMENT + LINE_SEPARATOR + KEY2A + " = " + VALUE1 + LINE_SEPARATOR;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaveComment1a() throws Exception {
|
||||||
|
properties.put(KEY2, COMMENT, VALUE1);
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
properties.save(sw);
|
||||||
|
String msg = sw.toString();
|
||||||
|
assertTrue(sw.toString().endsWith(RESULT1A), msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String RESULT2 =
|
||||||
|
COMMENT + LINE_SEPARATOR + COMMENT + LINE_SEPARATOR + KEY1A + " = " + VALUE1 + LINE_SEPARATOR;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaveComment2() throws Exception {
|
||||||
|
properties.put(KEY1, List.of(new String[] {COMMENT, COMMENT}), VALUE1);
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
properties.save(sw);
|
||||||
|
String msg = sw.toString();
|
||||||
|
assertTrue(sw.toString().endsWith(RESULT2), msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String RESULT3 = COMMENT + LINE_SEPARATOR + COMMENT + LINE_SEPARATOR + KEY1A + " = " + VALUE1
|
||||||
|
+ "\\" + LINE_SEPARATOR + VALUE1 + LINE_SEPARATOR;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaveComment3() throws Exception {
|
||||||
|
properties.put(KEY1, List.of(new String[] {COMMENT, COMMENT}), List.of(new String[] {VALUE1, VALUE1}));
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
properties.save(sw);
|
||||||
|
String msg = sw.toString();
|
||||||
|
assertTrue(sw.toString().endsWith(RESULT3), msg);
|
||||||
|
List<String> rawValue = properties.getRaw(KEY1);
|
||||||
|
assertEquals(2, (Object) rawValue.size());
|
||||||
|
assertEquals(KEY1A + " = " + VALUE1, rawValue.get(0));
|
||||||
|
assertEquals(VALUE1, rawValue.get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEntrySetValue() throws Exception {
|
||||||
|
properties.put(KEY1, VALUE1);
|
||||||
|
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
properties.save(baos);
|
||||||
|
|
||||||
|
properties = new MavenProperties();
|
||||||
|
properties.load(new ByteArrayInputStream(baos.toByteArray()));
|
||||||
|
Object o22 = properties.get(KEY1);
|
||||||
|
assertEquals(VALUE1, o22);
|
||||||
|
for (Map.Entry<String, String> entry : properties.entrySet()) {
|
||||||
|
entry.setValue(entry.getValue() + "x");
|
||||||
|
}
|
||||||
|
Object o21 = properties.get(KEY1);
|
||||||
|
assertEquals(VALUE1 + "x", o21);
|
||||||
|
|
||||||
|
baos = new ByteArrayOutputStream();
|
||||||
|
properties.save(baos);
|
||||||
|
|
||||||
|
properties = new MavenProperties();
|
||||||
|
properties.load(new ByteArrayInputStream(baos.toByteArray()));
|
||||||
|
Object o2 = properties.get(KEY1);
|
||||||
|
assertEquals(VALUE1 + "x", o2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiValueEscaping() throws IOException {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
pw.println("fruits apple, banana, pear, \\");
|
||||||
|
pw.println(" cantaloupe, watermelon, \\");
|
||||||
|
pw.println(" kiwi, mango");
|
||||||
|
|
||||||
|
java.util.Properties p = new java.util.Properties();
|
||||||
|
p.load(new StringReader(sw.toString()));
|
||||||
|
Object o24 = p.getProperty("fruits");
|
||||||
|
assertEquals("apple, banana, pear, cantaloupe, watermelon, kiwi, mango", o24);
|
||||||
|
|
||||||
|
MavenProperties props = new MavenProperties();
|
||||||
|
props.load(new StringReader(sw.toString()));
|
||||||
|
Object o23 = props.getProperty("fruits");
|
||||||
|
assertEquals("apple, banana, pear, cantaloupe, watermelon, kiwi, mango", o23);
|
||||||
|
List<String> raw = props.getRaw("fruits");
|
||||||
|
assertNotNull(raw);
|
||||||
|
assertEquals(3, (Object) raw.size());
|
||||||
|
assertEquals("fruits apple, banana, pear, ", raw.get(0));
|
||||||
|
|
||||||
|
props = new MavenProperties();
|
||||||
|
props.put(
|
||||||
|
"fruits",
|
||||||
|
props.getComments("fruits"),
|
||||||
|
List.of(
|
||||||
|
"fruits apple, banana, pear, ",
|
||||||
|
" cantaloupe, watermelon, ",
|
||||||
|
" kiwi, mango"));
|
||||||
|
Object o22 = props.getProperty("fruits");
|
||||||
|
assertEquals("apple, banana, pear, cantaloupe, watermelon, kiwi, mango", o22);
|
||||||
|
raw = props.getRaw("fruits");
|
||||||
|
assertNotNull(raw);
|
||||||
|
assertEquals(3, (Object) raw.size());
|
||||||
|
assertEquals("fruits apple, banana, pear, ", raw.get(0));
|
||||||
|
|
||||||
|
sw = new StringWriter();
|
||||||
|
props.save(sw);
|
||||||
|
props = new MavenProperties();
|
||||||
|
props.load(new StringReader(sw.toString()));
|
||||||
|
Object o21 = props.getProperty("fruits");
|
||||||
|
assertEquals("apple, banana, pear, cantaloupe, watermelon, kiwi, mango", o21);
|
||||||
|
raw = props.getRaw("fruits");
|
||||||
|
assertNotNull(raw);
|
||||||
|
assertEquals(3, (Object) raw.size());
|
||||||
|
assertEquals("fruits apple, banana, pear, ", raw.get(0));
|
||||||
|
|
||||||
|
props = new MavenProperties();
|
||||||
|
props.put(
|
||||||
|
"fruits",
|
||||||
|
props.getComments("fruits"),
|
||||||
|
List.of(
|
||||||
|
" apple, banana, pear, ",
|
||||||
|
" cantaloupe, watermelon, ",
|
||||||
|
" kiwi, mango"));
|
||||||
|
Object o2 = props.getProperty("fruits");
|
||||||
|
assertEquals("apple, banana, pear, cantaloupe, watermelon, kiwi, mango", o2);
|
||||||
|
raw = props.getRaw("fruits");
|
||||||
|
assertNotNull(raw);
|
||||||
|
assertEquals(3, (Object) raw.size());
|
||||||
|
assertEquals("fruits = apple, banana, pear, ", raw.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdate() throws Exception {
|
||||||
|
MavenProperties p1 = new MavenProperties();
|
||||||
|
p1.put(
|
||||||
|
"fruits",
|
||||||
|
List.of("#", "# List of fruits", "#"),
|
||||||
|
List.of(
|
||||||
|
" apple, banana, pear, ",
|
||||||
|
" cantaloupe, watermelon, ",
|
||||||
|
" kiwi, mango"));
|
||||||
|
p1.put("trees", List.of("#", "# List of trees", "#"), List.of(" fir, oak, maple"));
|
||||||
|
p1.put("vegetables", List.of("#", "# List of vegetables", "#"), List.of(" potatoes"));
|
||||||
|
|
||||||
|
MavenProperties p2 = new MavenProperties();
|
||||||
|
p2.put(
|
||||||
|
"fruits",
|
||||||
|
List.of("#", "# List of good fruits", "#"),
|
||||||
|
List.of(" apple, banana, pear"));
|
||||||
|
p2.put("trees", "fir, oak, maple");
|
||||||
|
p1.update(p2);
|
||||||
|
|
||||||
|
assertEquals(2, (Object) p1.size());
|
||||||
|
Object o23 = p1.getComments("trees");
|
||||||
|
assertEquals(List.of("#", "# List of trees", "#"), o23);
|
||||||
|
Object o22 = p1.getProperty("trees");
|
||||||
|
assertEquals("fir, oak, maple", o22);
|
||||||
|
Object o21 = p1.getComments("fruits");
|
||||||
|
assertEquals(List.of("#", "# List of good fruits", "#"), o21);
|
||||||
|
Object o2 = p1.getProperty("fruits");
|
||||||
|
assertEquals("apple, banana, pear", o2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSubstitution() throws IOException {
|
||||||
|
String str = "port = 4141" + LINE_SEPARATOR + "host = localhost"
|
||||||
|
+ LINE_SEPARATOR + "url = https://${host}:${port}/service"
|
||||||
|
+ LINE_SEPARATOR;
|
||||||
|
MavenProperties properties = new MavenProperties();
|
||||||
|
properties.load(new StringReader(str));
|
||||||
|
properties.put("url", "https://localhost:4141/service");
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
properties.save(sw);
|
||||||
|
Object o2 = sw.toString();
|
||||||
|
assertEquals(str, o2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -85,7 +85,8 @@ public class DefaultSettingsBuilder implements SettingsBuilder {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}))
|
}))
|
||||||
.globalSettingsSource(toSource(request.getGlobalSettingsFile(), request.getGlobalSettingsSource()))
|
.installationSettingsSource(
|
||||||
|
toSource(request.getGlobalSettingsFile(), request.getGlobalSettingsSource()))
|
||||||
.projectSettingsSource(
|
.projectSettingsSource(
|
||||||
toSource(request.getProjectSettingsFile(), request.getProjectSettingsSource()))
|
toSource(request.getProjectSettingsFile(), request.getProjectSettingsSource()))
|
||||||
.userSettingsSource(toSource(request.getUserSettingsFile(), request.getUserSettingsSource()))
|
.userSettingsSource(toSource(request.getUserSettingsFile(), request.getUserSettingsSource()))
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class DefaultToolchainsBuilder implements ToolchainsBuilder {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}))
|
}))
|
||||||
.globalToolchainsSource(convert(request.getGlobalToolchainsSource()))
|
.installationToolchainsSource(convert(request.getGlobalToolchainsSource()))
|
||||||
.userToolchainsSource(convert(request.getUserToolchainsSource()))
|
.userToolchainsSource(convert(request.getUserToolchainsSource()))
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
|
|
1
pom.xml
1
pom.xml
|
@ -123,6 +123,7 @@ under the License.
|
||||||
<module>maven-toolchain-model</module>
|
<module>maven-toolchain-model</module>
|
||||||
<module>maven-toolchain-builder</module>
|
<module>maven-toolchain-builder</module>
|
||||||
<module>maven-bom</module>
|
<module>maven-bom</module>
|
||||||
|
<module>maven-docgen</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<scm>
|
<scm>
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
|
||||||
|
# Configuration Options
|
||||||
|
<!--
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| No | Key | Type | Description | Default Value | Since | Source |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| 1. | `maven.build.timestamp.format` | `String` | Build timestamp format. | `yyyy-MM-dd'T'HH:mm:ssXXX` | 3.0.0 | Model properties |
|
||||||
|
| 2. | `maven.ext.class.path` | `String` | Extensions class path. | - | | User properties |
|
||||||
|
| 3. | `maven.home` | `String` | Maven home. | - | 3.0.0 | User properties |
|
||||||
|
| 4. | `maven.installation.conf` | `String` | Maven installation configuration directory. | `${maven.home}/conf` | 4.0.0 | User properties |
|
||||||
|
| 5. | `maven.installation.extensions` | `String` | Maven installation extensions. | `${maven.installation.conf}/extensions.xml` | 4.0.0 | User properties |
|
||||||
|
| 6. | `maven.installation.settings` | `String` | Maven installation settings. | `${maven.installation.conf}/settings.xml` | 4.0.0 | User properties |
|
||||||
|
| 7. | `maven.installation.toolchains` | `String` | Maven installation toolchains. | `${maven.installation.conf}/toolchains.xml` | 4.0.0 | User properties |
|
||||||
|
| 8. | `maven.plugin.validation` | `String` | Plugin validation level. | `inline` | 3.9.2 | User properties |
|
||||||
|
| 9. | `maven.plugin.validation.excludes` | `String` | Plugin validation exclusions. | - | 3.9.6 | User properties |
|
||||||
|
| 10. | `maven.project.conf` | `String` | Maven project configuration directory. | `${session.rootDirectory}/.mvn` | 4.0.0 | User properties |
|
||||||
|
| 11. | `maven.project.extensions` | `String` | Maven project extensions. | `${maven.project.conf}/extensions.xml` | 4.0.0 | User properties |
|
||||||
|
| 12. | `maven.project.settings` | `String` | Maven project settings. | `${maven.project.conf}/settings.xml` | 4.0.0 | User properties |
|
||||||
|
| 13. | `maven.projectBuilder.parallelism` | `Integer` | ProjectBuilder parallelism. | `cores/2 + 1` | 4.0.0 | User properties |
|
||||||
|
| 14. | `maven.relocations.entries` | `String` | User controlled relocations. This property is a comma separated list of entries with the syntax <code>GAV>GAV</code>. The first <code>GAV</code> can contain <code>\*</code> for any elem (so <code>\*:\*:\*</code> would mean ALL, something you don't want). The second <code>GAV</code> is either fully specified, or also can contain <code>\*</code>, then it behaves as "ordinary relocation": the coordinate is preserved from relocated artifact. Finally, if right hand <code>GAV</code> is absent (line looks like <code>GAV></code>), the left hand matching <code>GAV</code> is banned fully (from resolving). <br/> Note: the <code>></code> means project level, while <code>>></code> means global (whole session level, so even plugins will get relocated artifacts) relocation. <br/> For example, <pre>maven.relocations.entries = org.foo:\*:\*>, \\<br/> org.here:\*:\*>org.there:\*:\*, \\<br/> javax.inject:javax.inject:1>>jakarta.inject:jakarta.inject:1.0.5</pre> means: 3 entries, ban <code>org.foo group</code> (exactly, so <code>org.foo.bar</code> is allowed), relocate <code>org.here</code> to <code>org.there</code> and finally globally relocate (see <code>>></code> above) <code>javax.inject:javax.inject:1</code> to <code>jakarta.inject:jakarta.inject:1.0.5</code>. | - | 4.0.0 | User properties |
|
||||||
|
| 15. | `maven.repo.local` | `String` | Maven local repository. | `${maven.user.conf}/repository` | 3.0.0 | User properties |
|
||||||
|
| 16. | `maven.repo.local.recordReverseTree` | `String` | User property for reverse dependency tree. If enabled, Maven will record ".tracking" directory into local repository with "reverse dependency tree", essentially explaining WHY given artifact is present in local repository. Default: <code>false</code>, will not record anything. | `false` | 3.9.0 | User properties |
|
||||||
|
| 17. | `maven.repo.local.tail` | `String` | User property for chained LRM: list of "tail" local repository paths (separated by comma), to be used with {@code org.eclipse.aether.util.repository.ChainedLocalRepositoryManager} . Default value: <code>null</code>, no chained LRM is used. | - | 3.9.0 | User properties |
|
||||||
|
| 18. | `maven.resolver.dependencyManagerTransitivity` | `String` | User property for selecting dependency manager behaviour regarding transitive dependencies and dependency management entries in their POMs. Maven 3 targeted full backward compatibility with Maven2, hence it ignored dependency management entries in transitive dependency POMs. Maven 4 enables "transitivity" by default, hence unlike Maven2, obeys dependency management entries deep in dependency graph as well. <br/> Default: <code>"true"</code>. | `true` | 4.0.0 | User properties |
|
||||||
|
| 19. | `maven.resolver.transport` | `String` | Resolver transport to use. Can be <code>default</code>, <code>wagon</code>, <code>apache</code>, <code>jdk</code> or <code>auto</code>. | `default` | 4.0.0 | User properties |
|
||||||
|
| 20. | `maven.style.color` | `String` | Maven output color mode. Allowed values are <code>auto</code>, <code>always</code>, <code>never</code>. | `auto` | 4.0.0 | User properties |
|
||||||
|
| 21. | `maven.user.conf` | `String` | Maven user configuration directory. | `${user.home}/.m2` | 4.0.0 | User properties |
|
||||||
|
| 22. | `maven.user.extensions` | `String` | Maven user extensions. | `${maven.user.conf}/extensions.xml` | 4.0.0 | User properties |
|
||||||
|
| 23. | `maven.user.settings` | `String` | Maven user settings. | `${maven.user.conf}/settings.xml` | 4.0.0 | User properties |
|
||||||
|
| 24. | `maven.user.toolchains` | `String` | Maven user toolchains. | `${maven.user.home}/toolchains.xml` | 4.0.0 | User properties |
|
||||||
|
| 25. | `maven.versionFilters` | `String` | User property for version filters expression, a semicolon separated list of filters to apply. By default, no version filter is applied (like in Maven 3). <br/> Supported filters: <ul> <li>"h" or "h(num)" - highest version or top list of highest ones filter</li> <li>"l" or "l(num)" - lowest version or bottom list of lowest ones filter</li> <li>"s" - contextual snapshot filter</li> <li>"e(G:A:V)" - predicate filter (leaves out G:A:V from range, if hit, V can be range)</li> </ul> Example filter expression: <code>"h(5);s;e(org.foo:bar:1)</code> will cause: ranges are filtered for "top 5" (instead full range), snapshots are banned if root project is not a snapshot, and if range for <code>org.foo:bar</code> is being processed, version 1 is omitted. | - | 4.0.0 | User properties |
|
||||||
|
|
Loading…
Reference in New Issue