Add version command
- Add new styling system which works around concept that you use tags to request jline styles where tags comes from an activated theme. - There is a default theme with options to add custom ones and change it via property. - Add templating system which uses antlr stringtemplate which allows to write output with a template instead of manually crafting code. - Add version command which integrates to Boot's BuildProperties and GitProperties. Only version field is visible on default and others can be enabled/disable via properties. - Fixes #352 - Fixes #353
This commit is contained in:
17
pom.xml
17
pom.xml
@@ -154,6 +154,23 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>pl.project13.maven</groupId>
|
||||
<artifactId>git-commit-id-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>revision</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<verbose>true</verbose>
|
||||
<dateFormat>yyyy-MM-dd'T'HH:mm:ssZ</dateFormat>
|
||||
<generateGitPropertiesFile>true</generateGitPropertiesFile>
|
||||
<generateGitPropertiesFilename>${project.build.outputDirectory}/git.properties</generateGitPropertiesFilename>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
|
||||
@@ -28,6 +28,7 @@ public class SpringShellProperties {
|
||||
private Script script = new Script();
|
||||
private Interactive interactive = new Interactive();
|
||||
private Noninteractive noninteractive = new Noninteractive();
|
||||
private Theme theme = new Theme();
|
||||
private Command command = new Command();
|
||||
|
||||
public void setScript(Script script) {
|
||||
@@ -54,6 +55,14 @@ public class SpringShellProperties {
|
||||
this.noninteractive = noninteractive;
|
||||
}
|
||||
|
||||
public Theme getTheme() {
|
||||
return theme;
|
||||
}
|
||||
|
||||
public void setTheme(Theme theme) {
|
||||
this.theme = theme;
|
||||
}
|
||||
|
||||
public Command getCommand() {
|
||||
return command;
|
||||
}
|
||||
@@ -101,6 +110,19 @@ public class SpringShellProperties {
|
||||
}
|
||||
}
|
||||
|
||||
public static class Theme {
|
||||
|
||||
private String name = "default";
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
public static class HelpCommand {
|
||||
|
||||
private boolean enabled = true;
|
||||
@@ -210,6 +232,7 @@ public class SpringShellProperties {
|
||||
private ScriptCommand script = new ScriptCommand();
|
||||
private HistoryCommand history = new HistoryCommand();
|
||||
private CompletionCommand completion = new CompletionCommand();
|
||||
private VersionCommand version = new VersionCommand();
|
||||
|
||||
public void setHelp(HelpCommand help) {
|
||||
this.help = help;
|
||||
@@ -266,5 +289,116 @@ public class SpringShellProperties {
|
||||
public void setCompletion(CompletionCommand completion) {
|
||||
this.completion = completion;
|
||||
}
|
||||
|
||||
public VersionCommand getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(VersionCommand version) {
|
||||
this.version = version;
|
||||
}
|
||||
}
|
||||
|
||||
public static class VersionCommand {
|
||||
|
||||
private boolean enabled = true;
|
||||
private String template = "classpath:template/version-default.st";
|
||||
private boolean showBuildGroup = false;
|
||||
private boolean showBuildArtifact = false;
|
||||
private boolean showBuildName = false;
|
||||
private boolean showBuildVersion = true;
|
||||
private boolean showBuildTime = false;
|
||||
private boolean showGitBranch = false;
|
||||
private boolean showGitCommitId = false;
|
||||
private boolean showGitShortCommitId = false;
|
||||
private boolean showGitCommitTime = false;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
public void setTemplate(String template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
public boolean isShowBuildGroup() {
|
||||
return showBuildGroup;
|
||||
}
|
||||
|
||||
public void setShowBuildGroup(boolean showBuildGroup) {
|
||||
this.showBuildGroup = showBuildGroup;
|
||||
}
|
||||
|
||||
public boolean isShowBuildArtifact() {
|
||||
return showBuildArtifact;
|
||||
}
|
||||
|
||||
public void setShowBuildArtifact(boolean showBuildArtifact) {
|
||||
this.showBuildArtifact = showBuildArtifact;
|
||||
}
|
||||
|
||||
public boolean isShowBuildName() {
|
||||
return showBuildName;
|
||||
}
|
||||
|
||||
public void setShowBuildName(boolean showBuildName) {
|
||||
this.showBuildName = showBuildName;
|
||||
}
|
||||
|
||||
public boolean isShowBuildVersion() {
|
||||
return showBuildVersion;
|
||||
}
|
||||
|
||||
public void setShowBuildVersion(boolean showBuildVersion) {
|
||||
this.showBuildVersion = showBuildVersion;
|
||||
}
|
||||
|
||||
public boolean isShowBuildTime() {
|
||||
return showBuildTime;
|
||||
}
|
||||
|
||||
public void setShowBuildTime(boolean showBuildTime) {
|
||||
this.showBuildTime = showBuildTime;
|
||||
}
|
||||
|
||||
public boolean isShowGitBranch() {
|
||||
return showGitBranch;
|
||||
}
|
||||
|
||||
public void setShowGitBranch(boolean showGitBranch) {
|
||||
this.showGitBranch = showGitBranch;
|
||||
}
|
||||
|
||||
public boolean isShowGitCommitId() {
|
||||
return showGitCommitId;
|
||||
}
|
||||
|
||||
public void setShowGitCommitId(boolean showGitCommitId) {
|
||||
this.showGitCommitId = showGitCommitId;
|
||||
}
|
||||
|
||||
public boolean isShowGitShortCommitId() {
|
||||
return showGitShortCommitId;
|
||||
}
|
||||
|
||||
public void setShowGitShortCommitId(boolean showGitShortCommitId) {
|
||||
this.showGitShortCommitId = showGitShortCommitId;
|
||||
}
|
||||
|
||||
public boolean isShowGitCommitTime() {
|
||||
return showGitCommitTime;
|
||||
}
|
||||
|
||||
public void setShowGitCommitTime(boolean showGitCommitTime) {
|
||||
this.showGitCommitTime = showGitCommitTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,12 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
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.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.shell.boot.SpringShellProperties.VersionCommand;
|
||||
import org.springframework.shell.boot.condition.OnCompletionCommandCondition;
|
||||
import org.springframework.shell.result.ThrowableResultHandler;
|
||||
import org.springframework.shell.standard.commands.Clear;
|
||||
@@ -35,6 +38,8 @@ import org.springframework.shell.standard.commands.History;
|
||||
import org.springframework.shell.standard.commands.Quit;
|
||||
import org.springframework.shell.standard.commands.Script;
|
||||
import org.springframework.shell.standard.commands.Stacktrace;
|
||||
import org.springframework.shell.standard.commands.Version;
|
||||
import org.springframework.shell.style.TemplateExecutor;
|
||||
|
||||
/**
|
||||
* Creates beans for standard commands.
|
||||
@@ -94,4 +99,26 @@ public class StandardCommandsAutoConfiguration {
|
||||
public Completion completion(SpringShellProperties properties) {
|
||||
return new Completion(properties.getCommand().getCompletion().getRootCommand());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(Version.Command.class)
|
||||
@ConditionalOnProperty(prefix = "spring.shell.command.version", value = "enabled", havingValue = "true", matchIfMissing = true)
|
||||
public Version version(SpringShellProperties properties, ObjectProvider<BuildProperties> buildProperties,
|
||||
ObjectProvider<GitProperties> gitProperties, ObjectProvider<TemplateExecutor> templateExecutor) {
|
||||
Version version = new Version(templateExecutor.getIfAvailable());
|
||||
version.setBuildProperties(buildProperties.getIfAvailable());
|
||||
version.setGitProperties(gitProperties.getIfAvailable());
|
||||
VersionCommand versionProperties = properties.getCommand().getVersion();
|
||||
version.setTemplate(versionProperties.getTemplate());
|
||||
version.setShowBuildArtifact(versionProperties.isShowBuildArtifact());
|
||||
version.setShowBuildGroup(versionProperties.isShowBuildGroup());
|
||||
version.setShowBuildName(versionProperties.isShowBuildName());
|
||||
version.setShowBuildTime(versionProperties.isShowBuildTime());
|
||||
version.setShowBuildVersion(versionProperties.isShowBuildVersion());
|
||||
version.setShowGitBranch(versionProperties.isShowGitBranch());
|
||||
version.setShowGitCommitId(versionProperties.isShowGitCommitId());
|
||||
version.setShowGitShortCommitId(versionProperties.isShowGitShortCommitId());
|
||||
version.setShowGitCommitTime(versionProperties.isShowGitCommitTime());
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.shell.boot;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.shell.style.TemplateExecutor;
|
||||
import org.springframework.shell.style.Theme;
|
||||
import org.springframework.shell.style.ThemeRegistry;
|
||||
import org.springframework.shell.style.ThemeResolver;
|
||||
import org.springframework.shell.style.ThemeSettings;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(SpringShellProperties.class)
|
||||
public class ThemingAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public ThemeRegistry themeRegistry(ObjectProvider<Theme> themes) {
|
||||
ThemeRegistry registry = new ThemeRegistry();
|
||||
registry.register(Theme.of("default", ThemeSettings.themeSettings()));
|
||||
themes.orderedStream().forEachOrdered(theme -> registry.register(theme));
|
||||
return registry;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ThemeResolver themeResolver(ThemeRegistry themeRegistry, SpringShellProperties properties) {
|
||||
return new ThemeResolver(themeRegistry, properties.getTheme().getName());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TemplateExecutor templateExecutor(ThemeResolver themeResolver) {
|
||||
return new TemplateExecutor(themeResolver);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,4 +11,5 @@ org.springframework.shell.boot.JLineShellAutoConfiguration,\
|
||||
org.springframework.shell.boot.JCommanderParameterResolverAutoConfiguration,\
|
||||
org.springframework.shell.boot.ParameterResolverAutoConfiguration,\
|
||||
org.springframework.shell.boot.StandardAPIAutoConfiguration,\
|
||||
org.springframework.shell.boot.ThemingAutoConfiguration,\
|
||||
org.springframework.shell.boot.StandardCommandsAutoConfiguration
|
||||
|
||||
@@ -35,6 +35,7 @@ public class SpringShellPropertiesTests {
|
||||
assertThat(properties.getScript().isEnabled()).isTrue();
|
||||
assertThat(properties.getInteractive().isEnabled()).isTrue();
|
||||
assertThat(properties.getNoninteractive().isEnabled()).isTrue();
|
||||
assertThat(properties.getTheme().getName()).isEqualTo("default");
|
||||
assertThat(properties.getCommand().getClear().isEnabled()).isTrue();
|
||||
assertThat(properties.getCommand().getHelp().isEnabled()).isTrue();
|
||||
assertThat(properties.getCommand().getHistory().isEnabled()).isTrue();
|
||||
@@ -43,6 +44,17 @@ public class SpringShellPropertiesTests {
|
||||
assertThat(properties.getCommand().getStacktrace().isEnabled()).isTrue();
|
||||
assertThat(properties.getCommand().getCompletion().isEnabled()).isTrue();
|
||||
assertThat(properties.getCommand().getCompletion().getRootCommand()).isNull();
|
||||
assertThat(properties.getCommand().getVersion().isEnabled()).isTrue();
|
||||
assertThat(properties.getCommand().getVersion().getTemplate()).isNotNull();
|
||||
assertThat(properties.getCommand().getVersion().isShowBuildArtifact()).isFalse();
|
||||
assertThat(properties.getCommand().getVersion().isShowBuildGroup()).isFalse();
|
||||
assertThat(properties.getCommand().getVersion().isShowBuildName()).isFalse();
|
||||
assertThat(properties.getCommand().getVersion().isShowBuildTime()).isFalse();
|
||||
assertThat(properties.getCommand().getVersion().isShowBuildVersion()).isTrue();
|
||||
assertThat(properties.getCommand().getVersion().isShowGitBranch()).isFalse();
|
||||
assertThat(properties.getCommand().getVersion().isShowGitCommitId()).isFalse();
|
||||
assertThat(properties.getCommand().getVersion().isShowGitShortCommitId()).isFalse();
|
||||
assertThat(properties.getCommand().getVersion().isShowGitCommitTime()).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -52,6 +64,7 @@ public class SpringShellPropertiesTests {
|
||||
.withPropertyValues("spring.shell.script.enabled=false")
|
||||
.withPropertyValues("spring.shell.interactive.enabled=false")
|
||||
.withPropertyValues("spring.shell.noninteractive.enabled=false")
|
||||
.withPropertyValues("spring.shell.theme.name=fake")
|
||||
.withPropertyValues("spring.shell.command.clear.enabled=false")
|
||||
.withPropertyValues("spring.shell.command.help.enabled=false")
|
||||
.withPropertyValues("spring.shell.command.history.enabled=false")
|
||||
@@ -60,12 +73,24 @@ public class SpringShellPropertiesTests {
|
||||
.withPropertyValues("spring.shell.command.stacktrace.enabled=false")
|
||||
.withPropertyValues("spring.shell.command.completion.enabled=false")
|
||||
.withPropertyValues("spring.shell.command.completion.root-command=fake")
|
||||
.withPropertyValues("spring.shell.command.version.enabled=false")
|
||||
.withPropertyValues("spring.shell.command.version.template=fake")
|
||||
.withPropertyValues("spring.shell.command.version.show-build-artifact=true")
|
||||
.withPropertyValues("spring.shell.command.version.show-build-group=true")
|
||||
.withPropertyValues("spring.shell.command.version.show-build-name=true")
|
||||
.withPropertyValues("spring.shell.command.version.show-build-time=true")
|
||||
.withPropertyValues("spring.shell.command.version.show-build-version=false")
|
||||
.withPropertyValues("spring.shell.command.version.show-git-branch=true")
|
||||
.withPropertyValues("spring.shell.command.version.show-git-commit-id=true")
|
||||
.withPropertyValues("spring.shell.command.version.show-git-short-commit-id=true")
|
||||
.withPropertyValues("spring.shell.command.version.show-git-commit-time=true")
|
||||
.withUserConfiguration(Config1.class)
|
||||
.run((context) -> {
|
||||
SpringShellProperties properties = context.getBean(SpringShellProperties.class);
|
||||
assertThat(properties.getScript().isEnabled()).isFalse();
|
||||
assertThat(properties.getInteractive().isEnabled()).isFalse();
|
||||
assertThat(properties.getNoninteractive().isEnabled()).isFalse();
|
||||
assertThat(properties.getTheme().getName()).isEqualTo("fake");
|
||||
assertThat(properties.getCommand().getClear().isEnabled()).isFalse();
|
||||
assertThat(properties.getCommand().getHelp().isEnabled()).isFalse();
|
||||
assertThat(properties.getCommand().getHistory().isEnabled()).isFalse();
|
||||
@@ -74,6 +99,17 @@ public class SpringShellPropertiesTests {
|
||||
assertThat(properties.getCommand().getStacktrace().isEnabled()).isFalse();
|
||||
assertThat(properties.getCommand().getCompletion().isEnabled()).isFalse();
|
||||
assertThat(properties.getCommand().getCompletion().getRootCommand()).isEqualTo("fake");
|
||||
assertThat(properties.getCommand().getVersion().isEnabled()).isFalse();
|
||||
assertThat(properties.getCommand().getVersion().getTemplate()).isEqualTo("fake");
|
||||
assertThat(properties.getCommand().getVersion().isShowBuildArtifact()).isTrue();
|
||||
assertThat(properties.getCommand().getVersion().isShowBuildGroup()).isTrue();
|
||||
assertThat(properties.getCommand().getVersion().isShowBuildName()).isTrue();
|
||||
assertThat(properties.getCommand().getVersion().isShowBuildTime()).isTrue();
|
||||
assertThat(properties.getCommand().getVersion().isShowBuildVersion()).isFalse();
|
||||
assertThat(properties.getCommand().getVersion().isShowGitBranch()).isTrue();
|
||||
assertThat(properties.getCommand().getVersion().isShowGitCommitId()).isTrue();
|
||||
assertThat(properties.getCommand().getVersion().isShowGitShortCommitId()).isTrue();
|
||||
assertThat(properties.getCommand().getVersion().isShowGitCommitTime()).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.shell.boot;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.shell.style.TemplateExecutor;
|
||||
import org.springframework.shell.style.Theme;
|
||||
import org.springframework.shell.style.ThemeRegistry;
|
||||
import org.springframework.shell.style.ThemeResolver;
|
||||
import org.springframework.shell.style.ThemeSettings;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ThemingAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(ThemingAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void testDefaults() {
|
||||
this.contextRunner
|
||||
.run(context -> {
|
||||
assertThat(context).hasSingleBean(TemplateExecutor.class);
|
||||
assertThat(context).hasSingleBean(ThemeRegistry.class);
|
||||
ThemeRegistry registry = context.getBean(ThemeRegistry.class);
|
||||
assertThat(registry.get("default")).isNotNull();
|
||||
assertThat(context).hasSingleBean(ThemeResolver.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegistersCustomTheme() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(CustomThemeConfig.class)
|
||||
.run(context -> {
|
||||
assertThat(context).hasSingleBean(ThemeRegistry.class);
|
||||
ThemeRegistry registry = context.getBean(ThemeRegistry.class);
|
||||
assertThat(registry.get("default")).isNotNull();
|
||||
assertThat(registry.get("mytheme")).isNotNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class CustomThemeConfig {
|
||||
|
||||
@Bean
|
||||
public Theme myTheme() {
|
||||
return new Theme() {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "mytheme";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThemeSettings getSettings() {
|
||||
return new MyThemeSettings();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static class MyThemeSettings extends ThemeSettings {
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
<artifactId>spring-shell-parent</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
|
||||
<description>Core API and classes for Spring Shell 2</description>
|
||||
|
||||
<dependencies>
|
||||
@@ -31,7 +31,10 @@
|
||||
<groupId>org.jline</groupId>
|
||||
<artifactId>jline-terminal-jna</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>ST4</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.shell</groupId>
|
||||
<artifactId>spring-shell-table</artifactId>
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.shell.style;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.jline.style.StyleExpression;
|
||||
import org.stringtemplate.v4.AttributeRenderer;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@code ST} {@link AttributeRenderer} which knows to use format string to
|
||||
* render strings into {@code jline} {@link StyleExpression} based on theming
|
||||
* settings.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
public class StringToStyleExpressionRenderer implements AttributeRenderer<String> {
|
||||
|
||||
private final ThemeResolver themeResolver;
|
||||
|
||||
public StringToStyleExpressionRenderer(ThemeResolver themeResolver) {
|
||||
Assert.notNull(themeResolver, "themeResolver must be set");
|
||||
this.themeResolver = themeResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(String value, String formatString, Locale locale) {
|
||||
if (!StringUtils.hasText(formatString)) {
|
||||
return value;
|
||||
}
|
||||
else {
|
||||
return String.format("@{%s %s}", themeResolver.resolveTag(formatString), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.shell.style;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jline.utils.AttributedString;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.stringtemplate.v4.ST;
|
||||
import org.stringtemplate.v4.STErrorListener;
|
||||
import org.stringtemplate.v4.STGroup;
|
||||
import org.stringtemplate.v4.misc.STMessage;
|
||||
|
||||
/**
|
||||
* Template executor which knows to use styling.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
public class TemplateExecutor {
|
||||
|
||||
private final static STErrorListener ERROR_LISTENER = new LoggingSTErrorListener();
|
||||
private final ThemeResolver themeResolver;
|
||||
private StringToStyleExpressionRenderer renderer;
|
||||
|
||||
public TemplateExecutor(ThemeResolver themeResolver) {
|
||||
this.themeResolver = themeResolver;
|
||||
renderer = new StringToStyleExpressionRenderer(themeResolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render template with a given attributes.
|
||||
*
|
||||
* @param template the ST template
|
||||
* @param attributes the ST template attributes
|
||||
* @return a rendered template
|
||||
*/
|
||||
public AttributedString render(String template, Map<String, Object> attributes) {
|
||||
STGroup group = new STGroup();
|
||||
group.setListener(ERROR_LISTENER);
|
||||
group.registerRenderer(String.class, renderer);
|
||||
|
||||
ST st = new ST(group, template);
|
||||
if (attributes != null) {
|
||||
attributes.entrySet().stream().forEach(e -> st.add(e.getKey(), e.getValue()));
|
||||
}
|
||||
String templateRendered = st.render();
|
||||
return themeResolver.evaluateExpression(templateRendered);
|
||||
}
|
||||
|
||||
private static class LoggingSTErrorListener implements STErrorListener {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(LoggingSTErrorListener.class);
|
||||
|
||||
@Override
|
||||
public void compileTimeError(STMessage msg) {
|
||||
log.error("compileTimeError [{}]", msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runTimeError(STMessage msg) {
|
||||
log.error("runTimeError [{}]", msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void IOError(STMessage msg) {
|
||||
log.error("IOError [{}]", msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void internalError(STMessage msg) {
|
||||
log.error("internalError [{}]", msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.shell.style;
|
||||
|
||||
/**
|
||||
* Contract representing a theme with its name and settings.
|
||||
*
|
||||
* {@link Theme} is a concept where you can request a {@code style} by using a theme {@code tag}.
|
||||
* At this point an actual style is not known as it's going to get resolved from an
|
||||
* enable {@code theme}.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
public interface Theme {
|
||||
|
||||
/**
|
||||
* Gets a theme name.
|
||||
*
|
||||
* @return a theme name.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Gets a theme settings.
|
||||
*
|
||||
* @return a theme settings
|
||||
*/
|
||||
ThemeSettings getSettings();
|
||||
|
||||
/**
|
||||
* Create a {@link Theme}.
|
||||
*
|
||||
* @param name the theme name
|
||||
* @param themeSettings the theme settings
|
||||
* @return a theme
|
||||
*/
|
||||
public static Theme of(String name, ThemeSettings themeSettings) {
|
||||
return new Theme() {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThemeSettings getSettings() {
|
||||
return themeSettings;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.shell.style;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Registry which stores {@link Theme}'s with its name.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
public class ThemeRegistry {
|
||||
|
||||
private final Map<String, Theme> themes = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Gets a theme from a registry.
|
||||
*
|
||||
* @param name the theme name
|
||||
* @return a theme
|
||||
*/
|
||||
public Theme get(String name) {
|
||||
return themes.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a theme.
|
||||
*
|
||||
* @param theme the theme
|
||||
*/
|
||||
public void register(Theme theme) {
|
||||
Assert.notNull(theme, "theme cannot be null");
|
||||
themes.put(theme.getName(), theme);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.shell.style;
|
||||
|
||||
import org.jline.style.MemoryStyleSource;
|
||||
import org.jline.style.StyleExpression;
|
||||
import org.jline.style.StyleResolver;
|
||||
import org.jline.style.StyleSource;
|
||||
import org.jline.utils.AttributedString;
|
||||
import org.jline.utils.AttributedStyle;
|
||||
|
||||
/**
|
||||
* Service which helps to do various things with styles.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
public class ThemeResolver {
|
||||
|
||||
private StyleSource styleSource = new MemoryStyleSource();
|
||||
private StyleResolver styleResolver = new StyleResolver(styleSource, "default");
|
||||
private StyleExpression styleExpression = new StyleExpression(styleResolver);
|
||||
private final Theme theme;
|
||||
|
||||
public ThemeResolver(ThemeRegistry themeRegistry, String themeName) {
|
||||
this.theme = themeRegistry.get(themeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate expression.
|
||||
*
|
||||
* @param expression the expression
|
||||
* @return evaluated attributed string
|
||||
*/
|
||||
public AttributedString evaluateExpression(String expression) {
|
||||
return styleExpression.evaluate(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve style from a tag with activated theme.
|
||||
*
|
||||
* @param tag the tag
|
||||
* @return a style
|
||||
*/
|
||||
public String resolveTag(String tag) {
|
||||
return theme.getSettings().resolveTag(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve {@link AttributedStyle} from a {@code spec}.
|
||||
*
|
||||
* @param spec the spec
|
||||
* @return resolved attributed style
|
||||
*/
|
||||
public AttributedStyle resolveStyle(String spec) {
|
||||
return styleResolver.resolve(spec);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.shell.style;
|
||||
|
||||
/**
|
||||
* {@link ThemeSettings} is storing {@link Theme} related settings together and
|
||||
* is base class for further customizations.
|
||||
*
|
||||
* Settings in this base class are default styles.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
public abstract class ThemeSettings {
|
||||
|
||||
/**
|
||||
* Represents some arbitrary {@code title}.
|
||||
*/
|
||||
public final static String TAG_TITLE = "title";
|
||||
|
||||
/**
|
||||
* Represents some arbitrary {@code value}.
|
||||
*/
|
||||
public final static String TAG_VALUE = "value";
|
||||
|
||||
/**
|
||||
* Styling for keys or names in a lists:
|
||||
* <list key1> : list value1
|
||||
* <list key2> : list value2
|
||||
*/
|
||||
public final static String TAG_LIST_KEY = "list-key";
|
||||
|
||||
/**
|
||||
* Styling for keys or names in a lists:
|
||||
* list key1 : <list value1>
|
||||
* list key2 : <list value2>
|
||||
*/
|
||||
public final static String TAG_LIST_VALUE = "list-value";
|
||||
|
||||
public String title() {
|
||||
return "bold";
|
||||
}
|
||||
|
||||
public String value() {
|
||||
return "fg:blue";
|
||||
}
|
||||
|
||||
public String listKey() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String listValue() {
|
||||
return "bold,fg:green";
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a theme setting from a given tag.
|
||||
*
|
||||
* @param tag the tag
|
||||
* @return a theme setting
|
||||
*/
|
||||
public String resolveTag(String tag) {
|
||||
switch (tag) {
|
||||
case TAG_TITLE:
|
||||
return title();
|
||||
case TAG_VALUE:
|
||||
return value();
|
||||
case TAG_LIST_KEY:
|
||||
return listKey();
|
||||
case TAG_LIST_VALUE:
|
||||
return listValue();
|
||||
}
|
||||
throw new IllegalArgumentException(String.format("Unknown tag '%s'", tag));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of a default settings.
|
||||
*
|
||||
* @return a default theme settings
|
||||
*/
|
||||
public static ThemeSettings themeSettings() {
|
||||
return new DefaultThemeSettings();
|
||||
}
|
||||
|
||||
private static class DefaultThemeSettings extends ThemeSettings {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.shell.style;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jline.utils.AttributedString;
|
||||
import org.jline.utils.AttributedStringBuilder;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.jline.utils.AttributedStyle.BOLD;
|
||||
|
||||
public class TemplateExecutorTests {
|
||||
|
||||
private ThemeResolver themeResolver;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ThemeRegistry themeRegistry = new ThemeRegistry();
|
||||
themeRegistry.register(new Theme() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "default";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThemeSettings getSettings() {
|
||||
return ThemeSettings.themeSettings();
|
||||
}
|
||||
});
|
||||
themeResolver = new ThemeResolver(themeRegistry, "default");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimple() {
|
||||
TemplateExecutor executor = new TemplateExecutor(themeResolver);
|
||||
String template = "<(\"foo\")>";
|
||||
AttributedString result = executor.render(template, null);
|
||||
AttributedString equalTo = new AttributedStringBuilder().append("foo").toAttributedString();
|
||||
assertThat(result).isEqualTo(equalTo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithExpression() {
|
||||
TemplateExecutor executor = new TemplateExecutor(themeResolver);
|
||||
String template = "<foo>";
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
attributes.put("foo", "bar");
|
||||
AttributedString result = executor.render(template, attributes);
|
||||
AttributedString equalTo = new AttributedStringBuilder().append("bar").toAttributedString();
|
||||
assertThat(result).isEqualTo(equalTo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithTheme() {
|
||||
TemplateExecutor executor = new TemplateExecutor(themeResolver);
|
||||
String template = "<foo; format=\"title\">";
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
attributes.put("foo", "bar");
|
||||
AttributedString result = executor.render(template, attributes);
|
||||
AttributedString equalTo = new AttributedStringBuilder().append("bar", BOLD).toAttributedString();
|
||||
assertThat(result).isEqualTo(equalTo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullDontStyle() {
|
||||
TemplateExecutor executor = new TemplateExecutor(themeResolver);
|
||||
String template = "<foo; format=\"list-key\">";
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
attributes.put("foo", "bar");
|
||||
AttributedString result = executor.render(template, attributes);
|
||||
AttributedString equalTo = new AttributedStringBuilder().append("bar").toAttributedString();
|
||||
assertThat(result).isEqualTo(equalTo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.shell.style;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ThemeRegistryTests {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ThemeRegistry registry = new ThemeRegistry();
|
||||
Theme theme = Theme.of("name1", ThemeSettings.themeSettings());
|
||||
registry.register(theme);
|
||||
assertThat(registry.get("name1")).isSameAs(theme);
|
||||
assertThat(registry.get("name2")).isNull();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.shell.style;
|
||||
|
||||
import org.jline.utils.AttributedString;
|
||||
import org.jline.utils.AttributedStyle;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ThemeResolverTests {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ThemeRegistry themeRegistry = new ThemeRegistry();
|
||||
themeRegistry.register(new Theme() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "default";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThemeSettings getSettings() {
|
||||
return ThemeSettings.themeSettings();
|
||||
}
|
||||
});
|
||||
ThemeResolver themeResolver = new ThemeResolver(themeRegistry, "default");
|
||||
assertThat(themeResolver.resolveTag(ThemeSettings.TAG_TITLE)).isEqualTo("bold");
|
||||
assertThat(themeResolver.resolveStyle("bold")).isEqualTo(AttributedStyle.BOLD);
|
||||
assertThat(themeResolver.evaluateExpression("@{bold foo}"))
|
||||
.isEqualTo(new AttributedString("foo", AttributedStyle.BOLD));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.shell.style;
|
||||
|
||||
import org.jline.style.MemoryStyleSource;
|
||||
import org.jline.style.StyleResolver;
|
||||
import org.jline.style.StyleSource;
|
||||
import org.jline.utils.AttributedStyle;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ThemeSettingsTests {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ThemeSettings themeSettings = ThemeSettings.themeSettings();
|
||||
String resolveTag = themeSettings.resolveTag(ThemeSettings.TAG_TITLE);
|
||||
assertThat(resolveTag).isEqualTo("bold");
|
||||
|
||||
StyleSource styleSource = new MemoryStyleSource();
|
||||
StyleResolver styleResolver = new StyleResolver(styleSource, "default");
|
||||
AttributedStyle style = styleResolver.resolve(resolveTag);
|
||||
assertThat(style).isEqualTo(AttributedStyle.BOLD);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,13 @@
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>build-info</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
logging:
|
||||
level:
|
||||
root: error
|
||||
spring:
|
||||
main:
|
||||
banner-mode: off
|
||||
@@ -8,3 +5,15 @@ spring:
|
||||
command:
|
||||
completion:
|
||||
root-command: spring-shell-samples
|
||||
## disable console logging
|
||||
logging:
|
||||
pattern:
|
||||
console:
|
||||
## log debug from a cli
|
||||
# file:
|
||||
# name: shell.log
|
||||
# level:
|
||||
# root: debug
|
||||
# org:
|
||||
# springframework:
|
||||
# shell: debug
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.shell.standard.commands;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jline.utils.AttributedString;
|
||||
|
||||
import org.springframework.boot.info.BuildProperties;
|
||||
import org.springframework.boot.info.GitProperties;
|
||||
import org.springframework.context.ResourceLoaderAware;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.shell.standard.AbstractShellComponent;
|
||||
import org.springframework.shell.standard.ShellComponent;
|
||||
import org.springframework.shell.standard.ShellMethod;
|
||||
import org.springframework.shell.style.TemplateExecutor;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Command to list version and other build related infos.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
@ShellComponent
|
||||
public class Version extends AbstractShellComponent implements ResourceLoaderAware {
|
||||
|
||||
/**
|
||||
* Marker interface used in auto-config.
|
||||
*/
|
||||
public interface Command {
|
||||
}
|
||||
|
||||
private BuildProperties buildProperties;
|
||||
private GitProperties gitProperties;
|
||||
private ResourceLoader resourceLoader;
|
||||
private TemplateExecutor templateExecutor;
|
||||
private String template;
|
||||
private boolean showBuildGroup;
|
||||
private boolean showBuildArtifact;
|
||||
private boolean showBuildName;
|
||||
private boolean showBuildVersion;
|
||||
private boolean showBuildTime;
|
||||
private boolean showGitBranch;
|
||||
private boolean showGitCommitId;
|
||||
private boolean showGitShortCommitId;
|
||||
private boolean showGitCommitTime;
|
||||
|
||||
public Version(TemplateExecutor templateExecutor) {
|
||||
this.templateExecutor = templateExecutor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResourceLoader(ResourceLoader resourceLoader) {
|
||||
this.resourceLoader = resourceLoader;
|
||||
}
|
||||
|
||||
@ShellMethod(key = "version", value = "Show version info")
|
||||
public AttributedString version() {
|
||||
String templateResource = resourceAsString(resourceLoader.getResource(template));
|
||||
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
if (buildProperties != null) {
|
||||
if (showBuildGroup && StringUtils.hasText(buildProperties.getGroup())) {
|
||||
attributes.put("buildGroup", buildProperties.getGroup());
|
||||
}
|
||||
if (showBuildArtifact && StringUtils.hasText(buildProperties.getArtifact())) {
|
||||
attributes.put("buildArtifact", buildProperties.getArtifact());
|
||||
}
|
||||
if (showBuildName && StringUtils.hasText(buildProperties.getName())) {
|
||||
attributes.put("buildName", buildProperties.getName());
|
||||
}
|
||||
if (showBuildVersion && StringUtils.hasText(buildProperties.getVersion())) {
|
||||
attributes.put("buildVersion", buildProperties.getVersion());
|
||||
}
|
||||
if (showBuildTime && buildProperties.getTime() != null) {
|
||||
attributes.put("buildTime", buildProperties.getTime().toString());
|
||||
}
|
||||
}
|
||||
if (gitProperties != null) {
|
||||
if (showGitBranch && StringUtils.hasText(gitProperties.getBranch())) {
|
||||
attributes.put("gitBranch", gitProperties.getBranch());
|
||||
}
|
||||
if (showGitCommitId && StringUtils.hasText(gitProperties.getCommitId())) {
|
||||
attributes.put("gitCommitId", gitProperties.getCommitId());
|
||||
}
|
||||
if (showGitShortCommitId && StringUtils.hasText(gitProperties.getShortCommitId())) {
|
||||
attributes.put("gitShortCommitId", gitProperties.getShortCommitId());
|
||||
}
|
||||
if (showGitCommitTime && gitProperties.getCommitTime() != null) {
|
||||
attributes.put("gitCommitTime", gitProperties.getCommitTime().toString());
|
||||
}
|
||||
}
|
||||
AttributedString rendered = templateExecutor.render(templateResource, attributes);
|
||||
return rendered;
|
||||
}
|
||||
|
||||
public void setBuildProperties(BuildProperties buildProperties) {
|
||||
this.buildProperties = buildProperties;
|
||||
}
|
||||
|
||||
public void setGitProperties(GitProperties gitProperties) {
|
||||
this.gitProperties = gitProperties;
|
||||
}
|
||||
|
||||
public void setTemplate(String template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
public void setShowBuildGroup(boolean showBuildGroup) {
|
||||
this.showBuildGroup = showBuildGroup;
|
||||
}
|
||||
|
||||
public void setShowBuildArtifact(boolean showBuildArtifact) {
|
||||
this.showBuildArtifact = showBuildArtifact;
|
||||
}
|
||||
|
||||
public void setShowBuildName(boolean showBuildName) {
|
||||
this.showBuildName = showBuildName;
|
||||
}
|
||||
|
||||
public void setShowBuildVersion(boolean showBuildVersion) {
|
||||
this.showBuildVersion = showBuildVersion;
|
||||
}
|
||||
|
||||
public void setShowBuildTime(boolean showBuildTime) {
|
||||
this.showBuildTime = showBuildTime;
|
||||
}
|
||||
|
||||
public void setShowGitBranch(boolean showGitBranch) {
|
||||
this.showGitBranch = showGitBranch;
|
||||
}
|
||||
|
||||
public void setShowGitCommitId(boolean showGitCommitId) {
|
||||
this.showGitCommitId = showGitCommitId;
|
||||
}
|
||||
|
||||
public void setShowGitShortCommitId(boolean showGitShortCommitId) {
|
||||
this.showGitShortCommitId = showGitShortCommitId;
|
||||
}
|
||||
|
||||
public void setShowGitCommitTime(boolean showGitCommitTime) {
|
||||
this.showGitCommitTime = showGitCommitTime;
|
||||
}
|
||||
|
||||
private static String resourceAsString(Resource resource) {
|
||||
try (Reader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)) {
|
||||
return FileCopyUtils.copyToString(reader);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,10 @@
|
||||
"includes": [
|
||||
{
|
||||
"pattern": "completion/.*"
|
||||
},
|
||||
{
|
||||
"pattern": "template/.*.st"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<if(buildVersion)>
|
||||
<("Build Version"); format="list-key">: <buildVersion; format="list-value">
|
||||
<endif>
|
||||
<if(buildGroup)>
|
||||
<("Build Group"); format="list-key">: <buildGroup; format="list-value">
|
||||
<endif>
|
||||
<if(buildArtifact)>
|
||||
<("Build Artifact"); format="list-key">: <buildArtifact; format="list-value">
|
||||
<endif>
|
||||
<if(buildName)>
|
||||
<("Build Name"); format="list-key">: <buildName; format="list-value">
|
||||
<endif>
|
||||
<if(buildTime)>
|
||||
<("Build Time"); format="list-key">: <buildTime; format="list-value">
|
||||
<endif>
|
||||
<if(gitShortCommitId)>
|
||||
<("Git Short Commit Id"); format="list-key">: <gitShortCommitId; format="list-value">
|
||||
<endif>
|
||||
<if(gitCommitId)>
|
||||
<("Git Commit Id"); format="list-key">: <gitCommitId; format="list-value">
|
||||
<endif>
|
||||
<if(gitBranch)>
|
||||
<("Git Branch"); format="list-key">: <gitBranch; format="list-value">
|
||||
<endif>
|
||||
<if(gitCommitTime)>
|
||||
<("Git Commit Time"); format="list-key">: <gitCommitTime; format="list-value">
|
||||
<endif>
|
||||
Reference in New Issue
Block a user