Provide sensible defaults for launch script properties when using Gradle

Closes gh-4458
This commit is contained in:
Andy Wilkinson
2018-06-22 12:25:35 +01:00
parent b01efb2392
commit a097f923c1
6 changed files with 211 additions and 36 deletions

View File

@@ -184,7 +184,7 @@ public class BootJar extends Jar implements BootArchive {
private LaunchScriptConfiguration enableLaunchScriptIfNecessary() {
LaunchScriptConfiguration launchScript = this.support.getLaunchScript();
if (launchScript == null) {
launchScript = new LaunchScriptConfiguration();
launchScript = new LaunchScriptConfiguration(this);
this.support.setLaunchScript(launchScript);
}
return launchScript;

View File

@@ -162,7 +162,7 @@ public class BootWar extends War implements BootArchive {
private LaunchScriptConfiguration enableLaunchScriptIfNecessary() {
LaunchScriptConfiguration launchScript = this.support.getLaunchScript();
if (launchScript == null) {
launchScript = new LaunchScriptConfiguration();
launchScript = new LaunchScriptConfiguration(this);
this.support.setLaunchScript(launchScript);
}
return launchScript;

View File

@@ -22,6 +22,9 @@ import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.gradle.api.Project;
import org.gradle.api.tasks.bundling.AbstractArchiveTask;
import org.springframework.boot.loader.tools.FileUtils;
/**
@@ -37,6 +40,19 @@ public class LaunchScriptConfiguration implements Serializable {
private File script;
public LaunchScriptConfiguration() {
}
LaunchScriptConfiguration(AbstractArchiveTask archiveTask) {
Project project = archiveTask.getProject();
putIfMissing(this.properties, "initInfoProvides", archiveTask.getBaseName());
putIfMissing(this.properties, "initInfoShortDescription",
removeLineBreaks(project.getDescription()), archiveTask.getBaseName());
putIfMissing(this.properties, "initInfoDescription",
augmentLineBreaks(project.getDescription()), archiveTask.getBaseName());
}
/**
* Returns the properties that are applied to the launch script when it's being
* including in the executable archive.
@@ -121,4 +137,24 @@ public class LaunchScriptConfiguration implements Serializable {
}
}
private String removeLineBreaks(String string) {
return (string != null ? string.replaceAll("\\s+", " ") : null);
}
private String augmentLineBreaks(String string) {
return (string != null ? string.replaceAll("\n", "\n# ") : null);
}
private void putIfMissing(Map<String, String> properties, String key,
String... valueCandidates) {
if (!properties.containsKey(key)) {
for (String candidate : valueCandidates) {
if (candidate != null && !candidate.isEmpty()) {
properties.put(key, candidate);
return;
}
}
}
}
}

View File

@@ -24,7 +24,9 @@ import java.nio.file.attribute.PosixFilePermission;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@@ -64,6 +66,8 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
private final String classesPath;
private Project project;
private T task;
protected AbstractBootArchiveTests(Class<T> taskClass, String launcherClass,
@@ -77,10 +81,12 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Before
public void createTask() {
try {
Project project = ProjectBuilder.builder()
.withProjectDir(this.temp.newFolder()).build();
this.project = ProjectBuilder.builder().withProjectDir(this.temp.newFolder())
.build();
this.project
.setDescription("Test project for " + this.taskClass.getSimpleName());
this.task = configure(
project.getTasks().create("testArchive", this.taskClass));
this.project.getTasks().create("testArchive", this.taskClass));
}
catch (IOException ex) {
throw new RuntimeException(ex);
@@ -186,8 +192,12 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
this.task.setMainClassName("com.example.Main");
this.task.launchScript();
this.task.execute();
Map<String, String> properties = new HashMap<>();
properties.put("initInfoProvides", this.task.getBaseName());
properties.put("initInfoShortDescription", this.project.getDescription());
properties.put("initInfoDescription", this.project.getDescription());
assertThat(Files.readAllBytes(this.task.getArchivePath().toPath()))
.startsWith(new DefaultLaunchScript(null, null).toByteArray());
.startsWith(new DefaultLaunchScript(null, properties).toByteArray());
try {
Set<PosixFilePermission> permissions = Files
.getPosixFilePermissions(this.task.getArchivePath().toPath());
@@ -211,13 +221,20 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
}
@Test
public void launchScriptPropertiesAreReplaced() throws IOException {
public void launchScriptInitInfoPropertiesCanBeCustomized() throws IOException {
this.task.setMainClassName("com.example.Main");
this.task.launchScript((configuration) -> configuration.getProperties()
.put("initInfoProvides", "test property value"));
this.task.launchScript((configuration) -> {
configuration.getProperties().put("initInfoProvides", "provides");
configuration.getProperties().put("initInfoShortDescription",
"short description");
configuration.getProperties().put("initInfoDescription", "description");
});
this.task.execute();
assertThat(Files.readAllBytes(this.task.getArchivePath().toPath()))
.containsSequence("test property value".getBytes());
byte[] bytes = Files.readAllBytes(this.task.getArchivePath().toPath());
assertThat(bytes).containsSequence("Provides: provides".getBytes());
assertThat(bytes)
.containsSequence("Short-Description: short description".getBytes());
assertThat(bytes).containsSequence("Description: description".getBytes());
}
@Test

View File

@@ -0,0 +1,93 @@
/*
* Copyright 2012-2018 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.tasks.bundling;
import org.gradle.api.Project;
import org.gradle.api.tasks.bundling.AbstractArchiveTask;
import org.junit.Before;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link LaunchScriptConfiguration}.
*
* @author Andy Wilkinson
*/
public class LaunchScriptConfigurationTests {
private final AbstractArchiveTask task = mock(AbstractArchiveTask.class);
private final Project project = mock(Project.class);
@Before
public void setUp() {
given(this.task.getProject()).willReturn(this.project);
}
@Test
public void initInfoProvidesUsesArchiveBaseNameByDefault() {
given(this.task.getBaseName()).willReturn("base-name");
assertThat(new LaunchScriptConfiguration(this.task).getProperties())
.containsEntry("initInfoProvides", "base-name");
}
@Test
public void initInfoShortDescriptionUsesDescriptionByDefault() {
given(this.project.getDescription()).willReturn("Project description");
assertThat(new LaunchScriptConfiguration(this.task).getProperties())
.containsEntry("initInfoShortDescription", "Project description");
}
@Test
public void initInfoShortDescriptionUsesArchiveBaseNameWhenDescriptionIsNull() {
given(this.task.getBaseName()).willReturn("base-name");
assertThat(new LaunchScriptConfiguration(this.task).getProperties())
.containsEntry("initInfoShortDescription", "base-name");
}
@Test
public void initInfoShortDescriptionUsesSingleLineVersionOfMultiLineProjectDescription() {
given(this.project.getDescription()).willReturn("Project\ndescription");
assertThat(new LaunchScriptConfiguration(this.task).getProperties())
.containsEntry("initInfoShortDescription", "Project description");
}
@Test
public void initInfoDescriptionUsesArchiveBaseNameWhenDescriptionIsNull() {
given(this.task.getBaseName()).willReturn("base-name");
assertThat(new LaunchScriptConfiguration(this.task).getProperties())
.containsEntry("initInfoDescription", "base-name");
}
@Test
public void initInfoDescriptionUsesProjectDescriptionByDefault() {
given(this.project.getDescription()).willReturn("Project description");
assertThat(new LaunchScriptConfiguration(this.task).getProperties())
.containsEntry("initInfoDescription", "Project description");
}
@Test
public void initInfoDescriptionUsesCorrectlyFormattedMultiLineProjectDescription() {
given(this.project.getDescription()).willReturn("The\nproject\ndescription");
assertThat(new LaunchScriptConfiguration(this.task).getProperties())
.containsEntry("initInfoDescription", "The\n# project\n# description");
}
}