Commit 5e743fb2 authored by Andy Wilkinson's avatar Andy Wilkinson

Fully honour local repository location configured in settings.xml

Previously, DefaultRepositorySystemSessionAutoConfiguration would
read the local repository configuration from settings.xml, but did
not perform any property interpolation. This would leave placeholders
such as ${user.home} as-is and result in the use of the wrong
location. To address this, the code that reads settings.xml has been
updated to provide the current System properties as a property
interpolation source.

RepositoryConfigurationFactory configures the local repository as a
"remote" repository when the local repository location has been
overridden. This allows spring grab to copy dependencies from the
local repository into the grab output location (configured via the
grape.root system property) rather than having to download them again.
This logic did not consider the customization of the local repository
location via settings.xml so the dependencies would be downloaded again.
To address this, RepositoryConfigurationFactory has been updated to
attempt to use the location configured in settings.xml, before falling
back to the default location.

The logic that reads settings.xml has deliberately been duplicated. It
could have been extracted into a separate class, but this is only a
temporary measure until gh-3275 is tackled. Duplication was deemed
preferable to adding a new public class in 1.2.x that we’d then want to
remove in 1.3.

Closes gh-3274
parent bbb0b7a8
......@@ -21,6 +21,11 @@ import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.building.DefaultSettingsBuilderFactory;
import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
import org.apache.maven.settings.building.SettingsBuildingException;
import org.apache.maven.settings.building.SettingsBuildingRequest;
import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration;
import org.springframework.util.StringUtils;
......@@ -66,12 +71,35 @@ public final class RepositoryConfigurationFactory {
public static void addDefaultCacheAsRespository(
List<RepositoryConfiguration> repositoryConfiguration) {
RepositoryConfiguration repository = new RepositoryConfiguration("local",
new File(getM2HomeDirectory(), "repository").toURI(), true);
getLocalRepositoryDirectory().toURI(), true);
if (!repositoryConfiguration.contains(repository)) {
repositoryConfiguration.add(0, repository);
}
}
private static File getLocalRepositoryDirectory() {
String localRepository = loadSettings().getLocalRepository();
if (StringUtils.hasText(localRepository)) {
return new File(localRepository);
}
return new File(getM2HomeDirectory(), "repository");
}
private static Settings loadSettings() {
File settingsFile = new File(System.getProperty("user.home"), ".m2/settings.xml");
SettingsBuildingRequest request = new DefaultSettingsBuildingRequest();
request.setUserSettingsFile(settingsFile);
request.setSystemProperties(System.getProperties());
try {
return new DefaultSettingsBuilderFactory().newInstance().build(request)
.getEffectiveSettings();
}
catch (SettingsBuildingException ex) {
throw new IllegalStateException("Failed to build settings from "
+ settingsFile, ex);
}
}
private static File getM2HomeDirectory() {
String mavenRoot = System.getProperty("maven.home");
if (StringUtils.hasLength(mavenRoot)) {
......
......@@ -57,15 +57,7 @@ public class DefaultRepositorySystemSessionAutoConfiguration implements
}
private File getM2RepoDirectory() {
return new File(getM2HomeDirectory(), "repository");
}
private File getM2HomeDirectory() {
String grapeRoot = System.getProperty("grape.root");
if (StringUtils.hasLength(grapeRoot)) {
return new File(grapeRoot);
}
return getDefaultM2HomeDirectory();
return new File(getDefaultM2HomeDirectory(), "repository");
}
private File getDefaultM2HomeDirectory() {
......
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed 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.springframework.boot.cli.compiler.grape;
import java.io.File;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.LocalRepositoryManager;
import org.springframework.util.StringUtils;
/**
* Honours the configuration of {@code grape.root} by customizing the session's local
* repository location.
*
* @author Andy Wilkinson
* @since 1.2.5
*/
public class GrapeRootRepositorySystemSessionAutoConfiguration implements
RepositorySystemSessionAutoConfiguration {
@Override
public void apply(DefaultRepositorySystemSession session,
RepositorySystem repositorySystem) {
String grapeRoot = System.getProperty("grape.root");
if (StringUtils.hasLength(grapeRoot)) {
configureLocalRepository(session, repositorySystem, grapeRoot);
}
}
private void configureLocalRepository(DefaultRepositorySystemSession session,
RepositorySystem repositorySystem, String grapeRoot) {
File repositoryDir = new File(grapeRoot, "repository");
LocalRepository localRepository = new LocalRepository(repositoryDir);
LocalRepositoryManager localRepositoryManager = repositorySystem
.newLocalRepositoryManager(session, localRepository);
session.setLocalRepositoryManager(localRepositoryManager);
}
}
......@@ -96,6 +96,7 @@ public class SettingsXmlRepositorySystemSessionAutoConfiguration implements
File settingsFile = new File(this.homeDir, ".m2/settings.xml");
SettingsBuildingRequest request = new DefaultSettingsBuildingRequest();
request.setUserSettingsFile(settingsFile);
request.setSystemProperties(System.getProperties());
try {
return new DefaultSettingsBuilderFactory().newInstance().build(request)
.getEffectiveSettings();
......
org.springframework.boot.cli.compiler.grape.SettingsXmlRepositorySystemSessionAutoConfiguration
\ No newline at end of file
org.springframework.boot.cli.compiler.grape.SettingsXmlRepositorySystemSessionAutoConfiguration
org.springframework.boot.cli.compiler.grape.GrapeRootRepositorySystemSessionAutoConfiguration
\ No newline at end of file
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed 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.springframework.boot.cli.compiler.grape;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.LocalRepositoryManager;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link GrapeRootRepositorySystemSessionAutoConfiguration}
*
* @author Andy Wilkinson
*/
@RunWith(MockitoJUnitRunner.class)
public class GrapeRootRepositorySystemSessionAutoConfigurationTests {
private DefaultRepositorySystemSession session = MavenRepositorySystemUtils
.newSession();
@Mock
private RepositorySystem repositorySystem;
@Test
public void noLocalRepositoryWhenNoGrapeRoot() {
given(
this.repositorySystem.newLocalRepositoryManager(eq(this.session),
any(LocalRepository.class))).willAnswer(
new Answer<LocalRepositoryManager>() {
@Override
public LocalRepositoryManager answer(InvocationOnMock invocation)
throws Throwable {
LocalRepository localRepository = invocation.getArgumentAt(1,
LocalRepository.class);
return new SimpleLocalRepositoryManagerFactory()
.newInstance(
GrapeRootRepositorySystemSessionAutoConfigurationTests.this.session,
localRepository);
}
});
new GrapeRootRepositorySystemSessionAutoConfiguration().apply(this.session,
this.repositorySystem);
verify(this.repositorySystem, times(0)).newLocalRepositoryManager(
eq(this.session), any(LocalRepository.class));
assertThat(this.session.getLocalRepository(), is(nullValue()));
}
@Test
public void grapeRootConfiguresLocalRepositoryLocation() {
given(
this.repositorySystem.newLocalRepositoryManager(eq(this.session),
any(LocalRepository.class))).willAnswer(
new LocalRepositoryManagerAnswer());
System.setProperty("grape.root", "foo");
try {
new GrapeRootRepositorySystemSessionAutoConfiguration().apply(this.session,
this.repositorySystem);
}
finally {
System.clearProperty("grape.root");
}
verify(this.repositorySystem, times(1)).newLocalRepositoryManager(
eq(this.session), any(LocalRepository.class));
assertThat(this.session.getLocalRepository(), is(notNullValue()));
assertThat(this.session.getLocalRepository().getBasedir().getAbsolutePath(),
endsWith("/foo/repository"));
}
private class LocalRepositoryManagerAnswer implements Answer<LocalRepositoryManager> {
@Override
public LocalRepositoryManager answer(InvocationOnMock invocation)
throws Throwable {
LocalRepository localRepository = invocation.getArgumentAt(1,
LocalRepository.class);
return new SimpleLocalRepositoryManagerFactory().newInstance(
GrapeRootRepositorySystemSessionAutoConfigurationTests.this.session,
localRepository);
}
}
}
......@@ -20,8 +20,10 @@ import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.apache.maven.settings.building.SettingsBuildingException;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
import org.eclipse.aether.repository.Authentication;
import org.eclipse.aether.repository.AuthenticationContext;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.LocalRepositoryManager;
import org.eclipse.aether.repository.Proxy;
import org.eclipse.aether.repository.RemoteRepository;
......@@ -30,10 +32,17 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import static org.hamcrest.Matchers.endsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
/**
* Tests for {@link SettingsXmlRepositorySystemSessionAutoConfiguration}.
......@@ -49,9 +58,6 @@ public class SettingsXmlRepositorySystemSessionAutoConfigurationTests {
@Mock
private RepositorySystem repositorySystem;
@Mock
LocalRepositoryManager localRepositoryManager;
@Test
public void basicSessionCustomization() throws SettingsBuildingException {
assertSessionCustomization("src/test/resources/maven-settings/basic");
......@@ -62,6 +68,39 @@ public class SettingsXmlRepositorySystemSessionAutoConfigurationTests {
assertSessionCustomization("src/test/resources/maven-settings/encrypted");
}
@Test
public void propertyInterpolation() throws SettingsBuildingException {
final DefaultRepositorySystemSession session = MavenRepositorySystemUtils
.newSession();
given(
this.repositorySystem.newLocalRepositoryManager(eq(session),
any(LocalRepository.class))).willAnswer(
new Answer<LocalRepositoryManager>() {
@Override
public LocalRepositoryManager answer(InvocationOnMock invocation)
throws Throwable {
LocalRepository localRepository = invocation.getArgumentAt(1,
LocalRepository.class);
return new SimpleLocalRepositoryManagerFactory().newInstance(
session, localRepository);
}
});
System.setProperty("foo", "bar");
try {
new SettingsXmlRepositorySystemSessionAutoConfiguration(
"src/test/resources/maven-settings/property-interpolation").apply(
session, this.repositorySystem);
}
finally {
System.clearProperty("foo");
}
assertThat(session.getLocalRepository().getBasedir().getAbsolutePath(),
endsWith("/bar/repository"));
}
private void assertSessionCustomization(String userHome) {
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment