From 1205290d044af21d378b5fc680072d8a8734cd77 Mon Sep 17 00:00:00 2001 From: David Pilar Date: Sun, 25 Jan 2026 09:10:22 +0100 Subject: [PATCH] Restored version command result as in v3 #1286 Signed-off-by: David Pilar --- .../autoconfigure/SpringShellProperties.java | 90 ++++++++++++++++++ .../StandardCommandsAutoConfiguration.java | 30 ++++-- .../shell/core/command/Version.java | 79 ++++++++++++++- .../shell/core/command/VersionTests.java | 95 +++++++++++++++++++ 4 files changed, 285 insertions(+), 9 deletions(-) create mode 100644 spring-shell-core/src/test/java/org/springframework/shell/core/command/VersionTests.java diff --git a/spring-shell-core-autoconfigure/src/main/java/org/springframework/shell/core/autoconfigure/SpringShellProperties.java b/spring-shell-core-autoconfigure/src/main/java/org/springframework/shell/core/autoconfigure/SpringShellProperties.java index bcb6190c9..2bc6f3aad 100644 --- a/spring-shell-core-autoconfigure/src/main/java/org/springframework/shell/core/autoconfigure/SpringShellProperties.java +++ b/spring-shell-core-autoconfigure/src/main/java/org/springframework/shell/core/autoconfigure/SpringShellProperties.java @@ -301,6 +301,24 @@ public static class VersionCommand { private boolean enabled = true; + 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; } @@ -309,6 +327,78 @@ public void setEnabled(boolean enabled) { this.enabled = enabled; } + 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; + } + } public static class Context { diff --git a/spring-shell-core-autoconfigure/src/main/java/org/springframework/shell/core/autoconfigure/StandardCommandsAutoConfiguration.java b/spring-shell-core-autoconfigure/src/main/java/org/springframework/shell/core/autoconfigure/StandardCommandsAutoConfiguration.java index a509d16c2..dec0a0754 100644 --- a/spring-shell-core-autoconfigure/src/main/java/org/springframework/shell/core/autoconfigure/StandardCommandsAutoConfiguration.java +++ b/spring-shell-core-autoconfigure/src/main/java/org/springframework/shell/core/autoconfigure/StandardCommandsAutoConfiguration.java @@ -16,15 +16,14 @@ package org.springframework.shell.core.autoconfigure; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; 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.shell.core.command.Clear; -import org.springframework.shell.core.command.Command; -import org.springframework.shell.core.command.Help; -import org.springframework.shell.core.command.Script; -import org.springframework.shell.core.command.Version; +import org.springframework.shell.core.command.*; /** * Creates beans for standard commands. @@ -51,8 +50,25 @@ public Command clearCommand() { @Bean @ConditionalOnProperty(value = "spring.shell.command.version.enabled", havingValue = "true", matchIfMissing = true) - public Command versionCommand() { - return new Version(); + public Command versionCommand(SpringShellProperties shellProperties, + ObjectProvider buildProperties, ObjectProvider gitProperties) { + SpringShellProperties.VersionCommand properties = shellProperties.getCommand().getVersion(); + Version version = new Version(); + + buildProperties.ifAvailable(props -> version + .setBuildProperties(new Version.BuildProperties(properties.isShowBuildGroup() ? props.getGroup() : null, + properties.isShowBuildArtifact() ? props.getArtifact() : null, + properties.isShowBuildName() ? props.getName() : null, + properties.isShowBuildVersion() ? props.getVersion() : null, + properties.isShowBuildTime() ? props.getTime() : null))); + + gitProperties.ifAvailable(props -> version + .setGitProperties(new Version.GitProperties(properties.isShowGitBranch() ? props.getBranch() : null, + properties.isShowGitCommitId() ? props.getCommitId() : null, + properties.isShowGitShortCommitId() ? props.getShortCommitId() : null, + properties.isShowGitCommitTime() ? props.getCommitTime() : null))); + + return version; } @Bean diff --git a/spring-shell-core/src/main/java/org/springframework/shell/core/command/Version.java b/spring-shell-core/src/main/java/org/springframework/shell/core/command/Version.java index 8de12621f..4d12bfc01 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/core/command/Version.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/core/command/Version.java @@ -15,7 +15,15 @@ */ package org.springframework.shell.core.command; +import org.jspecify.annotations.Nullable; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.util.StringUtils; + import java.io.PrintWriter; +import java.time.Instant; /** * Command to print the current version of Spring Shell. @@ -23,8 +31,31 @@ * @author Janne Valkealahti * @author Mahmoud Ben Hassine * @author Piotr Olaszewski + * @author David Pilar */ -public class Version implements Command { +public class Version implements Command, InitializingBean, ApplicationContextAware { + + public record BuildProperties(@Nullable String group, @Nullable String artifact, @Nullable String name, + @Nullable String version, @Nullable Instant time) { + } + + public record GitProperties(@Nullable String branch, @Nullable String commitId, @Nullable String shortCommitId, + @Nullable Instant commitTime) { + } + + private ApplicationContext applicationContext; + + private @Nullable BuildProperties buildProperties; + + private @Nullable GitProperties gitProperties; + + public void setBuildProperties(BuildProperties buildProperties) { + this.buildProperties = buildProperties; + } + + public void setGitProperties(GitProperties gitProperties) { + this.gitProperties = gitProperties; + } @Override public String getDescription() { @@ -40,13 +71,57 @@ public String getGroup() { public ExitStatus execute(CommandContext commandContext) throws Exception { Package pkg = Version.class.getPackage(); String version = "N/A"; - if (pkg != null && pkg.getImplementationVersion() != null) { + if (buildProperties != null && StringUtils.hasText(buildProperties.version())) { + version = buildProperties.version(); + } + else if (pkg != null && pkg.getImplementationVersion() != null) { version = pkg.getImplementationVersion(); } PrintWriter printWriter = commandContext.outputWriter(); printWriter.println("Version: " + version); + + if (buildProperties != null) { + if (StringUtils.hasText(buildProperties.group())) { + printWriter.println("Build Group: " + buildProperties.group()); + } + if (StringUtils.hasText(buildProperties.artifact())) { + printWriter.println("Build Artifact: " + buildProperties.artifact()); + } + if (StringUtils.hasText(buildProperties.name())) { + printWriter.println("Build Name: " + buildProperties.name()); + } + if (buildProperties.time() != null) { + printWriter.println("Build Time: " + buildProperties.time()); + } + } + if (gitProperties != null) { + if (StringUtils.hasText(gitProperties.shortCommitId())) { + printWriter.println("Git Short Commit ID: " + gitProperties.shortCommitId()); + } + if (StringUtils.hasText(gitProperties.commitId())) { + printWriter.println("Git Commit ID: " + gitProperties.commitId()); + } + if (StringUtils.hasText(gitProperties.branch())) { + printWriter.println("Git Branch: " + gitProperties.branch()); + } + if (gitProperties.commitTime() != null) { + printWriter.println("Git Commit Time: " + gitProperties.commitTime()); + } + } + printWriter.flush(); return ExitStatus.OK; } + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + @Override + public void afterPropertiesSet() { + applicationContext.getBeanProvider(Version.BuildProperties.class).ifAvailable(this::setBuildProperties); + applicationContext.getBeanProvider(Version.GitProperties.class).ifAvailable(this::setGitProperties); + } + } diff --git a/spring-shell-core/src/test/java/org/springframework/shell/core/command/VersionTests.java b/spring-shell-core/src/test/java/org/springframework/shell/core/command/VersionTests.java new file mode 100644 index 000000000..0e01a71fa --- /dev/null +++ b/spring-shell-core/src/test/java/org/springframework/shell/core/command/VersionTests.java @@ -0,0 +1,95 @@ +package org.springframework.shell.core.command; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.time.Instant; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * @author David Pilar + */ +class VersionTests { + + private StringWriter writer; + + private CommandContext context; + + @BeforeEach + void before() { + writer = new StringWriter(); + context = mock(CommandContext.class); + when(context.outputWriter()).thenReturn(new PrintWriter(writer)); + } + + @ParameterizedTest + @MethodSource("versionWithoutDetailsInfoData") + void testVersionWithoutDetailsInfo(Version.BuildProperties buildProperties, Version.GitProperties gitProperties) + throws Exception { + // given + Version version = new Version(); + version.setBuildProperties(buildProperties); + version.setGitProperties(gitProperties); + + // when + version.execute(context); + String result = writer.toString(); + + // then + assertTrue(result.contains("Version:")); + assertFalse(result.contains("Build Version:")); + assertFalse(result.contains("Build Group:")); + assertFalse(result.contains("Build Artifact:")); + assertFalse(result.contains("Build Name:")); + assertFalse(result.contains("Build Time:")); + assertFalse(result.contains("Git Short Commit ID:")); + assertFalse(result.contains("Git Commit ID:")); + assertFalse(result.contains("Git Branch:")); + assertFalse(result.contains("Git Commit Time:")); + } + + static Stream versionWithoutDetailsInfoData() { + return Stream.of(Arguments.of(null, null), + Arguments.of(new Version.BuildProperties(null, null, null, null, null), + new Version.GitProperties(null, null, null, null))); + } + + @Test + void testVersionWithDetailsInfo() throws Exception { + // given + Version.BuildProperties buildProperties = new Version.BuildProperties("group", "artifact", "name", "1.0.0", + Instant.now()); + Version.GitProperties gitProperties = new Version.GitProperties("branch", "commitId", "shortCommitId", + Instant.now()); + + Version version = new Version(); + version.setBuildProperties(buildProperties); + version.setGitProperties(gitProperties); + + // when + version.execute(context); + String result = writer.toString(); + + // then + assertTrue(result.contains("Version: " + buildProperties.version())); + assertTrue(result.contains("Build Group: " + buildProperties.group())); + assertTrue(result.contains("Build Artifact: " + buildProperties.artifact())); + assertTrue(result.contains("Build Name: " + buildProperties.name())); + assertTrue(result.contains("Build Time: " + buildProperties.time())); + assertTrue(result.contains("Git Short Commit ID: " + gitProperties.shortCommitId())); + assertTrue(result.contains("Git Commit ID: " + gitProperties.commitId())); + assertTrue(result.contains("Git Branch: " + gitProperties.branch())); + assertTrue(result.contains("Git Commit Time: " + gitProperties.commitTime())); + } + +} \ No newline at end of file