Split sample app
- spring-shell-sample-commands and spring-shell-sample-e2e - Needed changes in e2e tests and workflow - Fixes #754
This commit is contained in:
9
.github/workflows/e2e.yml
vendored
9
.github/workflows/e2e.yml
vendored
@@ -42,9 +42,12 @@ jobs:
|
||||
name: spring-shell-samples-${{ matrix.nickname }}
|
||||
retention-days: 1
|
||||
path: |
|
||||
spring-shell-samples/build/libs/*.jar
|
||||
spring-shell-samples/build/native/nativeCompile/spring-shell-samples
|
||||
spring-shell-samples/build/native/nativeCompile/spring-shell-samples.exe
|
||||
spring-shell-samples/spring-shell-sample-commands/build/libs/*.jar
|
||||
spring-shell-samples/spring-shell-sample-commands/build/native/nativeCompile/spring-shell-sample-commands
|
||||
spring-shell-samples/spring-shell-sample-commands/build/native/nativeCompile/spring-shell-sample-commands.exe
|
||||
spring-shell-samples/spring-shell-sample-e2e/build/libs/*.jar
|
||||
spring-shell-samples/spring-shell-sample-e2e/build/native/nativeCompile/spring-shell-sample-e2e
|
||||
spring-shell-samples/spring-shell-sample-e2e/build/native/nativeCompile/spring-shell-sample-e2e.exe
|
||||
- name: Upload Build Logs
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
|
||||
37
.vscode/launch.json
vendored
37
.vscode/launch.json
vendored
@@ -3,41 +3,48 @@
|
||||
"configurations": [
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Sample interactive",
|
||||
"name": "commands interactive",
|
||||
"request": "launch",
|
||||
"mainClass": "org.springframework.shell.samples.SpringShellSample",
|
||||
"projectName": "spring-shell-samples"
|
||||
"projectName": "spring-shell-sample-commands"
|
||||
},
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Sample help",
|
||||
"name": "commands help",
|
||||
"request": "launch",
|
||||
"mainClass": "org.springframework.shell.samples.SpringShellSample",
|
||||
"projectName": "spring-shell-samples",
|
||||
"projectName": "spring-shell-sample-commands",
|
||||
"args": "help"
|
||||
},
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Sample fail noarg",
|
||||
"name": "commands fail noarg",
|
||||
"request": "launch",
|
||||
"mainClass": "org.springframework.shell.samples.SpringShellSample",
|
||||
"projectName": "spring-shell-samples",
|
||||
"projectName": "spring-shell-sample-commands",
|
||||
"args": "fail"
|
||||
},
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Sample fail arg",
|
||||
"name": "commands fail arg",
|
||||
"request": "launch",
|
||||
"mainClass": "org.springframework.shell.samples.SpringShellSample",
|
||||
"projectName": "spring-shell-samples",
|
||||
"projectName": "spring-shell-sample-commands",
|
||||
"args": "fail --elementType TYPE"
|
||||
},
|
||||
{
|
||||
"type": "java",
|
||||
"name": "e2e interactive",
|
||||
"request": "launch",
|
||||
"mainClass": "org.springframework.shell.samples.SpringShellSample",
|
||||
"projectName": "spring-shell-sample-e2e"
|
||||
},
|
||||
{
|
||||
"type": "java",
|
||||
"name": "e2e reg error-handling",
|
||||
"request": "launch",
|
||||
"mainClass": "org.springframework.shell.samples.SpringShellSample",
|
||||
"projectName": "spring-shell-samples",
|
||||
"projectName": "spring-shell-sample-e2e",
|
||||
"args": "e2e reg error-handling"
|
||||
},
|
||||
{
|
||||
@@ -45,7 +52,7 @@
|
||||
"name": "e2e reg error-handling arg1 throw1",
|
||||
"request": "launch",
|
||||
"mainClass": "org.springframework.shell.samples.SpringShellSample",
|
||||
"projectName": "spring-shell-samples",
|
||||
"projectName": "spring-shell-sample-e2e",
|
||||
"args": "e2e reg error-handling --arg1 throw1"
|
||||
},
|
||||
{
|
||||
@@ -53,7 +60,7 @@
|
||||
"name": "e2e reg error-handling arg1 throw2",
|
||||
"request": "launch",
|
||||
"mainClass": "org.springframework.shell.samples.SpringShellSample",
|
||||
"projectName": "spring-shell-samples",
|
||||
"projectName": "spring-shell-sample-e2e",
|
||||
"args": "e2e reg error-handling --arg1 throw2"
|
||||
},
|
||||
{
|
||||
@@ -61,7 +68,7 @@
|
||||
"name": "e2e reg error-handling arg1 throw3",
|
||||
"request": "launch",
|
||||
"mainClass": "org.springframework.shell.samples.SpringShellSample",
|
||||
"projectName": "spring-shell-samples",
|
||||
"projectName": "spring-shell-sample-e2e",
|
||||
"args": "e2e reg error-handling --arg1 throw3"
|
||||
},
|
||||
{
|
||||
@@ -69,7 +76,7 @@
|
||||
"name": "e2e exit-code noarg",
|
||||
"request": "launch",
|
||||
"mainClass": "org.springframework.shell.samples.SpringShellSample",
|
||||
"projectName": "spring-shell-samples",
|
||||
"projectName": "spring-shell-sample-e2e",
|
||||
"args": "e2e reg exit-code"
|
||||
},
|
||||
{
|
||||
@@ -77,7 +84,7 @@
|
||||
"name": "e2e exit-code arg hi",
|
||||
"request": "launch",
|
||||
"mainClass": "org.springframework.shell.samples.SpringShellSample",
|
||||
"projectName": "spring-shell-samples",
|
||||
"projectName": "spring-shell-sample-e2e",
|
||||
"args": "e2e reg exit-code --arg1 hi"
|
||||
},
|
||||
{
|
||||
@@ -85,7 +92,7 @@
|
||||
"name": "e2e exit-code arg fun",
|
||||
"request": "launch",
|
||||
"mainClass": "org.springframework.shell.samples.SpringShellSample",
|
||||
"projectName": "spring-shell-samples",
|
||||
"projectName": "spring-shell-sample-e2e",
|
||||
"args": "e2e reg exit-code --arg1 fun"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -31,7 +31,7 @@ Generic workflow to run `spring-shell-e2e-tests` is:
|
||||
[source, bash]
|
||||
----
|
||||
spring-shell
|
||||
$ ./gradlew build nativeCompile -PspringShellSampleE2E=true -x test
|
||||
$ ./gradlew :spring-shell-samples:spring-shell-sample-e2e:build :spring-shell-samples:spring-shell-sample-e2e:nativeCompile -PspringShellSampleE2E=true -x test
|
||||
|
||||
spring-shell/e2e/spring-shell-e2e
|
||||
$ npm install
|
||||
|
||||
@@ -4,18 +4,28 @@ import * as path from 'path';
|
||||
export const tempDir = path.join(__dirname, 'spring-shell', 'temp');
|
||||
export const isWindows = os.platform() === 'win32';
|
||||
export const cliPathRelative = isWindows
|
||||
? '..\\..\\spring-shell-samples\\build\\native\\nativeCompile\\spring-shell-samples.exe'
|
||||
: '../../spring-shell-samples/build/native/nativeCompile/spring-shell-samples';
|
||||
? '..\\..\\spring-shell-samples\\spring-shell-sample-e2e\\build\\native\\nativeCompile\\spring-shell-sample-e2e.exe'
|
||||
: '../../spring-shell-samples/spring-shell-sample-e2e/build/native/nativeCompile/spring-shell-sample-e2e';
|
||||
export const commandsCliPathRelative = isWindows
|
||||
? '..\\..\\spring-shell-samples\\spring-shell-sample-commands\\build\\native\\nativeCompile\\spring-shell-sample-commands.exe'
|
||||
: '../../spring-shell-samples/spring-shell-sample-commands/build/native/nativeCompile/spring-shell-sample-commands';
|
||||
export const jarPathRelative = isWindows
|
||||
? '..\\..\\spring-shell-samples\\build\\libs\\spring-shell-samples.jar'
|
||||
: '../../spring-shell-samples/build/libs/spring-shell-samples.jar';
|
||||
? '..\\..\\spring-shell-samples\\spring-shell-sample-e2e\\build\\libs\\spring-shell-sample-e2e.jar'
|
||||
: '../../spring-shell-samples/spring-shell-sample-e2e/build/libs/spring-shell-sample-e2e.jar';
|
||||
export const commandsJarPathRelative = isWindows
|
||||
? '..\\..\\spring-shell-samples\\spring-shell-sample-commands\\build\\libs\\spring-shell-sample-commands.jar'
|
||||
: '../../spring-shell-samples/spring-shell-sample-commands/build/libs/spring-shell-sample-commands.jar';
|
||||
export const cliPath = path.resolve(cliPathRelative);
|
||||
export const commandsCliPath = path.resolve(commandsCliPathRelative);
|
||||
export const jarPath = path.resolve(jarPathRelative);
|
||||
export const commandsJarPath = path.resolve(commandsJarPathRelative);
|
||||
export const nativeDesc = 'native';
|
||||
export const jarDesc = 'jar';
|
||||
export const jarCommand = isWindows ? 'java.exe' : 'java';
|
||||
export const nativeCommand = cliPath;
|
||||
export const commandsNativeCommand = commandsCliPath;
|
||||
export const jarOptions = ['-jar', jarPath];
|
||||
export const commandsJarOptions = ['-jar', commandsJarPath];
|
||||
export const waitForExpectDefaultTimeout = 30000;
|
||||
export const waitForExpectDefaultInterval = 2000;
|
||||
export const testTimeout = 120000;
|
||||
|
||||
@@ -5,8 +5,8 @@ import {
|
||||
nativeDesc,
|
||||
jarDesc,
|
||||
jarCommand,
|
||||
nativeCommand,
|
||||
jarOptions,
|
||||
commandsNativeCommand,
|
||||
commandsJarOptions,
|
||||
waitForExpectDefaultTimeout,
|
||||
waitForExpectDefaultInterval,
|
||||
testTimeout
|
||||
@@ -71,7 +71,7 @@ describe('flow commands', () => {
|
||||
describe(jarDesc, () => {
|
||||
beforeAll(() => {
|
||||
command = jarCommand;
|
||||
options = jarOptions;
|
||||
options = commandsJarOptions;
|
||||
});
|
||||
|
||||
it(
|
||||
@@ -92,7 +92,7 @@ describe('flow commands', () => {
|
||||
*/
|
||||
describe(nativeDesc, () => {
|
||||
beforeAll(() => {
|
||||
command = nativeCommand;
|
||||
command = commandsNativeCommand;
|
||||
options = [];
|
||||
});
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@ include 'spring-shell-core-test-support'
|
||||
include 'spring-shell-management'
|
||||
include 'spring-shell-dependencies'
|
||||
include 'spring-shell-docs'
|
||||
include 'spring-shell-samples'
|
||||
include 'spring-shell-standard'
|
||||
include 'spring-shell-standard-commands'
|
||||
include 'spring-shell-table'
|
||||
@@ -56,12 +55,22 @@ file("${rootDir}/spring-shell-starters").eachDirMatch(~/spring-shell-starter.*/)
|
||||
include "spring-shell-starters:${it.name}"
|
||||
}
|
||||
|
||||
file("${rootDir}/spring-shell-samples").eachDirMatch(~/spring-shell-sample.*/) {
|
||||
include "spring-shell-samples:${it.name}"
|
||||
}
|
||||
|
||||
rootProject.children.each { project ->
|
||||
if (project.name == 'spring-shell-starters') {
|
||||
project.children.each { subproject ->
|
||||
subproject.buildFileName = "${subproject.name}.gradle"
|
||||
subproject.buildFileName = "${subproject.name}.gradle"
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else if (project.name == 'spring-shell-samples') {
|
||||
project.children.each { subproject ->
|
||||
subproject.buildFileName = "${subproject.name}.gradle"
|
||||
}
|
||||
}
|
||||
else {
|
||||
project.buildFileName = "${project.name}.gradle"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
plugins {
|
||||
id 'org.springframework.shell.sample'
|
||||
id 'org.springframework.boot'
|
||||
id 'org.graalvm.buildtools.native'
|
||||
}
|
||||
|
||||
description = 'Spring Shell Sample Commands'
|
||||
|
||||
dependencies {
|
||||
management platform(project(":spring-shell-management"))
|
||||
implementation project(':spring-shell-starters:spring-shell-starter-jna')
|
||||
testImplementation project(':spring-shell-starters:spring-shell-starter-test')
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
testImplementation 'org.awaitility:awaitility'
|
||||
}
|
||||
|
||||
springBoot {
|
||||
buildInfo()
|
||||
}
|
||||
|
||||
if (project.hasProperty('springShellSampleE2E') && springShellSampleE2E.toBoolean()) {
|
||||
bootJar {
|
||||
archiveName = "$baseName.$extension"
|
||||
}
|
||||
}
|
||||
|
||||
graalvmNative {
|
||||
metadataRepository {
|
||||
enabled = true
|
||||
}
|
||||
binaries {
|
||||
main {
|
||||
if (project.hasProperty('springShellSampleMusl') && springShellSampleMusl.toBoolean()) {
|
||||
buildArgs.add('--static')
|
||||
buildArgs.add('--libc=musl')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ plugins {
|
||||
id 'org.graalvm.buildtools.native'
|
||||
}
|
||||
|
||||
description = 'Spring Shell Samples'
|
||||
description = 'Spring Shell Sample E2E'
|
||||
|
||||
dependencies {
|
||||
management platform(project(":spring-shell-management"))
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2017-2023 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.samples;
|
||||
|
||||
import org.jline.utils.AttributedString;
|
||||
import org.jline.utils.AttributedStyle;
|
||||
|
||||
import org.springframework.boot.Banner.Mode;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.shell.command.annotation.CommandScan;
|
||||
import org.springframework.shell.jline.PromptProvider;
|
||||
|
||||
/**
|
||||
* Main entry point for the application.
|
||||
*
|
||||
* <p>Creates the application context and start the REPL.</p>
|
||||
*
|
||||
* @author Eric Bottard
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@CommandScan
|
||||
public class SpringShellSample {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication application = new SpringApplication(SpringShellSample.class);
|
||||
application.setBannerMode(Mode.OFF);
|
||||
application.run(args);
|
||||
// TODO: follow up with boot why spring.main.banner-mode=off doesn't work
|
||||
// SpringApplication.run(SpringShellSample.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PromptProvider myPromptProvider() {
|
||||
return () -> new AttributedString("my-shell:>", AttributedStyle.DEFAULT.foreground(AttributedStyle.YELLOW));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
spring:
|
||||
main:
|
||||
banner-mode: off
|
||||
shell:
|
||||
## pick global default option naming
|
||||
# option:
|
||||
# naming:
|
||||
# case-type: noop
|
||||
# case-type: camel
|
||||
# case-type: snake
|
||||
# case-type: kebab
|
||||
# case-type: pascal
|
||||
config:
|
||||
env: SPRING_SHELL_SAMPLES_USER_HOME
|
||||
location: "{userconfig}/spring-shell-samples"
|
||||
history:
|
||||
name: spring-shell-samples-history.log
|
||||
command:
|
||||
help:
|
||||
grouping-mode: group
|
||||
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,72 @@
|
||||
/*
|
||||
* Copyright 2022-2023 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.samples;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.assertj.core.api.Condition;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.shell.test.ShellAssertions;
|
||||
import org.springframework.shell.test.ShellTestClient;
|
||||
import org.springframework.shell.test.ShellTestClient.BaseShellSession;
|
||||
import org.springframework.shell.test.ShellTestClient.InteractiveShellSession;
|
||||
import org.springframework.shell.test.ShellTestClient.NonInteractiveShellSession;
|
||||
import org.springframework.shell.test.autoconfigure.ShellTest;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.annotation.DirtiesContext.ClassMode;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.awaitility.Awaitility.await;
|
||||
|
||||
@ShellTest(terminalWidth = 120)
|
||||
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
public class AbstractSampleTests {
|
||||
|
||||
@Autowired
|
||||
protected ShellTestClient client;
|
||||
|
||||
protected void assertScreenContainsText(BaseShellSession<?> session, String text) {
|
||||
await().atMost(2, TimeUnit.SECONDS).untilAsserted(() -> {
|
||||
ShellAssertions.assertThat(session.screen()).containsText(text);
|
||||
});
|
||||
}
|
||||
|
||||
protected void assertScreenNotContainsText(BaseShellSession<?> session, String textFound, String textNotFound) {
|
||||
Condition<String> notCondition = new Condition<>(line -> line.contains(textNotFound),
|
||||
String.format("Text '%s' not found", textNotFound));
|
||||
|
||||
await().atMost(2, TimeUnit.SECONDS).untilAsserted(() -> {
|
||||
ShellAssertions.assertThat(session.screen()).containsText(textFound);
|
||||
List<String> lines = session.screen().lines();
|
||||
assertThat(lines).areNot(notCondition);
|
||||
});
|
||||
}
|
||||
|
||||
protected BaseShellSession<?> createSession(String command, boolean interactive) {
|
||||
if (interactive) {
|
||||
InteractiveShellSession session = client.interactive().run();
|
||||
session.write(session.writeSequence().command(command).build());
|
||||
return session;
|
||||
}
|
||||
else {
|
||||
String[] commands = command.split(" ");
|
||||
NonInteractiveShellSession session = client.nonInterative(commands).run();
|
||||
return session;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user