Collect and display build information

This commit updates the Maven plugin to generate a
`META-INF/boot/build.properties` file with various build-specific
settings (group, artifact, name, version and build time). Additionally,
the plugin can be configured to write an arbitrary number of additional
properties.

A new `BuildProperties` bean is automatically exposed when such a file is
present. If that bean is present, an `InfoContributor` is automatically
created to expose that information under the `build` key.

As for the git contributor, it is possible to only display the core
settings or everything using the `management.info.build.mode` property.

See gh-2559
This commit is contained in:
Stephane Nicoll
2016-03-04 13:25:23 +01:00
parent 3e6b584953
commit dddea70985
31 changed files with 1024 additions and 112 deletions

View File

@@ -22,9 +22,11 @@ import java.util.Properties;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnResource;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.info.BuildProperties;
import org.springframework.boot.info.GitProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionContext;
@@ -60,6 +62,13 @@ public class ProjectInfoAutoConfiguration {
return new GitProperties(loadFrom(this.properties.getGit().getLocation(), "git"));
}
@ConditionalOnResource(resources = "${spring.info.build.location:classpath:META-INF/boot/build.properties}")
@ConditionalOnMissingBean
@Bean
public BuildProperties buildProperties() throws Exception {
return new BuildProperties(loadFrom(this.properties.getBuild().getLocation(), "build"));
}
protected Properties loadFrom(Resource location, String prefix) throws IOException {
String p = prefix.endsWith(".") ? prefix : prefix + ".";
Properties source = PropertiesLoaderUtils.loadProperties(location);
@@ -72,7 +81,6 @@ public class ProjectInfoAutoConfiguration {
return target;
}
static class GitResourceAvailableCondition extends SpringBootCondition {
private final ResourceLoader defaultResourceLoader = new DefaultResourceLoader();

View File

@@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.info;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
/**
@@ -30,8 +31,14 @@ import org.springframework.core.io.Resource;
@ConfigurationProperties("spring.info")
public class ProjectInfoProperties {
private final Build build = new Build();
private final Git git = new Git();
public Build getBuild() {
return this.build;
}
public Git getGit() {
return this.git;
}
@@ -46,13 +53,34 @@ public class ProjectInfoProperties {
getGit().setLocation(defaultGitLocation);
}
/**
* Build specific info properties.
*/
public static class Build {
/**
* Location of the generated build.properties file.
*/
private Resource location = new ClassPathResource("META-INF/boot/build.properties");
public Resource getLocation() {
return this.location;
}
public void setLocation(Resource location) {
this.location = location;
}
}
/**
* Git specific info properties.
*/
public static class Git {
/**
* Location of the generated git info properties file.
* Location of the generated git.properties file.
*/
private Resource location;

View File

@@ -23,6 +23,7 @@ import org.junit.After;
import org.junit.Test;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.info.BuildProperties;
import org.springframework.boot.info.GitProperties;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -82,12 +83,48 @@ public class ProjectInfoAutoConfigurationTests {
@Test
public void gitPropertiesFallbackWithGitPropertiesBean() {
load(CustomGitPropertiesConfiguration.class,
load(CustomInfoPropertiesConfiguration.class,
"spring.info.git.location=classpath:/org/springframework/boot/autoconfigure/info/git.properties");
GitProperties gitProperties = this.context.getBean(GitProperties.class);
assertThat(gitProperties).isSameAs(this.context.getBean("customGitProperties"));
}
@Test
public void buildPropertiesDefaultLocation() {
load();
BuildProperties buildProperties = this.context.getBean(BuildProperties.class);
assertThat(buildProperties.getGroup()).isEqualTo("com.example");
assertThat(buildProperties.getArtifact()).isEqualTo("demo");
assertThat(buildProperties.getName()).isEqualTo("Demo Project");
assertThat(buildProperties.getVersion()).isEqualTo("0.0.1-SNAPSHOT");
assertThat(buildProperties.getTime().getTime()).isEqualTo(1457100965000L);
}
@Test
public void buildPropertiesCustomLocation() {
load("spring.info.build.location=classpath:/org/springframework/boot/autoconfigure/info/build.properties");
BuildProperties buildProperties = this.context.getBean(BuildProperties.class);
assertThat(buildProperties.getGroup()).isEqualTo("com.example.acme");
assertThat(buildProperties.getArtifact()).isEqualTo("acme");
assertThat(buildProperties.getName()).isEqualTo("acme");
assertThat(buildProperties.getVersion()).isEqualTo("1.0.1-SNAPSHOT");
assertThat(buildProperties.getTime().getTime()).isEqualTo(1457088120000L);
}
@Test
public void buildPropertiesCustomInvalidLocation() {
load("spring.info.build.location=classpath:/org/acme/no-build.properties");
Map<String, BuildProperties> beans = this.context.getBeansOfType(BuildProperties.class);
assertThat(beans).hasSize(0);
}
@Test
public void buildPropertiesFallbackWithBuildInfoBean() {
load(CustomInfoPropertiesConfiguration.class);
BuildProperties buildProperties = this.context.getBean(BuildProperties.class);
assertThat(buildProperties).isSameAs(this.context.getBean("customBuildProperties"));
}
private void load(String... environment) {
load(null, environment);
}
@@ -105,13 +142,18 @@ public class ProjectInfoAutoConfigurationTests {
}
@Configuration
static class CustomGitPropertiesConfiguration {
static class CustomInfoPropertiesConfiguration {
@Bean
public GitProperties customGitProperties() {
return new GitProperties(new Properties());
}
@Bean
public BuildProperties customBuildProperties() {
return new BuildProperties(new Properties());
}
}
}

View File

@@ -0,0 +1,5 @@
build.group=com.example
build.artifact=demo
build.name=Demo Project
build.version=0.0.1-SNAPSHOT
build.time=2016-03-04T15\:16\:05+0100

View File

@@ -0,0 +1,5 @@
build.group=com.example.acme
build.artifact=acme
build.name=acme
build.version=1.0.1-SNAPSHOT
build.time=2016-03-04T11:42:00+0100