Allow meta-data driven version overrides in Gradle

Add a `versionManagement` gradle configuration which can be used to
provide alternative version meta-data. Primarily added so that the
Spring IO platform can provide version overrides without causing a
cyclic build dependency.

Fixes gh-750
pull/812/merge
Phillip Webb 11 years ago
parent 38fb8e6874
commit 506c0f50b9

@ -18,6 +18,7 @@ package org.springframework.boot.cli.compiler.dependencies;
import org.springframework.boot.dependency.tools.Dependency;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import org.springframework.boot.dependency.tools.VersionManagedDependencies;
/**
* {@link ArtifactCoordinatesResolver} backed by {@link ManagedDependencies}.
@ -30,7 +31,7 @@ public class ManagedDependenciesArtifactCoordinatesResolver implements
private final ManagedDependencies dependencies;
public ManagedDependenciesArtifactCoordinatesResolver() {
this(ManagedDependencies.get());
this(new VersionManagedDependencies());
}
ManagedDependenciesArtifactCoordinatesResolver(ManagedDependencies dependencies) {
@ -53,7 +54,7 @@ public class ManagedDependenciesArtifactCoordinatesResolver implements
if (artifactId != null) {
if (artifactId.startsWith("spring-boot")) {
return new Dependency("org.springframework.boot", artifactId,
this.dependencies.getVersion());
this.dependencies.getSpringBootVersion());
}
return this.dependencies.find(artifactId);
}

@ -24,10 +24,12 @@ import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.util.artifact.JavaScopes;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import org.springframework.boot.dependency.tools.PomManagedDependencies;
import org.springframework.boot.dependency.tools.VersionManagedDependencies;
/**
* Factory to create Maven {@link Dependency} objects from Boot
* {@link ManagedDependencies}.
* {@link PomManagedDependencies}.
*
* @author Phillip Webb
*/
@ -36,7 +38,7 @@ public class ManagedDependenciesFactory {
private final ManagedDependencies dependencies;
ManagedDependenciesFactory() {
this(ManagedDependencies.get());
this(new VersionManagedDependencies());
}
ManagedDependenciesFactory(ManagedDependencies dependencies) {

@ -45,7 +45,7 @@ public class ManagedDependenciesArtifactCoordinatesResolverTests {
public void setup() {
this.dependencies = mock(ManagedDependencies.class);
given(this.dependencies.find("a1")).willReturn(new Dependency("g1", "a1", "0"));
given(this.dependencies.getVersion()).willReturn("1");
given(this.dependencies.getSpringBootVersion()).willReturn("1");
this.resolver = new ManagedDependenciesArtifactCoordinatesResolver(
this.dependencies);
}

@ -225,6 +225,33 @@ actual Spring Boot version that you wish to use.
[[build-tool-plugins-gradle-custom-version-management]]
==== Custom version management
If is possible to customize the versions used by the `ResolutionStrategy` if you need
to deviate from Spring Boot's ``blessed'' dependencies. Alternative version meta-data
is consulted using the `versionManagement` configuration. For example:
[source,groovy,indent=0,subs="verbatim,attributes"]
----
dependencies {
versionManagement("com.mycorp:mycorp-versions:1.0.0.RELEASE@properties")
compile("org.springframework.data:spring-data-hadoop")
}
----
Version information needs to be published to a repository as a `.properties` file. For
the above example `mycorp-versions.properties` file might contain the following:
[source,properties,indent=0,subs="verbatim,attributes"]
----
org.springframework.data\:spring-data-hadoop=2.0.0.RELEASE
----
The properties file takes precedence over Spring Boot's defaults, and can be used
to override version numbers if necessary.
[[build-tool-plugins-gradle-packaging]]
=== Packaging executable jar and war files
Once the `spring-boot` plugin has been applied to your project it will automatically

@ -0,0 +1,115 @@
/*
* Copyright 2012-2014 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.dependency.tools;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Abstract base implementation for {@link ManagedDependencies}.
*
* @author Phillip Webb
* @since 1.1.0
*/
abstract class AbstractManagedDependencies implements ManagedDependencies {
private final Map<ArtifactAndGroupId, Dependency> byArtifactAndGroupId;
private final Map<String, Dependency> byArtifactId;
public AbstractManagedDependencies() {
this.byArtifactAndGroupId = new LinkedHashMap<ArtifactAndGroupId, Dependency>();
this.byArtifactId = new LinkedHashMap<String, Dependency>();
}
@Override
public Dependency find(String groupId, String artifactId) {
return this.byArtifactAndGroupId.get(new ArtifactAndGroupId(groupId, artifactId));
}
@Override
public Dependency find(String artifactId) {
return this.byArtifactId.get(artifactId);
}
@Override
public Iterator<Dependency> iterator() {
return this.byArtifactAndGroupId.values().iterator();
}
@Override
public String getSpringBootVersion() {
Dependency dependency = find("org.springframework.boot", "spring-boot");
return (dependency == null ? null : dependency.getVersion());
}
protected void add(ArtifactAndGroupId artifactAndGroupId, Dependency dependency) {
this.byArtifactAndGroupId.put(artifactAndGroupId, dependency);
this.byArtifactId.put(dependency.getArtifactId(), dependency);
}
/**
* Simple holder for an artifact+group ID.
*/
protected static class ArtifactAndGroupId {
private final String groupId;
private final String artifactId;
public ArtifactAndGroupId(Dependency dependency) {
this(dependency.getGroupId(), dependency.getArtifactId());
}
public ArtifactAndGroupId(String groupId, String artifactId) {
Assert.notNull(groupId, "GroupId must not be null");
Assert.notNull(artifactId, "ArtifactId must not be null");
this.groupId = groupId;
this.artifactId = artifactId;
}
public Dependency newDependency(String version) {
return new Dependency(this.groupId, this.artifactId, version);
}
@Override
public int hashCode() {
return this.groupId.hashCode() * 31 + this.artifactId.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() == obj.getClass()) {
ArtifactAndGroupId other = (ArtifactAndGroupId) obj;
boolean result = true;
result &= this.groupId.equals(other.groupId);
result &= this.artifactId.equals(other.artifactId);
return result;
}
return false;
}
}
}

@ -16,104 +16,20 @@
package org.springframework.boot.dependency.tools;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Provides access to the managed dependencies declared in
* {@literal spring-boot-dependencies}.
* Interface for accessing a known managed set of dependencies.
*
* @author Phillip Webb
* @see Dependency
*/
public class ManagedDependencies implements Iterable<Dependency> {
private static ManagedDependencies instance;
private final String version;
private final Map<ArtifactAndGroupId, Dependency> byArtifactAndGroupId;
private final Map<String, Dependency> byArtifactId;
ManagedDependencies(String dependenciesPomResource, String effectivePomResource) {
try {
Document dependenciesPomDocument = readDocument(dependenciesPomResource);
this.version = dependenciesPomDocument.getElementsByTagName("version")
.item(0).getTextContent();
// Parse all dependencies from the effective POM (with resolved properties)
Document effectivePomDocument = readDocument(effectivePomResource);
Map<ArtifactAndGroupId, Dependency> all = new HashMap<ArtifactAndGroupId, Dependency>();
for (Dependency dependency : readDependencies(effectivePomDocument)) {
all.put(new ArtifactAndGroupId(dependency), dependency);
}
// But only add those from the dependencies POM
this.byArtifactAndGroupId = new LinkedHashMap<ManagedDependencies.ArtifactAndGroupId, Dependency>();
this.byArtifactId = new LinkedHashMap<String, Dependency>();
for (Dependency dependency : readDependencies(dependenciesPomDocument)) {
ArtifactAndGroupId artifactAndGroupId = new ArtifactAndGroupId(dependency);
Dependency effectiveDependency = all.get(artifactAndGroupId);
if (effectiveDependency != null) {
this.byArtifactAndGroupId
.put(artifactAndGroupId, effectiveDependency);
this.byArtifactId.put(effectiveDependency.getArtifactId(),
effectiveDependency);
}
}
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
private Document readDocument(String resource) throws Exception {
InputStream stream = getClass().getResourceAsStream(resource);
if (stream == null) {
throw new IllegalStateException("Unable to open resource " + resource);
}
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance()
.newDocumentBuilder();
Document document = documentBuilder.parse(stream);
document.getDocumentElement().normalize();
return document;
}
private List<Dependency> readDependencies(Document document) throws Exception {
Element element = (Element) document.getElementsByTagName("project").item(0);
element = (Element) element.getElementsByTagName("dependencyManagement").item(0);
element = (Element) element.getElementsByTagName("dependencies").item(0);
NodeList nodes = element.getChildNodes();
List<Dependency> dependencies = new ArrayList<Dependency>();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node instanceof Element) {
dependencies.add(Dependency.fromDependenciesXml((Element) node));
}
}
return dependencies;
}
public interface ManagedDependencies extends Iterable<Dependency> {
/**
* Return the 'spring-boot-dependencies' POM version.
* @return The Spring Boot version being managed.
*/
public String getVersion() {
return this.version;
}
public String getSpringBootVersion();
/**
* Find a single dependency for the given group and artifact IDs.
@ -121,79 +37,19 @@ public class ManagedDependencies implements Iterable<Dependency> {
* @param artifactId the artifact ID
* @return a {@link Dependency} or {@code null}
*/
public Dependency find(String groupId, String artifactId) {
return this.byArtifactAndGroupId.get(new ArtifactAndGroupId(groupId, artifactId));
}
public Dependency find(String groupId, String artifactId);
/**
* Find a single dependency for the artifact IDs.
* @param artifactId the artifact ID
* @return a {@link Dependency} or {@code null}
*/
public Dependency find(String artifactId) {
return this.byArtifactId.get(artifactId);
}
public Dependency find(String artifactId);
/**
* Provide an {@link Iterator} over all managed {@link Dependency Dependencies}.
*/
@Override
public Iterator<Dependency> iterator() {
return this.byArtifactAndGroupId.values().iterator();
}
/**
* @return The Spring Boot managed dependencies.
*/
public static ManagedDependencies get() {
if (instance == null) {
return new ManagedDependencies("dependencies-pom.xml", "effective-pom.xml");
}
return instance;
}
/**
* Simple holder for an artifact+group ID.
*/
private static class ArtifactAndGroupId {
private final String groupId;
private final String artifactId;
public ArtifactAndGroupId(Dependency dependency) {
this(dependency.getGroupId(), dependency.getArtifactId());
}
public ArtifactAndGroupId(String groupId, String artifactId) {
Assert.notNull(groupId, "GroupId must not be null");
Assert.notNull(artifactId, "ArtifactId must not be null");
this.groupId = groupId;
this.artifactId = artifactId;
}
@Override
public int hashCode() {
return this.groupId.hashCode() * 31 + this.artifactId.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() == obj.getClass()) {
ArtifactAndGroupId other = (ArtifactAndGroupId) obj;
boolean result = true;
result &= this.groupId.equals(other.groupId);
result &= this.artifactId.equals(other.artifactId);
return result;
}
return false;
}
public Iterator<Dependency> iterator();
}
}

@ -0,0 +1,113 @@
/*
* Copyright 2012-2014 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.dependency.tools;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* {@link ManagedDependencies} implementation backed a maven POM.
*
* @author Phillip Webb
* @since 1.1.0
*/
public class PomManagedDependencies extends AbstractManagedDependencies {
/**
* Create a new {@link PomManagedDependencies} instance.
* @param effectivePomInputStream the effective POM containing resolved versions. The
* input stream will be closed once content has been loaded.
* @param dependenciesInputStream and optional POM used to limit the dependencies. The
* input stream will be closed once content has been loaded. which will be added from
* the effective POM
*/
public PomManagedDependencies(InputStream effectivePomInputStream,
InputStream dependenciesInputStream) {
try {
Document effectivePom = readDocument(effectivePomInputStream);
Document dependenciesPom = readDocument(dependenciesInputStream);
if (dependenciesPom == null) {
// No dependencies POM, add all items
for (Dependency dependency : readDependencies(effectivePom)) {
add(new ArtifactAndGroupId(dependency), dependency);
}
}
else {
// Only add items that are also in the dependencies POM
Map<ArtifactAndGroupId, Dependency> all = new HashMap<ArtifactAndGroupId, Dependency>();
for (Dependency dependency : readDependencies(effectivePom)) {
all.put(new ArtifactAndGroupId(dependency), dependency);
}
for (Dependency dependency : readDependencies(dependenciesPom)) {
ArtifactAndGroupId artifactAndGroupId = new ArtifactAndGroupId(
dependency);
Dependency effectiveDependency = all.get(artifactAndGroupId);
if (effectiveDependency != null) {
add(artifactAndGroupId, effectiveDependency);
}
}
}
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
private Document readDocument(InputStream inputStream) throws Exception {
if (inputStream == null) {
return null;
}
try {
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document document = builder.parse(inputStream);
document.getDocumentElement().normalize();
return document;
}
finally {
inputStream.close();
}
}
private List<Dependency> readDependencies(Document document) throws Exception {
Element element = (Element) document.getElementsByTagName("project").item(0);
element = (Element) element.getElementsByTagName("dependencyManagement").item(0);
element = (Element) element.getElementsByTagName("dependencies").item(0);
NodeList nodes = element.getChildNodes();
List<Dependency> dependencies = new ArrayList<Dependency>();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node instanceof Element) {
dependencies.add(Dependency.fromDependenciesXml((Element) node));
}
}
return dependencies;
}
}

@ -0,0 +1,73 @@
/*
* Copyright 2012-2014 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.dependency.tools;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
/**
* {@link ManagedDependencies} backed by an external properties file (of the form created
* by the Spring IO platform). The property key should be the groupID and versionId (in
* the form {@literal group:version}) and the value should be the version.
*
* @author Phillip Webb
* @since 1.1.0
*/
public class PropertiesFileManagedDependencies extends AbstractManagedDependencies {
/**
* Create a new {@link PropertiesFileManagedDependencies} instance from the specified
* input stream.
* @param inputStream source input stream (will be closed when properties have been
* loaded)
* @throws IOException
*/
public PropertiesFileManagedDependencies(InputStream inputStream) throws IOException {
try {
Properties properties = new Properties();
properties.load(inputStream);
initialize(properties);
}
finally {
inputStream.close();
}
}
private void initialize(Properties properties) {
Map<String, String> sortedMap = new TreeMap<String, String>();
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
sortedMap.put(entry.getKey().toString(), entry.getValue().toString());
}
for (Map.Entry<String, String> entry : sortedMap.entrySet()) {
ArtifactAndGroupId artifactAndGroupId = parse(entry.getKey());
Dependency dependency = artifactAndGroupId.newDependency(entry.getValue());
add(artifactAndGroupId, dependency);
}
}
private ArtifactAndGroupId parse(String value) {
String[] parts = value.split("\\:");
if (parts.length != 2) {
throw new IllegalStateException("Unable to parse " + value);
}
return new ArtifactAndGroupId(parts[0], parts[1]);
}
}

@ -0,0 +1,85 @@
/*
* Copyright 2012-2014 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.dependency.tools;
import java.io.InputStream;
import java.util.Collection;
import java.util.Collections;
/**
* {@link ManagedDependencies} used by various spring boot tools. Provides programmatic
* access to 'spring-boot-dependencies' and can also support user defined version managed
* dependencies.
*
* @author Phillip Webb
* @since 1.1.0
*/
public class VersionManagedDependencies extends AbstractManagedDependencies {
private static ManagedDependencies springBootDependencies;
/**
* Create a new {@link VersionManagedDependencies} instance for
* 'spring-boot-dependencies'.
*/
public VersionManagedDependencies() {
this(Collections.<ManagedDependencies> emptySet());
}
/**
* Create a new {@link VersionManagedDependencies} instance with optional version
* managed dependencies.
* @param versionManagedDependencies a collection of {@link ManagedDependencies} that
* take precedence over the `spring-boot-dependencies`.
*/
public VersionManagedDependencies(
Collection<ManagedDependencies> versionManagedDependencies) {
this(getSpringBootDependencies(), versionManagedDependencies);
}
VersionManagedDependencies(ManagedDependencies rootDependencies,
Collection<ManagedDependencies> versionManagedDependencies) {
addAll(rootDependencies);
if (versionManagedDependencies != null) {
for (ManagedDependencies managedDependencies : versionManagedDependencies) {
addAll(managedDependencies);
}
}
}
private void addAll(ManagedDependencies dependencies) {
for (Dependency dependency : dependencies) {
add(new ArtifactAndGroupId(dependency), dependency);
}
}
private static ManagedDependencies getSpringBootDependencies() {
if (springBootDependencies == null) {
springBootDependencies = new PomManagedDependencies(
getResource("effective-pom.xml"), getResource("dependencies-pom.xml"));
}
return springBootDependencies;
}
private static InputStream getResource(String name) {
InputStream inputStream = VersionManagedDependencies.class
.getResourceAsStream(name);
Assert.notNull(inputStream, "Unable to load " + name);
return inputStream;
}
}

@ -18,7 +18,7 @@
* Utilities for working with the managed dependencies declared in the
* {@literal spring-boot-dependencies} project.
*
* @see org.springframework.boot.dependency.tools.ManagedDependencies
* @see org.springframework.boot.dependency.tools.VersionManagedDependencies
*/
package org.springframework.boot.dependency.tools;

@ -0,0 +1,102 @@
/*
* Copyright 2012-2014 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.dependency.tools;
import java.io.InputStream;
import java.util.Iterator;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
/**
* Tests for {@link PomManagedDependencies}.
*
* @author Phillip Webb
*/
public class PomManagedDependenciesTests {
private PomManagedDependencies dependencies;
@Before
public void setup() {
InputStream x = getResource("test-effective-pom.xml");
InputStream y = getResource("test-dependencies-pom.xml");
this.dependencies = new PomManagedDependencies(x, y);
}
private InputStream getResource(String name) {
InputStream inputStream = getClass().getResourceAsStream(name);
assertNotNull("Unable to read " + name, inputStream);
return inputStream;
}
@Test
public void springBootVersion() throws Exception {
assertThat(this.dependencies.getSpringBootVersion(),
equalTo("1.0.0.BUILD-SNAPSHOT"));
}
@Test
public void iterate() throws Exception {
Iterator<Dependency> iterator = this.dependencies.iterator();
assertThat(iterator.next().toString(), equalTo("org.sample:sample01:1.0.0"));
assertThat(iterator.next().toString(), equalTo("org.sample:sample02:1.0.0"));
assertThat(iterator.next().toString(),
equalTo("org.springframework.boot:spring-boot:1.0.0.BUILD-SNAPSHOT"));
assertThat(iterator.hasNext(), equalTo(false));
}
@Test
public void findByArtifactAndGroupId() throws Exception {
assertThat(this.dependencies.find("org.sample", "sample02").toString(),
equalTo("org.sample:sample02:1.0.0"));
}
@Test
public void findByArtifactAndGroupIdMissing() throws Exception {
assertThat(this.dependencies.find("org.sample", "missing"), nullValue());
}
@Test
public void findByArtifactAndGroupIdOnlyInEffectivePom() throws Exception {
assertThat(this.dependencies.find("org.extra", "extra01"), nullValue());
}
@Test
public void findByArtifactId() throws Exception {
assertThat(this.dependencies.find("sample02").toString(),
equalTo("org.sample:sample02:1.0.0"));
}
@Test
public void findByArtifactIdMissing() throws Exception {
assertThat(this.dependencies.find("missing"), nullValue());
}
@Test
public void exludes() throws Exception {
Dependency dependency = this.dependencies.find("org.sample", "sample01");
assertThat(dependency.getExclusions().toString(),
equalTo("[org.exclude:exclude01]"));
}
}

@ -22,28 +22,28 @@ import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
/**
* Tests for {@link ManagedDependencies}.
* Tests for {@link PropertiesFileManagedDependencies}.
*
* @author Phillip Webb
*/
public class ManagedDependenciesTests {
public class PropertiesFileManagedDependenciesTests {
private ManagedDependencies dependencies;
private PropertiesFileManagedDependencies dependencies;
@Before
public void setup() {
this.dependencies = new ManagedDependencies("test-dependencies-pom.xml",
"test-effective-pom.xml");
public void setup() throws Exception {
this.dependencies = new PropertiesFileManagedDependencies(getClass()
.getResourceAsStream("external.properties"));
}
@Test
public void version() throws Exception {
assertThat(this.dependencies.getVersion(), equalTo("1.0.0.BUILD-SNAPSHOT"));
public void springBootVersion() throws Exception {
assertThat(this.dependencies.getSpringBootVersion(),
equalTo("1.0.0.BUILD-SNAPSHOT"));
}
@Test
@ -51,6 +51,8 @@ public class ManagedDependenciesTests {
Iterator<Dependency> iterator = this.dependencies.iterator();
assertThat(iterator.next().toString(), equalTo("org.sample:sample01:1.0.0"));
assertThat(iterator.next().toString(), equalTo("org.sample:sample02:1.0.0"));
assertThat(iterator.next().toString(),
equalTo("org.springframework.boot:spring-boot:1.0.0.BUILD-SNAPSHOT"));
assertThat(iterator.hasNext(), equalTo(false));
}
@ -83,17 +85,9 @@ public class ManagedDependenciesTests {
@Test
public void exludes() throws Exception {
// No Support for exclusion
Dependency dependency = this.dependencies.find("org.sample", "sample01");
assertThat(dependency.getExclusions().toString(),
equalTo("[org.exclude:exclude01]"));
}
@Test
public void get() throws Exception {
ManagedDependencies dependencies = ManagedDependencies.get();
assertThat(dependencies.iterator().hasNext(), equalTo(true));
assertThat(dependencies.find("org.springframework", "spring-core"),
notNullValue());
assertThat(dependency.getExclusions().size(), equalTo(0));
}
}

@ -0,0 +1,76 @@
/*
* Copyright 2012-2014 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.dependency.tools;
import java.util.Collections;
import java.util.Iterator;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
/**
* Tests for {@link VersionManagedDependencies}.
*
* @author Phillip Webb
*/
public class VersionManagedDependenciesTests {
private VersionManagedDependencies dependencies;
@Before
public void setup() throws Exception {
PropertiesFileManagedDependencies root = new PropertiesFileManagedDependencies(
getClass().getResourceAsStream("external.properties"));
PropertiesFileManagedDependencies extra = new PropertiesFileManagedDependencies(
getClass().getResourceAsStream("additional-external.properties"));
this.dependencies = new VersionManagedDependencies(root,
Collections.<ManagedDependencies> singleton(extra));
}
@Test
public void extra() throws Exception {
assertThat(this.dependencies.find("org.sample", "sample03").toString(),
equalTo("org.sample:sample03:2.0.0"));
}
@Test
public void override() throws Exception {
assertThat(this.dependencies.find("org.sample", "sample02").toString(),
equalTo("org.sample:sample02:2.0.0"));
}
@Test
public void getSpringBootVersion() throws Exception {
assertThat(this.dependencies.getSpringBootVersion(),
equalTo("1.0.0.BUILD-SNAPSHOT"));
}
@Test
public void iterator() throws Exception {
Iterator<Dependency> iterator = this.dependencies.iterator();
assertThat(iterator.next().toString(), equalTo("org.sample:sample01:1.0.0"));
assertThat(iterator.next().toString(), equalTo("org.sample:sample02:2.0.0"));
assertThat(iterator.next().toString(),
equalTo("org.springframework.boot:spring-boot:1.0.0.BUILD-SNAPSHOT"));
assertThat(iterator.next().toString(), equalTo("org.sample:sample03:2.0.0"));
assertThat(iterator.hasNext(), equalTo(false));
}
}

@ -0,0 +1,3 @@
org.sample\:sample01=1.0.0
org.sample\:sample02=1.0.0
org.springframework.boot\:spring-boot=1.0.0.BUILD-SNAPSHOT

@ -15,10 +15,10 @@
<artifactId>sample01</artifactId>
<version>${sample.version}</version>
<exclusions>
<exclusion>
<groupId>org.exclude</groupId>
<artifactId>exclude01</artifactId>
</exclusion>
<exclusion>
<groupId>org.exclude</groupId>
<artifactId>exclude01</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
@ -26,6 +26,11 @@
<artifactId>sample02</artifactId>
<version>${sample.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

@ -24,6 +24,11 @@
<artifactId>sample02</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.extra</groupId>
<artifactId>extra01</artifactId>

@ -32,7 +32,7 @@ import org.springframework.boot.gradle.task.RunWithAgent;
/**
* Gradle 'Spring Boot' {@link Plugin}.
*
*
* @author Phillip Webb
* @author Dave Syer
*/
@ -45,6 +45,9 @@ public class SpringBootPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getConfigurations().create(
SpringBootResolutionStrategy.VERSION_MANAGEMENT_CONFIGURATION);
applyRepackage(project);
applyRun(project);
@ -80,12 +83,12 @@ public class SpringBootPlugin implements Plugin<Project> {
project.getTasks().whenTaskAdded(new ComputeMain(project));
}
private void applyResolutionStrategy(Project project) {
private void applyResolutionStrategy(final Project project) {
project.getConfigurations().all(new Action<Configuration>() {
@Override
public void execute(Configuration configuration) {
SpringBootResolutionStrategy.apply(configuration.getResolutionStrategy());
SpringBootResolutionStrategy.apply(project, configuration);
}
});

@ -1,50 +1,99 @@
package org.springframework.boot.gradle;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.gradle.api.Action;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.DependencyResolveDetails;
import org.gradle.api.artifacts.ModuleVersionSelector;
import org.gradle.api.artifacts.ResolutionStrategy;
import org.springframework.boot.dependency.tools.Dependency;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import org.springframework.boot.dependency.tools.PropertiesFileManagedDependencies;
import org.springframework.boot.dependency.tools.VersionManagedDependencies;
/**
* A resolution strategy to resolve missing version numbers using the
* 'spring-boot-dependencies' POM.
*
*
* @author Phillip Webb
*/
public class SpringBootResolutionStrategy {
public static final String VERSION_MANAGEMENT_CONFIGURATION = "versionManagement";
private static final String SPRING_BOOT_GROUP = "org.springframework.boot";
public static void apply(ResolutionStrategy resolutionStrategy) {
resolutionStrategy.eachDependency(new Action<DependencyResolveDetails>() {
public static void apply(final Project project, Configuration configuration) {
if (VERSION_MANAGEMENT_CONFIGURATION.equals(configuration.getName())) {
return;
}
VersionResolver versionResolver = new VersionResolver(project);
configuration.getResolutionStrategy().eachDependency(versionResolver);
}
@Override
public void execute(DependencyResolveDetails resolveDetails) {
String version = resolveDetails.getTarget().getVersion();
if (version == null || version.trim().length() == 0) {
resolve(resolveDetails);
}
}
private static class VersionResolver implements Action<DependencyResolveDetails> {
});
}
private Configuration versionManagementConfiguration;
protected static void resolve(DependencyResolveDetails resolveDetails) {
private Collection<ManagedDependencies> versionManagedDependencies;
ManagedDependencies dependencies = ManagedDependencies.get();
ModuleVersionSelector target = resolveDetails.getTarget();
public VersionResolver(Project project) {
this.versionManagementConfiguration = project.getConfigurations().getByName(
VERSION_MANAGEMENT_CONFIGURATION);
}
if (SPRING_BOOT_GROUP.equals(target.getGroup())) {
resolveDetails.useVersion(dependencies.getVersion());
return;
@Override
public void execute(DependencyResolveDetails resolveDetails) {
String version = resolveDetails.getTarget().getVersion();
if (version == null || version.trim().length() == 0) {
resolve(resolveDetails);
}
}
Dependency dependency = dependencies.find(target.getGroup(), target.getName());
if (dependency != null) {
resolveDetails.useVersion(dependency.getVersion());
private void resolve(DependencyResolveDetails resolveDetails) {
ManagedDependencies dependencies = new VersionManagedDependencies(
getVersionManagedDependencies());
ModuleVersionSelector target = resolveDetails.getTarget();
if (SPRING_BOOT_GROUP.equals(target.getGroup())) {
resolveDetails.useVersion(dependencies.getSpringBootVersion());
return;
}
Dependency dependency = dependencies.find(target.getGroup(), target.getName());
if (dependency != null) {
resolveDetails.useVersion(dependency.getVersion());
}
}
}
private Collection<ManagedDependencies> getVersionManagedDependencies() {
if (versionManagedDependencies == null) {
Set<File> files = versionManagementConfiguration.resolve();
List<ManagedDependencies> dependencies = new ArrayList<ManagedDependencies>(
files.size());
for (File file : files) {
dependencies.add(getPropertiesFileManagedDependencies(file));
}
this.versionManagedDependencies = dependencies;
}
return versionManagedDependencies;
}
private ManagedDependencies getPropertiesFileManagedDependencies(File file) {
if (!file.getName().toLowerCase().endsWith(".properties")) {
throw new IllegalStateException(file + " is not a version property file");
}
try {
return new PropertiesFileManagedDependencies(new FileInputStream(file));
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
}
}

@ -0,0 +1,29 @@
buildscript {
ext {
springBootVersion = '1.1.0.BUILD-SNAPSHOT'
}
repositories {
mavenLocal()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'spring-boot'
repositories {
mavenLocal()
mavenCentral()
maven { url "http://repo.spring.io/release" }
maven { url "http://repo.spring.io/milestone" }
maven { url "http://repo.spring.io/snapshot" }
}
dependencies {
versionManagement("io.spring.platform:platform-versions:1.0.0.BUILD-SNAPSHOT@properties")
compile("org.springframework.boot:spring-boot-starter")
compile("org.springframework.data:spring-data-hadoop")
testCompile("org.springframework.boot:spring-boot-starter-test")
}

@ -0,0 +1,3 @@
simple manual test to show how versionManagement dependencies can be used
run gradle dependencies and check that there are no failures

@ -0,0 +1,6 @@
public class VersionManagementApplication {
public static void main(String[] args) {
}
}
Loading…
Cancel
Save