Simply Gradle plugin DSL for configuring a jar or war's launch script

Closes gh-9948
This commit is contained in:
Andy Wilkinson 2017-09-21 06:55:37 +01:00
parent 56d82eb68f
commit 96bf799b5c
12 changed files with 57 additions and 51 deletions

View File

@ -14,7 +14,6 @@ bootJar {
// tag::custom-launch-script[] // tag::custom-launch-script[]
bootJar { bootJar {
launchScript { launchScript {
included = true
script = file('src/custom.script') script = file('src/custom.script')
} }
} }

View File

@ -13,8 +13,6 @@ bootJar {
// tag::include-launch-script[] // tag::include-launch-script[]
bootJar { bootJar {
launchScript { launchScript()
included = true
}
} }
// end::include-launch-script[] // end::include-launch-script[]

View File

@ -14,7 +14,6 @@ bootJar {
// tag::launch-script-properties[] // tag::launch-script-properties[]
bootJar { bootJar {
launchScript { launchScript {
included = true
properties 'logFilename': 'example-app.log' properties 'logFilename': 'example-app.log'
} }
} }

View File

@ -67,17 +67,24 @@ public interface BootArchive extends Task {
void requiresUnpack(Spec<FileTreeElement> spec); void requiresUnpack(Spec<FileTreeElement> spec);
/** /**
* Returns the {@link LaunchScriptConfiguration} that will control the script, if any, * Returns the {@link LaunchScriptConfiguration} that will control the script that is
* that is prepended to the archive. * prepended to the archive.
* *
* @return the launch script configuration * @return the launch script configuration, or {@code null} if the launch script has
* not been configured.
*/ */
@Input @Input
@Optional
LaunchScriptConfiguration getLaunchScript(); LaunchScriptConfiguration getLaunchScript();
/** /**
* Applies the given {@code action} to the {@link LaunchScriptConfiguration} of this * Configures the archive to have a prepended launch script.
* archive. */
void launchScript();
/**
* Configures the archive to have a prepended launch script, customizing its
* configuration using the given {@code action}.
* *
* @param action the action to apply * @param action the action to apply
*/ */

View File

@ -61,7 +61,7 @@ class BootArchiveSupport {
private final String loaderMainClass; private final String loaderMainClass;
private LaunchScriptConfiguration launchScript = new LaunchScriptConfiguration(); private LaunchScriptConfiguration launchScript;
private boolean excludeDevtools = true; private boolean excludeDevtools = true;

View File

@ -97,9 +97,14 @@ public class BootJar extends Jar implements BootArchive {
return this.support.getLaunchScript(); return this.support.getLaunchScript();
} }
@Override
public void launchScript() {
enableLaunchScriptIfNecessary();
}
@Override @Override
public void launchScript(Action<LaunchScriptConfiguration> action) { public void launchScript(Action<LaunchScriptConfiguration> action) {
action.execute(getLaunchScript()); action.execute(enableLaunchScriptIfNecessary());
} }
@Override @Override
@ -142,4 +147,13 @@ public class BootJar extends Jar implements BootArchive {
return ZipCompression.DEFLATED; return ZipCompression.DEFLATED;
} }
private LaunchScriptConfiguration enableLaunchScriptIfNecessary() {
LaunchScriptConfiguration launchScript = this.support.getLaunchScript();
if (launchScript == null) {
launchScript = new LaunchScriptConfiguration();
this.support.setLaunchScript(launchScript);
}
return launchScript;
}
} }

View File

@ -91,9 +91,14 @@ public class BootWar extends War implements BootArchive {
return this.support.getLaunchScript(); return this.support.getLaunchScript();
} }
@Override
public void launchScript() {
enableLaunchScriptIfNecessary();
}
@Override @Override
public void launchScript(Action<LaunchScriptConfiguration> action) { public void launchScript(Action<LaunchScriptConfiguration> action) {
action.execute(getLaunchScript()); action.execute(enableLaunchScriptIfNecessary());
} }
/** /**
@ -150,4 +155,13 @@ public class BootWar extends War implements BootArchive {
return ZipCompression.DEFLATED; return ZipCompression.DEFLATED;
} }
private LaunchScriptConfiguration enableLaunchScriptIfNecessary() {
LaunchScriptConfiguration launchScript = this.support.getLaunchScript();
if (launchScript == null) {
launchScript = new LaunchScriptConfiguration();
this.support.setLaunchScript(launchScript);
}
return launchScript;
}
} }

View File

@ -183,7 +183,7 @@ class BootZipCopyAction implements CopyAction {
private void writeLaunchScriptIfNecessary(FileOutputStream fileStream) { private void writeLaunchScriptIfNecessary(FileOutputStream fileStream) {
try { try {
if (this.launchScript.isIncluded()) { if (this.launchScript != null) {
fileStream.write(new DefaultLaunchScript(this.launchScript.getScript(), fileStream.write(new DefaultLaunchScript(this.launchScript.getScript(),
this.launchScript.getProperties()).toByteArray()); this.launchScript.getProperties()).toByteArray());
this.output.setExecutable(true); this.output.setExecutable(true);

View File

@ -32,30 +32,10 @@ import org.springframework.boot.loader.tools.FileUtils;
*/ */
public class LaunchScriptConfiguration implements Serializable { public class LaunchScriptConfiguration implements Serializable {
private boolean included = false;
private final Map<String, String> properties = new HashMap<>(); private final Map<String, String> properties = new HashMap<>();
private File script; private File script;
/**
* Returns whether the launch script is included. Defaults to {@code false}.
*
* @return {@code true} is the script is included, otherwise {@code false}.
*/
public boolean isIncluded() {
return this.included;
}
/**
* Sets whether the launch script is included. Defaults to {@code false}.
*
* @param included {@code true} is the script is included, otherwise {@code false}.
*/
public void setIncluded(boolean included) {
this.included = included;
}
/** /**
* Returns the properties that are applied to the launch script when it's being * Returns the properties that are applied to the launch script when it's being
* including in the executable archive. * including in the executable archive.
@ -100,7 +80,6 @@ public class LaunchScriptConfiguration implements Serializable {
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + (this.included ? 1231 : 1237);
result = prime * result result = prime * result
+ ((this.properties == null) ? 0 : this.properties.hashCode()); + ((this.properties == null) ? 0 : this.properties.hashCode());
result = prime * result + ((this.script == null) ? 0 : this.script.hashCode()); result = prime * result + ((this.script == null) ? 0 : this.script.hashCode());
@ -119,9 +98,6 @@ public class LaunchScriptConfiguration implements Serializable {
return false; return false;
} }
LaunchScriptConfiguration other = (LaunchScriptConfiguration) obj; LaunchScriptConfiguration other = (LaunchScriptConfiguration) obj;
if (this.included != other.included) {
return false;
}
if (!this.properties.equals(other.properties)) { if (!this.properties.equals(other.properties)) {
return false; return false;
} }

View File

@ -184,7 +184,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
public void launchScriptCanBePrepended() throws IOException { public void launchScriptCanBePrepended() throws IOException {
this.task.setMainClass("com.example.Main"); this.task.setMainClass("com.example.Main");
this.task.getLaunchScript().setIncluded(true); this.task.launchScript();
this.task.execute(); this.task.execute();
assertThat(Files.readAllBytes(this.task.getArchivePath().toPath())) assertThat(Files.readAllBytes(this.task.getArchivePath().toPath()))
.startsWith(new DefaultLaunchScript(null, null).toByteArray()); .startsWith(new DefaultLaunchScript(null, null).toByteArray());
@ -201,12 +201,10 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
public void customLaunchScriptCanBePrepended() throws IOException { public void customLaunchScriptCanBePrepended() throws IOException {
this.task.setMainClass("com.example.Main"); this.task.setMainClass("com.example.Main");
LaunchScriptConfiguration launchScript = this.task.getLaunchScript();
launchScript.setIncluded(true);
File customScript = this.temp.newFile("custom.script"); File customScript = this.temp.newFile("custom.script");
Files.write(customScript.toPath(), Arrays.asList("custom script"), Files.write(customScript.toPath(), Arrays.asList("custom script"),
StandardOpenOption.CREATE); StandardOpenOption.CREATE);
launchScript.setScript(customScript); this.task.launchScript((configuration) -> configuration.setScript(customScript));
this.task.execute(); this.task.execute();
assertThat(Files.readAllBytes(this.task.getArchivePath().toPath())) assertThat(Files.readAllBytes(this.task.getArchivePath().toPath()))
.startsWith("custom script".getBytes()); .startsWith("custom script".getBytes());
@ -215,9 +213,8 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
public void launchScriptPropertiesAreReplaced() throws IOException { public void launchScriptPropertiesAreReplaced() throws IOException {
this.task.setMainClass("com.example.Main"); this.task.setMainClass("com.example.Main");
LaunchScriptConfiguration launchScript = this.task.getLaunchScript(); this.task.launchScript((configuration) -> configuration.getProperties()
launchScript.setIncluded(true); .put("initInfoProvides", "test property value"));
launchScript.getProperties().put("initInfoProvides", "test property value");
this.task.execute(); this.task.execute();
assertThat(Files.readAllBytes(this.task.getArchivePath().toPath())) assertThat(Files.readAllBytes(this.task.getArchivePath().toPath()))
.containsSequence("test property value".getBytes()); .containsSequence("test property value".getBytes());

View File

@ -9,8 +9,9 @@ apply plugin: 'org.springframework.boot'
bootJar { bootJar {
mainClass = 'com.example.Application' mainClass = 'com.example.Application'
launchScript { if (project.hasProperty('includeLaunchScript') ? includeLaunchScript : false) {
included = project.hasProperty('includeLaunchScript') ? includeLaunchScript : false launchScript {
properties 'prop' : project.hasProperty('launchScriptProperty') ? launchScriptProperty : 'default' properties 'prop' : project.hasProperty('launchScriptProperty') ? launchScriptProperty : 'default'
}
} }
} }

View File

@ -9,8 +9,9 @@ apply plugin: 'org.springframework.boot'
bootWar { bootWar {
mainClass = 'com.example.Application' mainClass = 'com.example.Application'
launchScript { if (project.hasProperty('includeLaunchScript') ? includeLaunchScript : false) {
included = project.hasProperty('includeLaunchScript') ? includeLaunchScript : false launchScript {
properties 'prop' : project.hasProperty('launchScriptProperty') ? launchScriptProperty : 'default' properties 'prop' : project.hasProperty('launchScriptProperty') ? launchScriptProperty : 'default'
}
} }
} }