Add support for using ${application.title} in startup banners
This commit introduces a new property, application.title, that can be used in a banner. Its value is resolved from the application manifest's Implementation-Title attribute. Closes gh-4603
This commit is contained in:
parent
a4baacc549
commit
884cae6f8d
|
|
@ -60,7 +60,8 @@ You can use the following variables inside your `banner.txt` file:
|
||||||
| Variable | Description
|
| Variable | Description
|
||||||
|
|
||||||
|`${application.version}`
|
|`${application.version}`
|
||||||
|The version number of your application as declared in `MANIFEST.MF`. For example `Implementation-Version: 1.0` is printed as `1.0`.
|
|The version number of your application as declared in `MANIFEST.MF`. For example
|
||||||
|
`Implementation-Version: 1.0` is printed as `1.0`.
|
||||||
|
|
||||||
|`${application.formatted-version}`
|
|`${application.formatted-version}`
|
||||||
|The version number of your application as declared in `MANIFEST.MF` formatted for
|
|The version number of your application as declared in `MANIFEST.MF` formatted for
|
||||||
|
|
@ -76,6 +77,10 @@ brackets and prefixed with `v`). For example `(v{spring-boot-version})`.
|
||||||
|`${Ansi.NAME}` (or `${AnsiColor.NAME}`, `${AnsiBackground.NAME}`, `${AnsiStyle.NAME}`)
|
|`${Ansi.NAME}` (or `${AnsiColor.NAME}`, `${AnsiBackground.NAME}`, `${AnsiStyle.NAME}`)
|
||||||
|Where `NAME` is the name of an ANSI escape code. See
|
|Where `NAME` is the name of an ANSI escape code. See
|
||||||
{sc-spring-boot}/ansi/AnsiPropertySource.{sc-ext}[`AnsiPropertySource`] for details.
|
{sc-spring-boot}/ansi/AnsiPropertySource.{sc-ext}[`AnsiPropertySource`] for details.
|
||||||
|
|
||||||
|
|`${application.title}`
|
||||||
|
|The title of your application as declared in `MANIFEST.MF`. For example
|
||||||
|
`Implementation-Title: MyApp` is printed as `MyApp`.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
TIP: The `SpringApplication.setBanner(...)` method can be used if you want to generate
|
TIP: The `SpringApplication.setBanner(...)` method can be used if you want to generate
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ package org.springframework.boot;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -40,6 +41,7 @@ import org.springframework.util.StreamUtils;
|
||||||
* Banner implementation that prints from a source {@link Resource}.
|
* Banner implementation that prints from a source {@link Resource}.
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
|
* @author Vedran Pavic
|
||||||
* @since 1.2.0
|
* @since 1.2.0
|
||||||
*/
|
*/
|
||||||
public class ResourceBanner implements Banner {
|
public class ResourceBanner implements Banner {
|
||||||
|
|
@ -80,6 +82,7 @@ public class ResourceBanner implements Banner {
|
||||||
resolvers.add(environment);
|
resolvers.add(environment);
|
||||||
resolvers.add(getVersionResolver(sourceClass));
|
resolvers.add(getVersionResolver(sourceClass));
|
||||||
resolvers.add(getAnsiResolver());
|
resolvers.add(getAnsiResolver());
|
||||||
|
resolvers.add(getTitleResolver(sourceClass));
|
||||||
return resolvers;
|
return resolvers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,4 +127,18 @@ public class ResourceBanner implements Banner {
|
||||||
return new PropertySourcesPropertyResolver(sources);
|
return new PropertySourcesPropertyResolver(sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PropertyResolver getTitleResolver(Class<?> sourceClass) {
|
||||||
|
MutablePropertySources sources = new MutablePropertySources();
|
||||||
|
String applicationTitle = getApplicationTitle(sourceClass);
|
||||||
|
Map<String, Object> titleMap = Collections.<String, Object>singletonMap(
|
||||||
|
"application.title", (applicationTitle == null ? "" : applicationTitle));
|
||||||
|
sources.addFirst(new MapPropertySource("title", titleMap));
|
||||||
|
return new PropertySourcesPropertyResolver(sources);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getApplicationTitle(Class<?> sourceClass) {
|
||||||
|
Package sourcePackage = (sourceClass == null ? null : sourceClass.getPackage());
|
||||||
|
return (sourcePackage == null ? null : sourcePackage.getImplementationTitle());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ import static org.junit.Assert.assertThat;
|
||||||
* Tests for {@link ResourceBanner}.
|
* Tests for {@link ResourceBanner}.
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
|
* @author Vedran Pavic
|
||||||
*/
|
*/
|
||||||
public class ResourceBannerTests {
|
public class ResourceBannerTests {
|
||||||
|
|
||||||
|
|
@ -51,7 +52,7 @@ public class ResourceBannerTests {
|
||||||
public void renderVersions() throws Exception {
|
public void renderVersions() throws Exception {
|
||||||
Resource resource = new ByteArrayResource(
|
Resource resource = new ByteArrayResource(
|
||||||
"banner ${a} ${spring-boot.version} ${application.version}".getBytes());
|
"banner ${a} ${spring-boot.version} ${application.version}".getBytes());
|
||||||
String banner = printBanner(resource, "10.2", "2.0");
|
String banner = printBanner(resource, "10.2", "2.0", null);
|
||||||
assertThat(banner, startsWith("banner 1 10.2 2.0"));
|
assertThat(banner, startsWith("banner 1 10.2 2.0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,7 +60,7 @@ public class ResourceBannerTests {
|
||||||
public void renderWithoutVersions() throws Exception {
|
public void renderWithoutVersions() throws Exception {
|
||||||
Resource resource = new ByteArrayResource(
|
Resource resource = new ByteArrayResource(
|
||||||
"banner ${a} ${spring-boot.version} ${application.version}".getBytes());
|
"banner ${a} ${spring-boot.version} ${application.version}".getBytes());
|
||||||
String banner = printBanner(resource, null, null);
|
String banner = printBanner(resource, null, null, null);
|
||||||
assertThat(banner, startsWith("banner 1 "));
|
assertThat(banner, startsWith("banner 1 "));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,7 +69,7 @@ public class ResourceBannerTests {
|
||||||
Resource resource = new ByteArrayResource(
|
Resource resource = new ByteArrayResource(
|
||||||
"banner ${a}${spring-boot.formatted-version}${application.formatted-version}"
|
"banner ${a}${spring-boot.formatted-version}${application.formatted-version}"
|
||||||
.getBytes());
|
.getBytes());
|
||||||
String banner = printBanner(resource, "10.2", "2.0");
|
String banner = printBanner(resource, "10.2", "2.0", null);
|
||||||
assertThat(banner, startsWith("banner 1 (v10.2) (v2.0)"));
|
assertThat(banner, startsWith("banner 1 (v10.2) (v2.0)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,7 +78,7 @@ public class ResourceBannerTests {
|
||||||
Resource resource = new ByteArrayResource(
|
Resource resource = new ByteArrayResource(
|
||||||
"banner ${a}${spring-boot.formatted-version}${application.formatted-version}"
|
"banner ${a}${spring-boot.formatted-version}${application.formatted-version}"
|
||||||
.getBytes());
|
.getBytes());
|
||||||
String banner = printBanner(resource, null, null);
|
String banner = printBanner(resource, null, null, null);
|
||||||
assertThat(banner, startsWith("banner 1"));
|
assertThat(banner, startsWith("banner 1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,7 +87,7 @@ public class ResourceBannerTests {
|
||||||
Resource resource = new ByteArrayResource(
|
Resource resource = new ByteArrayResource(
|
||||||
"${Ansi.RED}This is red.${Ansi.NORMAL}".getBytes());
|
"${Ansi.RED}This is red.${Ansi.NORMAL}".getBytes());
|
||||||
AnsiOutput.setEnabled(AnsiOutput.Enabled.ALWAYS);
|
AnsiOutput.setEnabled(AnsiOutput.Enabled.ALWAYS);
|
||||||
String banner = printBanner(resource, null, null);
|
String banner = printBanner(resource, null, null, null);
|
||||||
assertThat(banner, startsWith("\u001B[31mThis is red.\u001B[0m"));
|
assertThat(banner, startsWith("\u001B[31mThis is red.\u001B[0m"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,14 +96,30 @@ public class ResourceBannerTests {
|
||||||
Resource resource = new ByteArrayResource(
|
Resource resource = new ByteArrayResource(
|
||||||
"${Ansi.RED}This is red.${Ansi.NORMAL}".getBytes());
|
"${Ansi.RED}This is red.${Ansi.NORMAL}".getBytes());
|
||||||
AnsiOutput.setEnabled(AnsiOutput.Enabled.NEVER);
|
AnsiOutput.setEnabled(AnsiOutput.Enabled.NEVER);
|
||||||
String banner = printBanner(resource, null, null);
|
String banner = printBanner(resource, null, null, null);
|
||||||
assertThat(banner, startsWith("This is red."));
|
assertThat(banner, startsWith("This is red."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void renderWithTitle() throws Exception {
|
||||||
|
Resource resource = new ByteArrayResource(
|
||||||
|
"banner ${application.title} ${a}".getBytes());
|
||||||
|
String banner = printBanner(resource, null, null, "title");
|
||||||
|
assertThat(banner, startsWith("banner title 1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void renderWithoutTitle() throws Exception {
|
||||||
|
Resource resource = new ByteArrayResource(
|
||||||
|
"banner ${application.title} ${a}".getBytes());
|
||||||
|
String banner = printBanner(resource, null, null, null);
|
||||||
|
assertThat(banner, startsWith("banner 1"));
|
||||||
|
}
|
||||||
|
|
||||||
private String printBanner(Resource resource, String bootVersion,
|
private String printBanner(Resource resource, String bootVersion,
|
||||||
String applicationVersion) {
|
String applicationVersion, String applicationTitle) {
|
||||||
ResourceBanner banner = new MockResourceBanner(resource, bootVersion,
|
ResourceBanner banner = new MockResourceBanner(resource, bootVersion,
|
||||||
applicationVersion);
|
applicationVersion, applicationTitle);
|
||||||
ConfigurableEnvironment environment = new MockEnvironment();
|
ConfigurableEnvironment environment = new MockEnvironment();
|
||||||
Map<String, Object> source = Collections.<String, Object>singletonMap("a", "1");
|
Map<String, Object> source = Collections.<String, Object>singletonMap("a", "1");
|
||||||
environment.getPropertySources().addLast(new MapPropertySource("map", source));
|
environment.getPropertySources().addLast(new MapPropertySource("map", source));
|
||||||
|
|
@ -117,11 +134,14 @@ public class ResourceBannerTests {
|
||||||
|
|
||||||
private final String applicationVersion;
|
private final String applicationVersion;
|
||||||
|
|
||||||
|
private final String applicationTitle;
|
||||||
|
|
||||||
MockResourceBanner(Resource resource, String bootVersion,
|
MockResourceBanner(Resource resource, String bootVersion,
|
||||||
String applicationVersion) {
|
String applicationVersion, String applicationTitle) {
|
||||||
super(resource);
|
super(resource);
|
||||||
this.bootVersion = bootVersion;
|
this.bootVersion = bootVersion;
|
||||||
this.applicationVersion = applicationVersion;
|
this.applicationVersion = applicationVersion;
|
||||||
|
this.applicationTitle = applicationTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -134,6 +154,11 @@ public class ResourceBannerTests {
|
||||||
return this.applicationVersion;
|
return this.applicationVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getApplicationTitle(Class<?> sourceClass) {
|
||||||
|
return this.applicationTitle;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue