Skip to content

Commit 831f2cf

Browse files
committed
Provide pty info
- Enhance ShellContext for pty info - Enhance CommandContext to include ShellContext - Fixes #985
1 parent 90e032d commit 831f2cf

File tree

14 files changed

+217
-26
lines changed

14 files changed

+217
-26
lines changed

spring-shell-autoconfigure/src/main/java/org/springframework/shell/boot/ShellContextAutoConfiguration.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 the original author or authors.
2+
* Copyright 2022-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,6 +15,9 @@
1515
*/
1616
package org.springframework.shell.boot;
1717

18+
import org.jline.terminal.Terminal;
19+
import org.jline.terminal.spi.TerminalExt;
20+
1821
import org.springframework.boot.autoconfigure.AutoConfiguration;
1922
import org.springframework.context.annotation.Bean;
2023
import org.springframework.shell.context.DefaultShellContext;
@@ -24,7 +27,11 @@
2427
public class ShellContextAutoConfiguration {
2528

2629
@Bean
27-
public ShellContext shellContext() {
28-
return new DefaultShellContext();
30+
public ShellContext shellContext(Terminal terminal) {
31+
boolean pty = false;
32+
if (terminal instanceof TerminalExt ext) {
33+
pty = ext.getSystemStream() != null;
34+
}
35+
return new DefaultShellContext(pty);
2936
}
3037
}

spring-shell-autoconfigure/src/test/java/org/springframework/shell/boot/CommandCatalogAutoConfigurationTests.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022-2023 the original author or authors.
2+
* Copyright 2022-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -36,7 +36,8 @@
3636
public class CommandCatalogAutoConfigurationTests {
3737

3838
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
39-
.withConfiguration(AutoConfigurations.of(CommandCatalogAutoConfiguration.class, ShellContextAutoConfiguration.class));
39+
.withConfiguration(AutoConfigurations.of(CommandCatalogAutoConfiguration.class,
40+
JLineShellAutoConfiguration.class, ShellContextAutoConfiguration.class));
4041

4142
@Test
4243
void defaultCommandCatalog() {

spring-shell-core/src/main/java/org/springframework/shell/Shell.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017-2022 the original author or authors.
2+
* Copyright 2017-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -238,7 +238,7 @@ protected Object evaluate(Input input) {
238238

239239
CommandExecution execution = CommandExecution.of(
240240
argumentResolvers != null ? argumentResolvers.getResolvers() : null, validator, terminal,
241-
conversionService, commandRegistry);
241+
shellContext, conversionService, commandRegistry);
242242

243243
List<CommandExceptionResolver> commandExceptionResolvers = commandRegistration.get().getExceptionResolvers();
244244

spring-shell-core/src/main/java/org/springframework/shell/command/CommandContext.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022-2023 the original author or authors.
2+
* Copyright 2022-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
2323

2424
import org.springframework.shell.command.CommandParser.CommandParserResult;
2525
import org.springframework.shell.command.CommandParser.CommandParserResults;
26+
import org.springframework.shell.context.ShellContext;
2627
import org.springframework.util.ObjectUtils;
2728

2829
/**
@@ -77,6 +78,13 @@ public interface CommandContext {
7778
*/
7879
Terminal getTerminal();
7980

81+
/**
82+
* Gets a {@link ShellContext} associated with {@link CommandContext}.
83+
*
84+
* @return a shell context
85+
*/
86+
ShellContext getShellContext();
87+
8088
/**
8189
* Gets an instance of a default {@link CommandContext}.
8290
*
@@ -87,8 +95,8 @@ public interface CommandContext {
8795
* @return a command context
8896
*/
8997
static CommandContext of(String[] args, CommandParserResults results, Terminal terminal,
90-
CommandRegistration commandRegistration) {
91-
return new DefaultCommandContext(args, results, terminal, commandRegistration);
98+
CommandRegistration commandRegistration, ShellContext shellContext) {
99+
return new DefaultCommandContext(args, results, terminal, commandRegistration, shellContext);
92100
}
93101

94102
/**
@@ -100,13 +108,15 @@ static class DefaultCommandContext implements CommandContext {
100108
private final CommandParserResults results;
101109
private final Terminal terminal;
102110
private final CommandRegistration commandRegistration;
111+
private final ShellContext shellContext;
103112

104113
DefaultCommandContext(String[] args, CommandParserResults results, Terminal terminal,
105-
CommandRegistration commandRegistration) {
114+
CommandRegistration commandRegistration, ShellContext shellContext) {
106115
this.args = args;
107116
this.results = results;
108117
this.terminal = terminal;
109118
this.commandRegistration = commandRegistration;
119+
this.shellContext = shellContext;
110120
}
111121

112122
@Override
@@ -144,6 +154,11 @@ public Terminal getTerminal() {
144154
return terminal;
145155
}
146156

157+
@Override
158+
public ShellContext getShellContext() {
159+
return shellContext;
160+
}
161+
147162
private Optional<CommandParserResult> find(String name) {
148163
return results.results().stream()
149164
.filter(r -> {

spring-shell-core/src/main/java/org/springframework/shell/command/CommandExecution.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022-2023 the original author or authors.
2+
* Copyright 2022-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -41,6 +41,7 @@
4141
import org.springframework.shell.command.invocation.InvocableShellMethod;
4242
import org.springframework.shell.command.invocation.ShellMethodArgumentResolverComposite;
4343
import org.springframework.shell.command.parser.ParserConfig;
44+
import org.springframework.shell.context.ShellContext;
4445
import org.springframework.util.ObjectUtils;
4546

4647
/**
@@ -65,7 +66,7 @@ public interface CommandExecution {
6566
* @return default command execution
6667
*/
6768
public static CommandExecution of(List<? extends HandlerMethodArgumentResolver> resolvers) {
68-
return new DefaultCommandExecution(resolvers, null, null, null, null);
69+
return new DefaultCommandExecution(resolvers, null, null, null, null, null);
6970
}
7071

7172
/**
@@ -78,8 +79,8 @@ public static CommandExecution of(List<? extends HandlerMethodArgumentResolver>
7879
* @return default command execution
7980
*/
8081
public static CommandExecution of(List<? extends HandlerMethodArgumentResolver> resolvers, Validator validator,
81-
Terminal terminal, ConversionService conversionService) {
82-
return new DefaultCommandExecution(resolvers, validator, terminal, conversionService, null);
82+
Terminal terminal, ShellContext shellContext, ConversionService conversionService) {
83+
return new DefaultCommandExecution(resolvers, validator, terminal, shellContext, conversionService, null);
8384
}
8485

8586
/**
@@ -92,8 +93,8 @@ public static CommandExecution of(List<? extends HandlerMethodArgumentResolver>
9293
* @return default command execution
9394
*/
9495
public static CommandExecution of(List<? extends HandlerMethodArgumentResolver> resolvers, Validator validator,
95-
Terminal terminal, ConversionService conversionService, CommandCatalog commandCatalog) {
96-
return new DefaultCommandExecution(resolvers, validator, terminal, conversionService, commandCatalog);
96+
Terminal terminal, ShellContext shellContext, ConversionService conversionService, CommandCatalog commandCatalog) {
97+
return new DefaultCommandExecution(resolvers, validator, terminal, shellContext, conversionService, commandCatalog);
9798
}
9899

99100
/**
@@ -104,14 +105,16 @@ static class DefaultCommandExecution implements CommandExecution {
104105
private List<? extends HandlerMethodArgumentResolver> resolvers;
105106
private Validator validator;
106107
private Terminal terminal;
108+
private ShellContext shellContext;
107109
private ConversionService conversionService;
108110
private CommandCatalog commandCatalog;
109111

110112
public DefaultCommandExecution(List<? extends HandlerMethodArgumentResolver> resolvers, Validator validator,
111-
Terminal terminal, ConversionService conversionService, CommandCatalog commandCatalog) {
113+
Terminal terminal, ShellContext shellContext, ConversionService conversionService, CommandCatalog commandCatalog) {
112114
this.resolvers = resolvers;
113115
this.validator = validator;
114116
this.terminal = terminal;
117+
this.shellContext = shellContext;
115118
this.conversionService = conversionService;
116119
this.commandCatalog = commandCatalog;
117120
}
@@ -175,7 +178,7 @@ public Object evaluate(String[] args) {
175178
throw new CommandParserExceptionsException("Command parser resulted errors", results.errors());
176179
}
177180

178-
CommandContext ctx = CommandContext.of(args, results, terminal, usedRegistration);
181+
CommandContext ctx = CommandContext.of(args, results, terminal, usedRegistration, shellContext);
179182

180183
Object res = null;
181184

spring-shell-core/src/main/java/org/springframework/shell/context/DefaultShellContext.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 the original author or authors.
2+
* Copyright 2022-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,6 +25,15 @@
2525
public class DefaultShellContext implements ShellContext {
2626

2727
private InteractionMode interactionMode = InteractionMode.ALL;
28+
private final boolean pty;
29+
30+
public DefaultShellContext() {
31+
this(false);
32+
}
33+
34+
public DefaultShellContext(boolean pty) {
35+
this.pty = pty;
36+
}
2837

2938
@Override
3039
public InteractionMode getInteractionMode() {
@@ -36,4 +45,9 @@ public void setInteractionMode(InteractionMode interactionMode) {
3645
Assert.notNull(interactionMode, "mode cannot be null");
3746
this.interactionMode = interactionMode;
3847
}
48+
49+
@Override
50+
public boolean hasPty() {
51+
return this.pty;
52+
}
3953
}

spring-shell-core/src/main/java/org/springframework/shell/context/ShellContext.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 the original author or authors.
2+
* Copyright 2022-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -36,4 +36,13 @@ public interface ShellContext {
3636
* @param interactionMode the interaction mode
3737
*/
3838
void setInteractionMode(InteractionMode interactionMode);
39+
40+
/**
41+
* Gets if shell has a proper {@code pty} terminal. Terminal don't have
42+
* {@code pty} in cases where output is piped into a file or terminal is run in
43+
* an ci system where there is no real user interaction.
44+
*
45+
* @return {@code true} if terminal has pty features
46+
*/
47+
boolean hasPty();
3948
}

spring-shell-core/src/test/java/org/springframework/shell/command/CommandExecutionCustomConversionTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 the original author or authors.
2+
* Copyright 2023-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -43,7 +43,7 @@ public void setupCommandExecutionTests() {
4343
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
4444
resolvers.add(new ArgumentHeaderMethodArgumentResolver(conversionService, null));
4545
resolvers.add(new CommandContextMethodArgumentResolver());
46-
execution = CommandExecution.of(resolvers, null, null, conversionService, commandCatalog);
46+
execution = CommandExecution.of(resolvers, null, null, null, conversionService, commandCatalog);
4747
}
4848

4949
@Test

spring-shell-core/src/test/java/org/springframework/shell/command/CommandExecutionTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public void setupCommandExecutionTests() {
4747
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
4848
resolvers.add(new ArgumentHeaderMethodArgumentResolver(conversionService, null));
4949
resolvers.add(new CommandContextMethodArgumentResolver());
50-
execution = CommandExecution.of(resolvers, null, null, conversionService, commandCatalog);
50+
execution = CommandExecution.of(resolvers, null, null, null, conversionService, commandCatalog);
5151
}
5252

5353
@Test

spring-shell-docs/modules/ROOT/nav.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
*** xref:appendices/techintro/registration.adoc[]
8888
*** xref:appendices/techintro/parser.adoc[]
8989
*** xref:appendices/techintro/execution.adoc[]
90+
*** xref:appendices/techintro/shellcontext.adoc[]
9091
*** xref:appendices/techintro/commandcontext.adoc[]
9192
*** xref:appendices/techintro/commandcatalog.adoc[]
9293
*** xref:appendices/techintro/theming.adoc[]

0 commit comments

Comments
 (0)