mirror of https://github.com/apache/maven.git
[MNG-8402] System properties can take precedence over builtin expressions (#1947)
This commit is contained in:
parent
794efae428
commit
73e30c5d6f
|
@ -176,7 +176,6 @@ under the License.
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.jimfs</groupId>
|
<groupId>com.google.jimfs</groupId>
|
||||||
<artifactId>jimfs</artifactId>
|
<artifactId>jimfs</artifactId>
|
||||||
<version>1.3.0</version>
|
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
|
@ -92,7 +92,6 @@ under the License.
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.jimfs</groupId>
|
<groupId>com.google.jimfs</groupId>
|
||||||
<artifactId>jimfs</artifactId>
|
<artifactId>jimfs</artifactId>
|
||||||
<version>1.3.0</version>
|
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -164,6 +164,11 @@ under the License.
|
||||||
<artifactId>maven-resolver-transport-apache</artifactId>
|
<artifactId>maven-resolver-transport-apache</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.jimfs</groupId>
|
||||||
|
<artifactId>jimfs</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -184,8 +184,12 @@ public class DefaultModelInterpolator implements ModelInterpolator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// un-prefixed model reflection
|
||||||
|
String value = projectProperty(model, projectDir, expression, false);
|
||||||
// user properties
|
// user properties
|
||||||
String value = request.getUserProperties().get(expression);
|
if (value == null) {
|
||||||
|
value = request.getUserProperties().get(expression);
|
||||||
|
}
|
||||||
// model properties
|
// model properties
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
value = model.getProperties().get(expression);
|
value = model.getProperties().get(expression);
|
||||||
|
@ -198,12 +202,8 @@ public class DefaultModelInterpolator implements ModelInterpolator {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
value = request.getSystemProperties().get("env." + expression);
|
value = request.getSystemProperties().get("env." + expression);
|
||||||
}
|
}
|
||||||
if (value != null) {
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
// model reflection
|
|
||||||
return projectProperty(model, projectDir, expression, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
String projectProperty(Model model, Path projectDir, String subExpr, boolean prefixed) {
|
String projectProperty(Model model, Path projectDir, String subExpr, boolean prefixed) {
|
||||||
if (projectDir != null) {
|
if (projectDir != null) {
|
||||||
|
@ -223,7 +223,7 @@ public class DefaultModelInterpolator implements ModelInterpolator {
|
||||||
} else if (prefixed && subExpr.startsWith("baseUri.")) {
|
} else if (prefixed && subExpr.startsWith("baseUri.")) {
|
||||||
try {
|
try {
|
||||||
Object value = ReflectionValueExtractor.evaluate(
|
Object value = ReflectionValueExtractor.evaluate(
|
||||||
subExpr, projectDir.toAbsolutePath().toUri(), false);
|
subExpr, projectDir.toAbsolutePath().toUri(), true);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
return value.toString();
|
return value.toString();
|
||||||
}
|
}
|
||||||
|
@ -234,8 +234,8 @@ public class DefaultModelInterpolator implements ModelInterpolator {
|
||||||
return rootLocator.findMandatoryRoot(projectDir).toString();
|
return rootLocator.findMandatoryRoot(projectDir).toString();
|
||||||
} else if (prefixed && subExpr.startsWith("rootDirectory.")) {
|
} else if (prefixed && subExpr.startsWith("rootDirectory.")) {
|
||||||
try {
|
try {
|
||||||
Object value = ReflectionValueExtractor.evaluate(
|
Object value =
|
||||||
subExpr, projectDir.toAbsolutePath().toUri(), false);
|
ReflectionValueExtractor.evaluate(subExpr, rootLocator.findMandatoryRoot(projectDir), true);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
return value.toString();
|
return value.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,606 @@
|
||||||
|
/*
|
||||||
|
* 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.internal.impl.model;
|
||||||
|
|
||||||
|
import java.nio.file.FileSystem;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import com.google.common.jimfs.Configuration;
|
||||||
|
import com.google.common.jimfs.Jimfs;
|
||||||
|
import org.apache.maven.api.Session;
|
||||||
|
import org.apache.maven.api.di.Priority;
|
||||||
|
import org.apache.maven.api.di.Provides;
|
||||||
|
import org.apache.maven.api.model.Build;
|
||||||
|
import org.apache.maven.api.model.Dependency;
|
||||||
|
import org.apache.maven.api.model.Model;
|
||||||
|
import org.apache.maven.api.model.Organization;
|
||||||
|
import org.apache.maven.api.model.Repository;
|
||||||
|
import org.apache.maven.api.model.Resource;
|
||||||
|
import org.apache.maven.api.model.Scm;
|
||||||
|
import org.apache.maven.api.services.Lookup;
|
||||||
|
import org.apache.maven.api.services.ModelBuilderRequest;
|
||||||
|
import org.apache.maven.api.services.model.ModelInterpolator;
|
||||||
|
import org.apache.maven.api.services.model.RootLocator;
|
||||||
|
import org.apache.maven.internal.impl.model.profile.SimpleProblemCollector;
|
||||||
|
import org.apache.maven.internal.impl.standalone.ApiRunner;
|
||||||
|
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.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
class DefaultModelInterpolatorTest {
|
||||||
|
|
||||||
|
Map<String, String> context;
|
||||||
|
ModelInterpolator interpolator;
|
||||||
|
Session session;
|
||||||
|
AtomicReference<Path> rootDirectory; // used in TestRootLocator below
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
context = new HashMap<>();
|
||||||
|
context.put("basedir", "myBasedir");
|
||||||
|
context.put("anotherdir", "anotherBasedir");
|
||||||
|
context.put("project.baseUri", "myBaseUri");
|
||||||
|
|
||||||
|
session = ApiRunner.createSession(injector -> {
|
||||||
|
injector.bindInstance(DefaultModelInterpolatorTest.class, this);
|
||||||
|
});
|
||||||
|
interpolator = session.getService(Lookup.class).lookup(DefaultModelInterpolator.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void assertProblemFree(SimpleProblemCollector collector) {
|
||||||
|
assertEquals(0, collector.getErrors().size(), "Expected no errors");
|
||||||
|
assertEquals(0, collector.getWarnings().size(), "Expected no warnings");
|
||||||
|
assertEquals(0, collector.getFatals().size(), "Expected no fatals");
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("SameParameterValue")
|
||||||
|
protected void assertCollectorState(
|
||||||
|
int numFatals, int numErrors, int numWarnings, SimpleProblemCollector collector) {
|
||||||
|
assertEquals(numErrors, collector.getErrors().size(), "Errors");
|
||||||
|
assertEquals(numWarnings, collector.getWarnings().size(), "Warnings");
|
||||||
|
assertEquals(numFatals, collector.getFatals().size(), "Fatals");
|
||||||
|
}
|
||||||
|
|
||||||
|
private ModelBuilderRequest.ModelBuilderRequestBuilder createModelBuildingRequest(Map<String, String> p) {
|
||||||
|
ModelBuilderRequest.ModelBuilderRequestBuilder config = ModelBuilderRequest.builder()
|
||||||
|
.session(session)
|
||||||
|
.requestType(ModelBuilderRequest.RequestType.BUILD_PROJECT);
|
||||||
|
if (p != null) {
|
||||||
|
config.systemProperties(p);
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultBuildTimestampFormatShouldFormatTimeIn24HourFormat() {
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTimeZone(MavenBuildTimestamp.DEFAULT_BUILD_TIME_ZONE);
|
||||||
|
cal.set(Calendar.HOUR, 12);
|
||||||
|
cal.set(Calendar.AM_PM, Calendar.AM);
|
||||||
|
|
||||||
|
// just to make sure all the bases are covered...
|
||||||
|
cal.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
|
cal.set(Calendar.MINUTE, 16);
|
||||||
|
cal.set(Calendar.SECOND, 0);
|
||||||
|
cal.set(Calendar.YEAR, 1976);
|
||||||
|
cal.set(Calendar.MONTH, Calendar.NOVEMBER);
|
||||||
|
cal.set(Calendar.DATE, 11);
|
||||||
|
|
||||||
|
Date firstTestDate = cal.getTime();
|
||||||
|
|
||||||
|
cal.set(Calendar.HOUR, 11);
|
||||||
|
cal.set(Calendar.AM_PM, Calendar.PM);
|
||||||
|
|
||||||
|
// just to make sure all the bases are covered...
|
||||||
|
cal.set(Calendar.HOUR_OF_DAY, 23);
|
||||||
|
|
||||||
|
Date secondTestDate = cal.getTime();
|
||||||
|
|
||||||
|
SimpleDateFormat format = new SimpleDateFormat(MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT);
|
||||||
|
format.setTimeZone(MavenBuildTimestamp.DEFAULT_BUILD_TIME_ZONE);
|
||||||
|
assertEquals("1976-11-11T00:16:00Z", format.format(firstTestDate));
|
||||||
|
assertEquals("1976-11-11T23:16:00Z", format.format(secondTestDate));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultBuildTimestampFormatWithLocalTimeZoneMidnightRollover() {
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
|
||||||
|
|
||||||
|
cal.set(Calendar.HOUR_OF_DAY, 1);
|
||||||
|
cal.set(Calendar.MINUTE, 16);
|
||||||
|
cal.set(Calendar.SECOND, 0);
|
||||||
|
cal.set(Calendar.YEAR, 2014);
|
||||||
|
cal.set(Calendar.MONTH, Calendar.JUNE);
|
||||||
|
cal.set(Calendar.DATE, 16);
|
||||||
|
|
||||||
|
Date firstTestDate = cal.getTime();
|
||||||
|
|
||||||
|
cal.set(Calendar.MONTH, Calendar.NOVEMBER);
|
||||||
|
|
||||||
|
Date secondTestDate = cal.getTime();
|
||||||
|
|
||||||
|
SimpleDateFormat format = new SimpleDateFormat(MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT);
|
||||||
|
format.setTimeZone(MavenBuildTimestamp.DEFAULT_BUILD_TIME_ZONE);
|
||||||
|
assertEquals("2014-06-15T23:16:00Z", format.format(firstTestDate));
|
||||||
|
assertEquals("2014-11-16T00:16:00Z", format.format(secondTestDate));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShouldNotThrowExceptionOnReferenceToNonExistentValue() throws Exception {
|
||||||
|
Scm scm = Scm.newBuilder().connection("${test}/somepath").build();
|
||||||
|
Model model = Model.newBuilder().scm(scm).build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model, Paths.get("."), createModelBuildingRequest(context).build(), collector);
|
||||||
|
|
||||||
|
assertProblemFree(collector);
|
||||||
|
assertEquals("${test}/somepath", out.getScm().getConnection());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShouldThrowExceptionOnRecursiveScmConnectionReference() throws Exception {
|
||||||
|
Scm scm = Scm.newBuilder()
|
||||||
|
.connection("${project.scm.connection}/somepath")
|
||||||
|
.build();
|
||||||
|
Model model = Model.newBuilder().scm(scm).build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
interpolator.interpolateModel(
|
||||||
|
model, (Path) null, createModelBuildingRequest(context).build(), collector);
|
||||||
|
assertCollectorState(0, 1, 0, collector);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShouldNotThrowExceptionOnReferenceToValueContainingNakedExpression() throws Exception {
|
||||||
|
Scm scm = Scm.newBuilder().connection("${test}/somepath").build();
|
||||||
|
Map<String, String> props = new HashMap<>();
|
||||||
|
props.put("test", "test");
|
||||||
|
Model model = Model.newBuilder().scm(scm).properties(props).build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model, Paths.get("."), createModelBuildingRequest(context).build(), collector);
|
||||||
|
|
||||||
|
assertProblemFree(collector);
|
||||||
|
|
||||||
|
assertEquals("test/somepath", out.getScm().getConnection());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldInterpolateOrganizationNameCorrectly() throws Exception {
|
||||||
|
String orgName = "MyCo";
|
||||||
|
|
||||||
|
Model model = Model.newBuilder()
|
||||||
|
.name("${project.organization.name} Tools")
|
||||||
|
.organization(Organization.newBuilder().name(orgName).build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model, Paths.get("."), createModelBuildingRequest(context).build(), new SimpleProblemCollector());
|
||||||
|
|
||||||
|
assertEquals(orgName + " Tools", out.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldInterpolateDependencyVersionToSetSameAsProjectVersion() throws Exception {
|
||||||
|
Model model = Model.newBuilder()
|
||||||
|
.version("3.8.1")
|
||||||
|
.dependencies(Collections.singletonList(
|
||||||
|
Dependency.newBuilder().version("${project.version}").build()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model, Paths.get("."), createModelBuildingRequest(context).build(), collector);
|
||||||
|
assertCollectorState(0, 0, 0, collector);
|
||||||
|
|
||||||
|
assertEquals("3.8.1", (out.getDependencies().get(0)).getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShouldNotInterpolateDependencyVersionWithInvalidReference() throws Exception {
|
||||||
|
Model model = Model.newBuilder()
|
||||||
|
.version("3.8.1")
|
||||||
|
.dependencies(Collections.singletonList(
|
||||||
|
Dependency.newBuilder().version("${something}").build()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
/*
|
||||||
|
// This is the desired behaviour, however there are too many crappy poms in the repo and an issue with the
|
||||||
|
// timing of executing the interpolation
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
new RegexBasedModelInterpolator().interpolate( model, context );
|
||||||
|
fail( "Should have failed to interpolate with invalid reference" );
|
||||||
|
}
|
||||||
|
catch ( ModelInterpolationException expected )
|
||||||
|
{
|
||||||
|
assertTrue( true );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model, Paths.get("."), createModelBuildingRequest(context).build(), collector);
|
||||||
|
assertProblemFree(collector);
|
||||||
|
|
||||||
|
assertEquals("${something}", (out.getDependencies().get(0)).getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTwoReferences() throws Exception {
|
||||||
|
Model model = Model.newBuilder()
|
||||||
|
.version("3.8.1")
|
||||||
|
.artifactId("foo")
|
||||||
|
.dependencies(Collections.singletonList(Dependency.newBuilder()
|
||||||
|
.version("${project.artifactId}-${project.version}")
|
||||||
|
.build()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model, Paths.get("."), createModelBuildingRequest(context).build(), collector);
|
||||||
|
assertCollectorState(0, 0, 0, collector);
|
||||||
|
|
||||||
|
assertEquals("foo-3.8.1", (out.getDependencies().get(0)).getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProperty() throws Exception {
|
||||||
|
Model model = Model.newBuilder()
|
||||||
|
.version("3.8.1")
|
||||||
|
.artifactId("foo")
|
||||||
|
.repositories(Collections.singletonList(Repository.newBuilder()
|
||||||
|
.url("file://localhost/${anotherdir}/temp-repo")
|
||||||
|
.build()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model,
|
||||||
|
Paths.get("projectBasedir"),
|
||||||
|
createModelBuildingRequest(context).build(),
|
||||||
|
collector);
|
||||||
|
assertProblemFree(collector);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
"file://localhost/anotherBasedir/temp-repo",
|
||||||
|
(out.getRepositories().get(0)).getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBasedirUnx() throws Exception {
|
||||||
|
FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
|
||||||
|
Path projectBasedir = fs.getPath("projectBasedir");
|
||||||
|
|
||||||
|
Model model = Model.newBuilder()
|
||||||
|
.version("3.8.1")
|
||||||
|
.artifactId("foo")
|
||||||
|
.repositories(Collections.singletonList(
|
||||||
|
Repository.newBuilder().url("${basedir}/temp-repo").build()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model, projectBasedir, createModelBuildingRequest(context).build(), collector);
|
||||||
|
assertProblemFree(collector);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
projectBasedir.toAbsolutePath() + "/temp-repo",
|
||||||
|
(out.getRepositories().get(0)).getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBasedirWin() throws Exception {
|
||||||
|
FileSystem fs = Jimfs.newFileSystem(Configuration.windows());
|
||||||
|
Path projectBasedir = fs.getPath("projectBasedir");
|
||||||
|
|
||||||
|
Model model = Model.newBuilder()
|
||||||
|
.version("3.8.1")
|
||||||
|
.artifactId("foo")
|
||||||
|
.repositories(Collections.singletonList(
|
||||||
|
Repository.newBuilder().url("${basedir}/temp-repo").build()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model, projectBasedir, createModelBuildingRequest(context).build(), collector);
|
||||||
|
assertProblemFree(collector);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
projectBasedir.toAbsolutePath() + "/temp-repo",
|
||||||
|
(out.getRepositories().get(0)).getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBaseUri() throws Exception {
|
||||||
|
Path projectBasedir = Paths.get("projectBasedir");
|
||||||
|
|
||||||
|
Model model = Model.newBuilder()
|
||||||
|
.version("3.8.1")
|
||||||
|
.artifactId("foo")
|
||||||
|
.repositories(Collections.singletonList(Repository.newBuilder()
|
||||||
|
.url("${project.baseUri}/temp-repo")
|
||||||
|
.build()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model, projectBasedir, createModelBuildingRequest(context).build(), collector);
|
||||||
|
assertProblemFree(collector);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
projectBasedir.resolve("temp-repo").toUri().toString(),
|
||||||
|
(out.getRepositories().get(0)).getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRootDirectory() throws Exception {
|
||||||
|
Path rootDirectory = Paths.get("myRootDirectory");
|
||||||
|
|
||||||
|
Model model = Model.newBuilder()
|
||||||
|
.version("3.8.1")
|
||||||
|
.artifactId("foo")
|
||||||
|
.repositories(Collections.singletonList(Repository.newBuilder()
|
||||||
|
.url("file:${project.rootDirectory}/temp-repo")
|
||||||
|
.build()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model, rootDirectory, createModelBuildingRequest(context).build(), collector);
|
||||||
|
assertProblemFree(collector);
|
||||||
|
|
||||||
|
assertEquals("file:myRootDirectory/temp-repo", (out.getRepositories().get(0)).getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRootDirectoryWithUri() throws Exception {
|
||||||
|
Path rootDirectory = Paths.get("myRootDirectory");
|
||||||
|
|
||||||
|
Model model = Model.newBuilder()
|
||||||
|
.version("3.8.1")
|
||||||
|
.artifactId("foo")
|
||||||
|
.repositories(Collections.singletonList(Repository.newBuilder()
|
||||||
|
.url("${project.rootDirectory.uri}/temp-repo")
|
||||||
|
.build()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model, rootDirectory, createModelBuildingRequest(context).build(), collector);
|
||||||
|
assertProblemFree(collector);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
rootDirectory.resolve("temp-repo").toUri().toString(),
|
||||||
|
(out.getRepositories().get(0)).getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRootDirectoryWithNull() throws Exception {
|
||||||
|
Path projectDirectory = Paths.get("myProjectDirectory");
|
||||||
|
this.rootDirectory = new AtomicReference<>(null);
|
||||||
|
|
||||||
|
Model model = Model.newBuilder()
|
||||||
|
.version("3.8.1")
|
||||||
|
.artifactId("foo")
|
||||||
|
.repositories(Collections.singletonList(Repository.newBuilder()
|
||||||
|
.url("file:///${project.rootDirectory}/temp-repo")
|
||||||
|
.build()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
IllegalStateException e = assertThrows(
|
||||||
|
IllegalStateException.class,
|
||||||
|
() -> interpolator.interpolateModel(
|
||||||
|
model,
|
||||||
|
projectDirectory,
|
||||||
|
createModelBuildingRequest(context).build(),
|
||||||
|
collector));
|
||||||
|
|
||||||
|
assertEquals(RootLocator.UNABLE_TO_FIND_ROOT_PROJECT_MESSAGE, e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEnvars() throws Exception {
|
||||||
|
context.put("env.HOME", "/path/to/home");
|
||||||
|
|
||||||
|
Map<String, String> modelProperties = new HashMap<>();
|
||||||
|
modelProperties.put("outputDirectory", "${env.HOME}");
|
||||||
|
|
||||||
|
Model model = Model.newBuilder().properties(modelProperties).build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model, Paths.get("."), createModelBuildingRequest(context).build(), collector);
|
||||||
|
assertProblemFree(collector);
|
||||||
|
|
||||||
|
assertEquals("/path/to/home", out.getProperties().get("outputDirectory"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void envarExpressionThatEvaluatesToNullReturnsTheLiteralString() throws Exception {
|
||||||
|
|
||||||
|
Map<String, String> modelProperties = new HashMap<>();
|
||||||
|
modelProperties.put("outputDirectory", "${env.DOES_NOT_EXIST}");
|
||||||
|
|
||||||
|
Model model = Model.newBuilder().properties(modelProperties).build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model, Paths.get("."), createModelBuildingRequest(context).build(), collector);
|
||||||
|
assertProblemFree(collector);
|
||||||
|
|
||||||
|
assertEquals(out.getProperties().get("outputDirectory"), "${env.DOES_NOT_EXIST}");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void expressionThatEvaluatesToNullReturnsTheLiteralString() throws Exception {
|
||||||
|
Map<String, String> modelProperties = new HashMap<>();
|
||||||
|
modelProperties.put("outputDirectory", "${DOES_NOT_EXIST}");
|
||||||
|
|
||||||
|
Model model = Model.newBuilder().properties(modelProperties).build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model, Paths.get("."), createModelBuildingRequest(context).build(), collector);
|
||||||
|
assertProblemFree(collector);
|
||||||
|
|
||||||
|
assertEquals("${DOES_NOT_EXIST}", out.getProperties().get("outputDirectory"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldInterpolateSourceDirectoryReferencedFromResourceDirectoryCorrectly() throws Exception {
|
||||||
|
Model model = Model.newBuilder()
|
||||||
|
.build(Build.newBuilder()
|
||||||
|
.sourceDirectory("correct")
|
||||||
|
.resources(List.of(Resource.newBuilder()
|
||||||
|
.directory("${project.build.sourceDirectory}")
|
||||||
|
.build()))
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model, (Path) null, createModelBuildingRequest(context).build(), collector);
|
||||||
|
assertCollectorState(0, 0, 0, collector);
|
||||||
|
|
||||||
|
List<Resource> outResources = out.getBuild().getResources();
|
||||||
|
Iterator<Resource> resIt = outResources.iterator();
|
||||||
|
|
||||||
|
assertEquals(model.getBuild().getSourceDirectory(), resIt.next().getDirectory());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldInterpolateUnprefixedBasedirExpression() throws Exception {
|
||||||
|
Path basedir = Paths.get("/test/path");
|
||||||
|
Model model = Model.newBuilder()
|
||||||
|
.dependencies(Collections.singletonList(Dependency.newBuilder()
|
||||||
|
.systemPath("${basedir}/artifact.jar")
|
||||||
|
.build()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model result = interpolator.interpolateModel(
|
||||||
|
model, basedir, createModelBuildingRequest(context).build(), collector);
|
||||||
|
assertProblemFree(collector);
|
||||||
|
|
||||||
|
List<Dependency> rDeps = result.getDependencies();
|
||||||
|
assertNotNull(rDeps);
|
||||||
|
assertEquals(1, rDeps.size());
|
||||||
|
assertEquals(
|
||||||
|
basedir.resolve("artifact.jar").toAbsolutePath(),
|
||||||
|
Paths.get(rDeps.get(0).getSystemPath()).toAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRecursiveExpressionCycleNPE() throws Exception {
|
||||||
|
Map<String, String> props = new HashMap<>();
|
||||||
|
props.put("aa", "${bb}");
|
||||||
|
props.put("bb", "${aa}");
|
||||||
|
|
||||||
|
Model model = Model.newBuilder().properties(props).build();
|
||||||
|
|
||||||
|
SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
|
||||||
|
ModelBuilderRequest request = createModelBuildingRequest(Map.of()).build();
|
||||||
|
interpolator.interpolateModel(model, null, request, collector);
|
||||||
|
|
||||||
|
assertCollectorState(0, 2, 0, collector);
|
||||||
|
assertTrue(collector.getErrors().get(0).contains("recursive variable reference"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRecursiveExpressionCycleBaseDir() throws Exception {
|
||||||
|
Map<String, String> props = new HashMap<>();
|
||||||
|
props.put("basedir", "${basedir}");
|
||||||
|
ModelBuilderRequest request = createModelBuildingRequest(Map.of()).build();
|
||||||
|
|
||||||
|
Model model = Model.newBuilder().properties(props).build();
|
||||||
|
|
||||||
|
SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
ModelInterpolator interpolator = this.interpolator;
|
||||||
|
interpolator.interpolateModel(model, null, request, collector);
|
||||||
|
|
||||||
|
assertCollectorState(0, 1, 0, collector);
|
||||||
|
assertEquals(
|
||||||
|
"recursive variable reference: basedir", collector.getErrors().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldIgnorePropertiesWithPomPrefix() throws Exception {
|
||||||
|
final String orgName = "MyCo";
|
||||||
|
final String uninterpolatedName = "${pom.organization.name} Tools";
|
||||||
|
|
||||||
|
Model model = Model.newBuilder()
|
||||||
|
.name(uninterpolatedName)
|
||||||
|
.organization(Organization.newBuilder().name(orgName).build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||||
|
Model out = interpolator.interpolateModel(
|
||||||
|
model,
|
||||||
|
null,
|
||||||
|
createModelBuildingRequest(context).build(),
|
||||||
|
// .validationLevel(ModelBuilderRequest.VALIDATION_LEVEL_MAVEN_4_0),
|
||||||
|
collector);
|
||||||
|
|
||||||
|
assertCollectorState(0, 0, 0, collector);
|
||||||
|
assertEquals(uninterpolatedName, out.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Priority(10)
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
RootLocator testRootLocator() {
|
||||||
|
return new RootLocator() {
|
||||||
|
@Override
|
||||||
|
public Path findRoot(Path basedir) {
|
||||||
|
return rootDirectory != null ? rootDirectory.get() : basedir;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Path findMandatoryRoot(Path basedir) {
|
||||||
|
return Optional.ofNullable(findRoot(basedir))
|
||||||
|
.orElseThrow(() -> new IllegalStateException(getNoRootMessage()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* 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.internal.impl.model;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
class MavenBuildTimestampTest {
|
||||||
|
@Test
|
||||||
|
void testMavenBuildTimestampUsesUTC() {
|
||||||
|
Map<String, String> interpolationProperties = new HashMap<>();
|
||||||
|
interpolationProperties.put("maven.build.timestamp.format", "yyyyMMdd'T'HHmm'Z'");
|
||||||
|
MavenBuildTimestamp timestamp = new MavenBuildTimestamp(Instant.now(), interpolationProperties);
|
||||||
|
String formattedTimestamp = timestamp.formattedTimestamp();
|
||||||
|
assertTrue(formattedTimestamp.endsWith("Z"), "We expect the UTC marker at the end of the timestamp.");
|
||||||
|
}
|
||||||
|
}
|
|
@ -105,17 +105,22 @@ public class SimpleProblemCollector implements ModelProblemCollector {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getFatals() {
|
||||||
|
return getForLevel(ModelProblem.Severity.FATAL);
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> getErrors() {
|
public List<String> getErrors() {
|
||||||
return problems.stream()
|
return getForLevel(ModelProblem.Severity.ERROR);
|
||||||
.filter(p -> p.getSeverity() == ModelProblem.Severity.ERROR)
|
|
||||||
.map(p -> p.getMessage())
|
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getWarnings() {
|
public List<String> getWarnings() {
|
||||||
|
return getForLevel(ModelProblem.Severity.WARNING);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> getForLevel(BuilderProblem.Severity severity) {
|
||||||
return problems.stream()
|
return problems.stream()
|
||||||
.filter(p -> p.getSeverity() == ModelProblem.Severity.WARNING)
|
.filter(p -> p.getSeverity() == severity)
|
||||||
.map(p -> p.getMessage())
|
.map(BuilderProblem::getMessage)
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.maven.api.Artifact;
|
import org.apache.maven.api.Artifact;
|
||||||
|
@ -64,7 +65,6 @@ import org.apache.maven.internal.impl.resolver.scopes.Maven4ScopeManagerConfigur
|
||||||
import org.eclipse.aether.DefaultRepositorySystemSession;
|
import org.eclipse.aether.DefaultRepositorySystemSession;
|
||||||
import org.eclipse.aether.RepositorySystem;
|
import org.eclipse.aether.RepositorySystem;
|
||||||
import org.eclipse.aether.RepositorySystemSession;
|
import org.eclipse.aether.RepositorySystemSession;
|
||||||
import org.eclipse.aether.impl.RemoteRepositoryManager;
|
|
||||||
import org.eclipse.aether.internal.impl.scope.ScopeManagerImpl;
|
import org.eclipse.aether.internal.impl.scope.ScopeManagerImpl;
|
||||||
import org.eclipse.aether.repository.LocalRepository;
|
import org.eclipse.aether.repository.LocalRepository;
|
||||||
import org.eclipse.aether.repository.LocalRepositoryManager;
|
import org.eclipse.aether.repository.LocalRepositoryManager;
|
||||||
|
@ -75,10 +75,21 @@ public class ApiRunner {
|
||||||
* Create a new session.
|
* Create a new session.
|
||||||
*/
|
*/
|
||||||
public static Session createSession() {
|
public static Session createSession() {
|
||||||
|
return createSession(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new session.
|
||||||
|
*/
|
||||||
|
public static Session createSession(Consumer<Injector> injectorConsumer) {
|
||||||
Injector injector = Injector.create();
|
Injector injector = Injector.create();
|
||||||
injector.bindInstance(Injector.class, injector);
|
injector.bindInstance(Injector.class, injector);
|
||||||
injector.bindImplicit(ApiRunner.class);
|
injector.bindImplicit(ApiRunner.class);
|
||||||
|
injector.bindImplicit(RepositorySystemSupplier.class);
|
||||||
injector.discover(ApiRunner.class.getClassLoader());
|
injector.discover(ApiRunner.class.getClassLoader());
|
||||||
|
if (injectorConsumer != null) {
|
||||||
|
injectorConsumer.accept(injector);
|
||||||
|
}
|
||||||
Session session = injector.getInstance(Session.class);
|
Session session = injector.getInstance(Session.class);
|
||||||
SessionScope scope = new SessionScope();
|
SessionScope scope = new SessionScope();
|
||||||
scope.enter();
|
scope.enter();
|
||||||
|
@ -286,24 +297,6 @@ public class ApiRunner {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
static RepositorySystemSupplier newRepositorySystemSupplier() {
|
|
||||||
return new RepositorySystemSupplier();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
static RepositorySystem newRepositorySystem(RepositorySystemSupplier repositorySystemSupplier) {
|
|
||||||
return repositorySystemSupplier.getRepositorySystem();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
static RemoteRepositoryManager newRemoteRepositoryManager(RepositorySystemSupplier repositorySystemSupplier) {
|
|
||||||
return repositorySystemSupplier.getRemoteRepositoryManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
static Session newSession(RepositorySystem system, Lookup lookup) {
|
static Session newSession(RepositorySystem system, Lookup lookup) {
|
||||||
|
@ -313,6 +306,10 @@ public class ApiRunner {
|
||||||
// Java System properties
|
// Java System properties
|
||||||
System.getProperties().forEach((k, v) -> properties.put(k.toString(), v.toString()));
|
System.getProperties().forEach((k, v) -> properties.put(k.toString(), v.toString()));
|
||||||
|
|
||||||
|
// Do not allow user settings to interfere with our unit tests
|
||||||
|
// TODO: remove that when this go more public
|
||||||
|
properties.put("user.home", "target");
|
||||||
|
|
||||||
// SettingsDecrypter settingsDecrypter =
|
// SettingsDecrypter settingsDecrypter =
|
||||||
// (SettingsDecrypter)Objects.requireNonNull(this.createSettingsDecrypter(preBoot));
|
// (SettingsDecrypter)Objects.requireNonNull(this.createSettingsDecrypter(preBoot));
|
||||||
// new DefaultProfileSelector(List.of(
|
// new DefaultProfileSelector(List.of(
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
5
pom.xml
5
pom.xml
|
@ -648,6 +648,11 @@ under the License.
|
||||||
<artifactId>byte-buddy</artifactId>
|
<artifactId>byte-buddy</artifactId>
|
||||||
<version>${byteBuddyVersion}</version>
|
<version>${byteBuddyVersion}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.jimfs</groupId>
|
||||||
|
<artifactId>jimfs</artifactId>
|
||||||
|
<version>1.3.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<!--bootstrap-start-comment-->
|
<!--bootstrap-start-comment-->
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
Loading…
Reference in New Issue