diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml index fd70bea915..3ea33cb806 100644 --- a/spring-boot-dependencies/pom.xml +++ b/spring-boot-dependencies/pom.xml @@ -616,6 +616,10 @@ maven-install-plugin 2.5.1 + + maven-help-plugin + 2.2 + maven-jar-plugin 2.4 diff --git a/spring-boot-tools/pom.xml b/spring-boot-tools/pom.xml index 4eaa084c17..d5bbe494fe 100644 --- a/spring-boot-tools/pom.xml +++ b/spring-boot-tools/pom.xml @@ -14,6 +14,7 @@ ${basedir}/.. + spring-boot-dependency-tools spring-boot-loader spring-boot-loader-tools spring-boot-maven-plugin diff --git a/spring-boot-tools/spring-boot-dependency-tools/README.md b/spring-boot-tools/spring-boot-dependency-tools/README.md new file mode 100644 index 0000000000..c1f17ba629 --- /dev/null +++ b/spring-boot-tools/spring-boot-dependency-tools/README.md @@ -0,0 +1,4 @@ +# Spring Boot - Dependency Tools +The Spring Boot Dependency Tools module provides support utilities to help when resolving +'blessed' Spring Boot dependencies. It basically provides programmatic access to the +managed dependencies section of `spring-boot-dependencies/pom.xml` diff --git a/spring-boot-tools/spring-boot-dependency-tools/pom.xml b/spring-boot-tools/spring-boot-dependency-tools/pom.xml new file mode 100644 index 0000000000..ba14fa4bc0 --- /dev/null +++ b/spring-boot-tools/spring-boot-dependency-tools/pom.xml @@ -0,0 +1,115 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-tools + 1.0.0.BUILD-SNAPSHOT + + spring-boot-dependency-tools + jar + + ${basedir}/../.. + ${project.build.directory}/generated-resources/org/springframework/boot/dependency/tools + + + + + ${project.build.directory}/generated-resources + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + copy-dependencies-pom + generate-resources + + run + + + + + + + + + + + maven-help-plugin + + + generate-effective-dependencies-pom + generate-resources + + effective-pom + + + ${generated.pom.dir}/effective-pom.xml + + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + + org.apache.maven.plugins + + + maven-help-plugin + + + [2.2,) + + + effective-pom + + + + + + + + + + org.apache.maven.plugins + + + maven-antrun-plugin + + + [1.7,) + + + run + + + + + + + + + + + + + + + diff --git a/spring-boot-tools/spring-boot-dependency-tools/src/main/java/org/springframework/boot/dependency/tools/Assert.java b/spring-boot-tools/spring-boot-dependency-tools/src/main/java/org/springframework/boot/dependency/tools/Assert.java new file mode 100644 index 0000000000..0b11738154 --- /dev/null +++ b/spring-boot-tools/spring-boot-dependency-tools/src/main/java/org/springframework/boot/dependency/tools/Assert.java @@ -0,0 +1,32 @@ +/* + * 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; + +/** + * Simple subset of the Spring Assert utility. + * + * @author Phillip Webb + */ +class Assert { + + public static void notNull(Object object, String message) { + if (object == null) { + throw new IllegalArgumentException(message); + } + } + +} diff --git a/spring-boot-tools/spring-boot-dependency-tools/src/main/java/org/springframework/boot/dependency/tools/Dependency.java b/spring-boot-tools/spring-boot-dependency-tools/src/main/java/org/springframework/boot/dependency/tools/Dependency.java new file mode 100644 index 0000000000..525e544068 --- /dev/null +++ b/spring-boot-tools/spring-boot-dependency-tools/src/main/java/org/springframework/boot/dependency/tools/Dependency.java @@ -0,0 +1,234 @@ +/* + * 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.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * A single managed dependency. + * + * @author Phillip Webb + * @see ManagedDependencies + */ +public final class Dependency { + + private final String groupId; + + private final String artifactId; + + private final String version; + + private final List exclusions; + + /** + * Create a new {@link Dependency} instance. + * @param groupId the group ID + * @param artifactId the artifact ID + * @param version the version + */ + public Dependency(String groupId, String artifactId, String version) { + this(groupId, artifactId, version, Collections. emptyList()); + } + + /** + * Create a new {@link Dependency} instance. + * @param groupId the group ID + * @param artifactId the artifact ID + * @param version the version + * @param exclusions the exclusions + */ + public Dependency(String groupId, String artifactId, String version, + List exclusions) { + Assert.notNull(groupId, "GroupId must not be null"); + Assert.notNull(artifactId, "ArtifactId must not be null"); + Assert.notNull(version, "Version must not be null"); + Assert.notNull(exclusions, "Exclusions must not be null"); + this.groupId = groupId; + this.artifactId = artifactId; + this.version = version; + this.exclusions = Collections.unmodifiableList(exclusions); + } + + /** + * Return the dependency group id. + */ + public String getGroupId() { + return this.groupId; + } + + /** + * Return the dependency artifact id. + */ + public String getArtifactId() { + return this.artifactId; + } + + /** + * Return the dependency version. + */ + public String getVersion() { + return this.version; + } + + /** + * Return the dependency exclusions. + */ + public List getExclusions() { + return this.exclusions; + } + + @Override + public String toString() { + return this.groupId + ":" + this.artifactId + ":" + this.version; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + this.groupId.hashCode(); + result = prime * result + this.artifactId.hashCode(); + result = prime * result + this.version.hashCode(); + result = prime * result + this.exclusions.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() == obj.getClass()) { + Dependency other = (Dependency) obj; + boolean result = true; + result &= this.groupId.equals(other.groupId); + result &= this.artifactId.equals(other.artifactId); + result &= this.version.equals(other.version); + result &= this.exclusions.equals(other.exclusions); + return result; + } + return false; + } + + static Dependency fromDependenciesXml(Element element) throws Exception { + String groupId = getTextContent(element, "groupId"); + String artifactId = getTextContent(element, "artifactId"); + String version = getTextContent(element, "version"); + List exclusions = Exclusion.fromExclusionsXml(element + .getElementsByTagName("exclusions")); + return new Dependency(groupId, artifactId, version, exclusions); + } + + private static String getTextContent(Element element, String tagName) { + return element.getElementsByTagName(tagName).item(0).getTextContent(); + } + + /** + * A dependency exclusion. + */ + public final static class Exclusion { + + private final String groupId; + + private final String artifactId; + + private Exclusion(String groupId, String artifactId) { + Assert.notNull(groupId, "GroupId must not be null"); + Assert.notNull(groupId, "ArtifactId must not be null"); + this.groupId = groupId; + this.artifactId = artifactId; + } + + /** + * Return the exclusion artifact id. + */ + public String getArtifactId() { + return this.artifactId; + } + + /** + * Return the exclusion group id. + */ + public String getGroupId() { + return this.groupId; + } + + @Override + public String toString() { + return this.groupId + ":" + this.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()) { + Exclusion other = (Exclusion) obj; + boolean result = true; + result &= this.groupId.equals(other.groupId); + result &= this.artifactId.equals(other.artifactId); + return result; + } + return false; + } + + private static List fromExclusionsXml(NodeList exclusion) { + if (exclusion == null || exclusion.getLength() == 0) { + return Collections.emptyList(); + } + return fromExclusionsXml(exclusion.item(0)); + } + + private static List fromExclusionsXml(Node item) { + List exclusions = new ArrayList(); + NodeList children = item.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child instanceof Element) { + exclusions.add(fromExclusionXml((Element) child)); + } + } + return exclusions; + } + + private static Exclusion fromExclusionXml(Element element) { + String groupId = getTextContent(element, "groupId"); + String artifactId = getTextContent(element, "artifactId"); + return new Exclusion(groupId, artifactId); + } + + } + +} diff --git a/spring-boot-tools/spring-boot-dependency-tools/src/main/java/org/springframework/boot/dependency/tools/ManagedDependencies.java b/spring-boot-tools/spring-boot-dependency-tools/src/main/java/org/springframework/boot/dependency/tools/ManagedDependencies.java new file mode 100644 index 0000000000..c44faa15ea --- /dev/null +++ b/spring-boot-tools/spring-boot-dependency-tools/src/main/java/org/springframework/boot/dependency/tools/ManagedDependencies.java @@ -0,0 +1,199 @@ +/* + * 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.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}. + * + * @author Phillip Webb + * @see Dependency + */ +public class ManagedDependencies implements Iterable { + + private static ManagedDependencies instance; + + private final String version; + + private final Map byArtifactAndGroupId; + + private final Map 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 all = new HashMap(); + for (Dependency dependency : readDependencies(effectivePomDocument)) { + all.put(new ArtifactAndGroupId(dependency), dependency); + } + + // But only add those from the dependencies POM + this.byArtifactAndGroupId = new LinkedHashMap(); + this.byArtifactId = new LinkedHashMap(); + 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 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 dependencies = new ArrayList(); + 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; + } + + /** + * Return the 'spring-boot-dependencies' POM version. + */ + public String getVersion() { + return this.version; + } + + /** + * Find a single dependency for the given group and artifact IDs. + * @param groupId the group ID + * @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)); + } + + /** + * 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); + } + + /** + * Provide an {@link Iterator} over all managed {@link Dependency Dependencies}. + */ + @Override + public Iterator 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; + } + + } +} diff --git a/spring-boot-tools/spring-boot-dependency-tools/src/main/java/org/springframework/boot/dependency/tools/package-info.java b/spring-boot-tools/spring-boot-dependency-tools/src/main/java/org/springframework/boot/dependency/tools/package-info.java new file mode 100644 index 0000000000..9271ab60ae --- /dev/null +++ b/spring-boot-tools/spring-boot-dependency-tools/src/main/java/org/springframework/boot/dependency/tools/package-info.java @@ -0,0 +1,24 @@ +/* + * 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. + */ + +/** + * Utilities for working with the managed dependencies declared in the + * {@literal spring-boot-dependencies} project. + * + * @see org.springframework.boot.dependency.tools.ManagedDependencies + */ +package org.springframework.boot.dependency.tools; + diff --git a/spring-boot-tools/spring-boot-dependency-tools/src/test/java/org/springframework/boot/dependency/tools/ManagedDependenciesTests.java b/spring-boot-tools/spring-boot-dependency-tools/src/test/java/org/springframework/boot/dependency/tools/ManagedDependenciesTests.java new file mode 100644 index 0000000000..33cba815ad --- /dev/null +++ b/spring-boot-tools/spring-boot-dependency-tools/src/test/java/org/springframework/boot/dependency/tools/ManagedDependenciesTests.java @@ -0,0 +1,99 @@ +/* + * 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 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}. + * + * @author Phillip Webb + */ +public class ManagedDependenciesTests { + + private ManagedDependencies dependencies; + + @Before + public void setup() { + this.dependencies = new ManagedDependencies("test-dependencies-pom.xml", + "test-effective-pom.xml"); + } + + @Test + public void version() throws Exception { + assertThat(this.dependencies.getVersion(), equalTo("1.0.0.BUILD-SNAPSHOT")); + } + + @Test + public void iterate() throws Exception { + Iterator 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.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]")); + } + + @Test + public void get() throws Exception { + ManagedDependencies dependencies = ManagedDependencies.get(); + assertThat(dependencies.iterator().hasNext(), equalTo(true)); + assertThat(dependencies.find("org.springframework", "spring-core"), + notNullValue()); + } + +} diff --git a/spring-boot-tools/spring-boot-dependency-tools/src/test/resources/org/springframework/boot/dependency/tools/test-dependencies-pom.xml b/spring-boot-tools/spring-boot-dependency-tools/src/test/resources/org/springframework/boot/dependency/tools/test-dependencies-pom.xml new file mode 100644 index 0000000000..2bf7cf04b2 --- /dev/null +++ b/spring-boot-tools/spring-boot-dependency-tools/src/test/resources/org/springframework/boot/dependency/tools/test-dependencies-pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + 1.0.0.BUILD-SNAPSHOT + + 1.0.0 + + + 3.0.0 + + + + + org.sample + sample01 + ${sample.version} + + + org.exclude + exclude01 + + + + + org.sample + sample02 + ${sample.version} + + + + diff --git a/spring-boot-tools/spring-boot-dependency-tools/src/test/resources/org/springframework/boot/dependency/tools/test-effective-pom.xml b/spring-boot-tools/spring-boot-dependency-tools/src/test/resources/org/springframework/boot/dependency/tools/test-effective-pom.xml new file mode 100644 index 0000000000..f24b636687 --- /dev/null +++ b/spring-boot-tools/spring-boot-dependency-tools/src/test/resources/org/springframework/boot/dependency/tools/test-effective-pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + 1.0.0.BUILD-SNAPSHOT + + 1.0.0 + + + + + org.sample + sample01 + 1.0.0 + + + org.exclude + exclude01 + + + + + org.sample + sample02 + 1.0.0 + + + org.extra + extra01 + 2.0.0 + + + + diff --git a/spring-boot-tools/spring-boot-gradle-plugin/README.md b/spring-boot-tools/spring-boot-gradle-plugin/README.md index b7ac04897a..c6b547728b 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/README.md +++ b/spring-boot-tools/spring-boot-gradle-plugin/README.md @@ -1,6 +1,7 @@ # Spring Boot - Gradle Plugin The Spring Boot Gradle Plugin provides Spring Boot support in Gradle, allowing you to -package executable jar or war archives. +package executable jar or war archives, run Spring Boot applications and remove version +information from your `build.gradle` file. ## Including the plugin To use the Spring Boot Gradle Plugin simply include a `buildscript` dependency and apply @@ -27,6 +28,23 @@ buildscript { } ``` +## Declaring dependencies without versions +The `spring-boot` plugin will register a custom Gradle `ResolutionStrategy` with your +build that allows you to omit version numbers when declaring dependencies to known +artifacts. All artifacts with a `org.springframework.boot` group ID, and any of the +artifacts declared in the `managementDependencies` section of the `spring-dependencies` +POM can have their version number resolved automatically. + +Simply declare dependencies in the usual way, but leave the version number empty: + +```groovy +dependencies { + compile("org.springframework.boot:spring-boot-starter-web") + compile("org.thymeleaf:thymeleaf-spring4") + compile("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect") +} +``` + ## Packaging executable jar and war files Once the `spring-boot` plugin has been applied to your project it will automatically attempt to rewrite archives to make them executable using the `bootRepackage` task. You @@ -45,7 +63,6 @@ $ java -jar build/libs/mymodule-0.0.1-SNAPSHOT.jar ``` ### Running a Project in Place - To run a project in place without building a jar first you can use the "bootRun" task: ``` diff --git a/spring-boot-tools/spring-boot-gradle-plugin/pom.xml b/spring-boot-tools/spring-boot-gradle-plugin/pom.xml index e35a486081..ea9025f090 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/pom.xml +++ b/spring-boot-tools/spring-boot-gradle-plugin/pom.xml @@ -18,6 +18,11 @@ spring-boot-loader-tools ${project.version} + + ${project.groupId} + spring-boot-dependency-tools + ${project.version} + org.codehaus.groovy diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/SpringBootPlugin.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/SpringBootPlugin.java index a872cbe3ef..8c90e4034a 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/SpringBootPlugin.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/SpringBootPlugin.java @@ -16,8 +16,10 @@ package org.springframework.boot.gradle; +import org.gradle.api.Action; import org.gradle.api.Plugin; import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Dependency; import org.gradle.api.plugins.ApplicationPlugin; import org.gradle.api.plugins.BasePlugin; @@ -26,8 +28,8 @@ import org.springframework.boot.gradle.task.Repackage; import org.springframework.boot.gradle.task.RunApp; /** - * Gradle 'Spring Boot' {@link Plugin}. Provides 2 tasks (bootRepackge and bootRun). - * + * Gradle 'Spring Boot' {@link Plugin}. + * * @author Phillip Webb * @author Dave Syer */ @@ -44,19 +46,31 @@ public class SpringBootPlugin implements Plugin { project.getPlugins().apply(ApplicationPlugin.class); project.getExtensions().create("springBoot", SpringBootPluginExtension.class); - // register BootRepackage so that we can use - // task foo(type: BootRepackage) {} - project.getExtensions().getExtraProperties().set("BootRepackage", Repackage.class); + applyRepackage(project); + applyRun(project); + applyResolutionStrategy(project); + } + + private void applyRepackage(Project project) { Repackage packageTask = addRepackageTask(project); ensureTaskRunsOnAssembly(project, packageTask); + } + + private void applyRun(Project project) { addRunAppTask(project); + // register BootRepackage so that we can use task foo(type: BootRepackage) {} + project.getExtensions().getExtraProperties().set("BootRepackage", Repackage.class); } - private void addRunAppTask(Project project) { - RunApp runJarTask = project.getTasks().create(RUN_APP_TASK_NAME, RunApp.class); - runJarTask.setDescription("Run the project with support for auto-detecting main class and reloading static resources"); - runJarTask.setGroup("Execution"); - runJarTask.dependsOn("assemble"); + private void applyResolutionStrategy(Project project) { + project.getConfigurations().all(new Action() { + + @Override + public void execute(Configuration configuration) { + SpringBootResolutionStrategy.apply(configuration.getResolutionStrategy()); + } + + }); } private Repackage addRepackageTask(Project project) { @@ -71,6 +85,13 @@ public class SpringBootPlugin implements Plugin { return packageTask; } + private void addRunAppTask(Project project) { + RunApp runJarTask = project.getTasks().create(RUN_APP_TASK_NAME, RunApp.class); + runJarTask.setDescription("Run the project with support for auto-detecting main class and reloading static resources"); + runJarTask.setGroup("Execution"); + runJarTask.dependsOn("assemble"); + } + private void ensureTaskRunsOnAssembly(Project project, Repackage task) { project.getTasks().getByName(BasePlugin.ASSEMBLE_TASK_NAME).dependsOn(task); } diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/SpringBootPluginExtension.groovy b/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/SpringBootPluginExtension.groovy index 938edcb663..d69c9b5dad 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/SpringBootPluginExtension.groovy +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/SpringBootPluginExtension.groovy @@ -39,8 +39,19 @@ import org.springframework.boot.loader.tools.Layouts public class SpringBootPluginExtension { static enum LayoutType { - JAR(new Layouts.Jar()), WAR(new Layouts.War()), ZIP(new Layouts.Expanded()), DIR(new Layouts.Expanded()), NONE(new Layouts.None()); + + JAR(new Layouts.Jar()), + + WAR(new Layouts.War()), + + ZIP(new Layouts.Expanded()), + + DIR(new Layouts.Expanded()), + + NONE(new Layouts.None()); + Layout layout; + private LayoutType(Layout layout) { this.layout = layout; } @@ -85,6 +96,6 @@ public class SpringBootPluginExtension { * @return the Layout to use or null if not explicitly set */ Layout convertLayout() { - layout==null ? null : layout.layout + (layout == null ? null : layout.layout) } } diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/SpringBootResolutionStrategy.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/SpringBootResolutionStrategy.java new file mode 100644 index 0000000000..c14cb65414 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/SpringBootResolutionStrategy.java @@ -0,0 +1,51 @@ + +package org.springframework.boot.gradle; + +import org.gradle.api.Action; +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; + +/** + * A resolution strategy to resolve missing version numbers using the + * 'spring-boot-dependencies' POM. + * + * @author Phillip Webb + */ +public class SpringBootResolutionStrategy { + + private static final String SPRING_BOOT_GROUP = "org.springframework.boot"; + + public static void apply(ResolutionStrategy resolutionStrategy) { + resolutionStrategy.eachDependency(new Action() { + + @Override + public void execute(DependencyResolveDetails resolveDetails) { + String version = resolveDetails.getTarget().getVersion(); + if (version == null || version.trim().length() == 0) { + resolve(resolveDetails); + } + } + + }); + } + + protected static void resolve(DependencyResolveDetails resolveDetails) { + + ManagedDependencies dependencies = ManagedDependencies.get(); + ModuleVersionSelector target = resolveDetails.getTarget(); + + if (SPRING_BOOT_GROUP.equals(target.getGroup())) { + resolveDetails.useVersion(dependencies.getVersion()); + return; + } + + Dependency dependency = dependencies.find(target.getGroup(), target.getName()); + if (dependency != null) { + resolveDetails.useVersion(dependency.getVersion()); + } + } + +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/task/RunApp.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/task/RunApp.java index dd65847684..1068e8de88 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/task/RunApp.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/task/RunApp.java @@ -36,7 +36,7 @@ import org.springframework.boot.loader.tools.MainClassFinder; /** * Run the project from Gradle. - * + * * @author Dave Syer */ public class RunApp extends DefaultTask { @@ -57,6 +57,7 @@ public class RunApp extends DefaultTask { main = set; } }; + }); final Set allResources = new LinkedHashSet();