diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/RepositoryConfigurationFactory.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/RepositoryConfigurationFactory.java index 97845f4f88f..6d1458d3e5d 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/RepositoryConfigurationFactory.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/RepositoryConfigurationFactory.java @@ -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 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)) { diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DefaultRepositorySystemSessionAutoConfiguration.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DefaultRepositorySystemSessionAutoConfiguration.java index 4b81cbdfd82..d1bfda16fbc 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DefaultRepositorySystemSessionAutoConfiguration.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DefaultRepositorySystemSessionAutoConfiguration.java @@ -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() { diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfiguration.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfiguration.java new file mode 100644 index 00000000000..0fbb818b76d --- /dev/null +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfiguration.java @@ -0,0 +1,55 @@ +/* + * 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); + } + +} diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfiguration.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfiguration.java index 8d6f95603d7..895868b9ffa 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfiguration.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfiguration.java @@ -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(); diff --git a/spring-boot-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.grape.RepositorySystemSessionAutoConfiguration b/spring-boot-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.grape.RepositorySystemSessionAutoConfiguration index 6020bac3ebe..cf394a7e183 100644 --- a/spring-boot-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.grape.RepositorySystemSessionAutoConfiguration +++ b/spring-boot-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.grape.RepositorySystemSessionAutoConfiguration @@ -1 +1,2 @@ -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 diff --git a/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfigurationTests.java b/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfigurationTests.java new file mode 100644 index 00000000000..64fcad630e3 --- /dev/null +++ b/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfigurationTests.java @@ -0,0 +1,122 @@ +/* + * 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() { + + @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 { + @Override + public LocalRepositoryManager answer(InvocationOnMock invocation) + throws Throwable { + LocalRepository localRepository = invocation.getArgumentAt(1, + LocalRepository.class); + return new SimpleLocalRepositoryManagerFactory().newInstance( + GrapeRootRepositorySystemSessionAutoConfigurationTests.this.session, + localRepository); + } + + } + +} diff --git a/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfigurationTests.java b/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfigurationTests.java index 54d4571f7f7..94db7c64f4c 100644 --- a/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfigurationTests.java +++ b/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfigurationTests.java @@ -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() { + + @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();