Publish artifacts and, when Maven plugin used, customize upload task

See gh-1666
pull/8686/merge
Andy Wilkinson 8 years ago
parent b1f9123311
commit f16efb2277

@ -224,6 +224,11 @@
<artifactId>gradle-language-jvm</artifactId>
<version>${gradle.version}</version>
</dependency>
<dependency>
<groupId>org.gradle</groupId>
<artifactId>gradle-maven</artifactId>
<version>${gradle.version}</version>
</dependency>
<dependency>
<groupId>org.gradle</groupId>
<artifactId>gradle-platform-jvm</artifactId>

@ -20,11 +20,14 @@ import java.util.concurrent.Callable;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.maven.MavenResolver;
import org.gradle.api.file.FileCollection;
import org.gradle.api.internal.artifacts.publish.ArchivePublishArtifact;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.plugins.WarPlugin;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.Upload;
import org.springframework.boot.gradle.PluginFeatures;
@ -35,17 +38,23 @@ import org.springframework.boot.gradle.PluginFeatures;
*/
public class BundlingPluginFeatures implements PluginFeatures {
private SinglePublishedArtifact singlePublishedArtifact;
@Override
public void apply(Project project) {
this.singlePublishedArtifact = new SinglePublishedArtifact(
project.getConfigurations().create("bootArchives").getArtifacts());
project.getPlugins().withType(JavaPlugin.class,
(javaPlugin) -> configureBootJarTask(project));
project.getPlugins().withType(WarPlugin.class,
(warPlugin) -> configureBootWarTask(project));
project.afterEvaluate(this::configureBootArchivesUpload);
}
private void configureBootWarTask(Project project) {
BootWar bootWar = project.getTasks().create("bootWar", BootWar.class);
bootWar.providedClasspath(providedRuntimeConfiguration(project));
this.singlePublishedArtifact.addCandidate(new ArchivePublishArtifact(bootWar));
}
private void configureBootJarTask(Project project) {
@ -57,6 +66,22 @@ public class BundlingPluginFeatures implements PluginFeatures {
.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
return mainSourceSet.getRuntimeClasspath();
});
this.singlePublishedArtifact.addCandidate(new ArchivePublishArtifact(bootJar));
}
private void configureBootArchivesUpload(Project project) {
Upload upload = project.getTasks().withType(Upload.class)
.findByName("uploadBootArchives");
if (upload == null) {
return;
}
clearConfigurationMappings(upload);
}
private void clearConfigurationMappings(Upload upload) {
upload.getRepositories().withType(MavenResolver.class, (resolver) -> {
resolver.getPom().getScopeMappings().getMappings().clear();
});
}
private Configuration providedRuntimeConfiguration(Project project) {

@ -0,0 +1,46 @@
/*
* Copyright 2012-2017 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.gradle.bundling;
import org.gradle.api.artifacts.PublishArtifact;
import org.gradle.api.artifacts.PublishArtifactSet;
/**
* A wrapper for a {@PublishArtifactSet} that ensures that only a single artifact is
* published, with a war file taking precedence over a jar file.
*
* @author Andy Wilkinson
*/
class SinglePublishedArtifact {
private final PublishArtifactSet artifacts;
private PublishArtifact currentArtifact;
SinglePublishedArtifact(PublishArtifactSet artifacts) {
this.artifacts = artifacts;
}
void addCandidate(PublishArtifact candidate) {
if (this.currentArtifact == null || "war".equals(candidate.getExtension())) {
this.artifacts.clear();
this.artifacts.add(candidate);
this.currentArtifact = candidate;
}
}
}

@ -0,0 +1,74 @@
/*
* Copyright 2012-2017 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.gradle.bundling;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.gradle.testkit.GradleBuild;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for uploading Boot jars and wars using Gradle's Maven plugin.
*
* @author Andy Wilkinson
*/
public class MavenIntegrationTests {
@Rule
public final GradleBuild gradleBuild = new GradleBuild();
@Test
public void bootJarCanBeUploaded() throws FileNotFoundException, IOException {
BuildResult result = this.gradleBuild.build("uploadBootArchives");
assertThat(result.task(":uploadBootArchives").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
assertThat(artifactWithSuffix("jar")).isFile();
assertThat(artifactWithSuffix("pom")).is(pomWith().groupId("com.example")
.artifactId(this.gradleBuild.getProjectDir().getName()).version("1.0")
.noPackaging().noDependencies());
}
@Test
public void bootWarCanBeUploaded() throws IOException {
BuildResult result = this.gradleBuild.build("uploadBootArchives");
assertThat(result.task(":uploadBootArchives").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
assertThat(artifactWithSuffix("war")).isFile();
assertThat(artifactWithSuffix("pom")).is(pomWith().groupId("com.example")
.artifactId(this.gradleBuild.getProjectDir().getName()).version("1.0")
.packaging("war").noDependencies());
}
private File artifactWithSuffix(String suffix) {
String name = this.gradleBuild.getProjectDir().getName();
return new File(new File(this.gradleBuild.getProjectDir(), "build/repo"),
String.format("com/example/%s/1.0/%s-1.0.%s", name, name, suffix));
}
private PomCondition pomWith() {
return new PomCondition();
}
}

@ -0,0 +1,111 @@
/*
* Copyright 2012-2017 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.gradle.bundling;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import org.assertj.core.api.Condition;
import org.assertj.core.description.Description;
import org.assertj.core.description.TextDescription;
import org.springframework.util.FileCopyUtils;
/**
* AssertJ {@link Condition} for asserting the contents of a pom file.
*
* @author Andy Wilkinson
*/
class PomCondition extends Condition<File> {
private Set<String> expectedContents;
private Set<String> notExpectedContents;
PomCondition() {
this(new HashSet<String>(), new HashSet<String>());
}
private PomCondition(Set<String> expectedContents, Set<String> notExpectedContents) {
super(new TextDescription("Pom file containing %s and not containing %s",
expectedContents, notExpectedContents));
this.expectedContents = expectedContents;
this.notExpectedContents = notExpectedContents;
}
@Override
public boolean matches(File pom) {
try {
String contents = FileCopyUtils.copyToString(new FileReader(pom));
for (String expected : this.expectedContents) {
if (!contents.contains(expected)) {
return false;
}
}
for (String notExpected : this.notExpectedContents) {
if (contents.contains(notExpected)) {
return false;
}
}
}
catch (IOException ex) {
throw new RuntimeException(ex);
}
return true;
}
@Override
public Description description() {
return new TextDescription("Pom file containing %s and not containing %s",
this.expectedContents, this.notExpectedContents);
}
PomCondition groupId(String groupId) {
this.expectedContents.add(String.format("<groupId>%s</groupId>", groupId));
return this;
}
PomCondition artifactId(String artifactId) {
this.expectedContents
.add(String.format("<artifactId>%s</artifactId>", artifactId));
return this;
}
PomCondition version(String version) {
this.expectedContents.add(String.format("<version>%s</version>", version));
return this;
}
PomCondition packaging(String packaging) {
this.expectedContents.add(String.format("<packaging>%s</packaging>", packaging));
return this;
}
PomCondition noDependencies() {
this.notExpectedContents.add("<dependencies>");
return this;
}
PomCondition noPackaging() {
this.notExpectedContents.add("<packaging>");
return this;
}
}

@ -56,8 +56,7 @@ public class GradleBuild implements TestRule {
@Override
public Statement apply(Statement base, Description description) {
String name = description.getTestClass().getSimpleName() + ".gradle";
URL scriptUrl = description.getTestClass().getResource(name);
URL scriptUrl = findDefaultScript(description);
if (scriptUrl != null) {
script(scriptUrl.getFile());
}
@ -77,6 +76,24 @@ public class GradleBuild implements TestRule {
}, description);
}
private URL findDefaultScript(Description description) {
URL scriptUrl = getScriptForTestMethod(description);
if (scriptUrl != null) {
return scriptUrl;
}
return getScriptForTestClass(description.getTestClass());
}
private URL getScriptForTestMethod(Description description) {
return description.getTestClass()
.getResource(description.getTestClass().getSimpleName() + "-"
+ description.getMethodName() + ".gradle");
}
private URL getScriptForTestClass(Class<?> testClass) {
return testClass.getResource(testClass.getSimpleName() + ".gradle");
}
private void before() throws IOException {
this.projectDir = this.temp.newFolder();
}
@ -123,7 +140,15 @@ public class GradleBuild implements TestRule {
}
}
public static String getBootVersion() {
public File getProjectDir() {
return this.projectDir;
}
public void setProjectDir(File projectDir) {
this.projectDir = projectDir;
}
private static String getBootVersion() {
return evaluateExpression(
"/*[local-name()='project']/*[local-name()='parent']/*[local-name()='version']"
+ "/text()");

@ -0,0 +1,24 @@
buildscript {
dependencies {
classpath files(pluginClasspath.split(','))
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'maven'
bootJar {
mainClass = 'com.example.Application'
}
group = 'com.example'
version = '1.0'
uploadBootArchives {
repositories {
mavenDeployer {
repository(url: "file:$buildDir/repo")
}
}
}

@ -0,0 +1,24 @@
buildscript {
dependencies {
classpath files(pluginClasspath.split(','))
}
}
apply plugin: 'war'
apply plugin: 'org.springframework.boot'
apply plugin: 'maven'
bootWar {
mainClass = 'com.example.Application'
}
group = 'com.example'
version = '1.0'
uploadBootArchives {
repositories {
mavenDeployer {
repository(url: "file:$buildDir/repo")
}
}
}
Loading…
Cancel
Save