diff --git a/.docker/gs64/docker-tests.sh b/.docker/gs64/docker-tests.sh index a296c64..76d98c2 100755 --- a/.docker/gs64/docker-tests.sh +++ b/.docker/gs64/docker-tests.sh @@ -48,6 +48,16 @@ function assertOutputIncludesMessage() { fi } +function assertOutputIsEmpty() { + local output=$1 + + if [ -s "$output" ];then + print_error "Expected std$output to be empty when invoked with $LAST_ARGUMENTS" + cat "$output" + exit 1 + fi +} + set -e if [ $# -eq 0 ]; then @@ -144,6 +154,14 @@ assertOutputIncludesMessage "\[ERROR\] \"Name\" parameter not provided. You must print_success " Missing name, OK" run_launchpad_gem launchpad start greeter assertOutputIncludesMessage "\[ERROR\] \"Name\" parameter not provided. You must provide one." err +print_success " Missing name and title, OK" + +run_launchpad_gem launchpad start --dry-run greeter --name=Juan --title=Mr +assertOutputIsEmpty err +print_success " Dry run with valid parameters, OK" +run_launchpad_gem launchpad start --dry-run greeter +assertOutputIncludesMessage "\[ERROR\] \"Name\" parameter not provided. You must provide one." err +print_success " Dry run with missing parameters, OK" print_success "OK" print_info "Running launchpad start broken test" @@ -151,6 +169,10 @@ run_launchpad_gem launchpad start broken --raise-error assertOutputIncludesMessage "\[INFO\] Obtaining configuration... \[DONE\]" out assertOutputIncludesMessage "\[ERROR\] Unexpected startup error: \"Doh!\"" err print_success "OK" +run_launchpad_gem launchpad start --dry-run broken --raise-error +assertOutputIsEmpty err +assertOutputIncludesMessage "\[INFO\] Obtaining configuration... \[DONE\]" out +print_success "Dry run, OK" print_info "Stopping stone" docker stop gs64-stone diff --git a/.docker/pharo/docker-tests.sh b/.docker/pharo/docker-tests.sh index 67d8c11..9a6e8e9 100755 --- a/.docker/pharo/docker-tests.sh +++ b/.docker/pharo/docker-tests.sh @@ -48,6 +48,16 @@ function assertOutputIncludesMessage() { fi } +function assertOutputIsEmpty() { + local output=$1 + + if [ -s "$output" ];then + print_error "Expected std$output to be empty when invoked with $LAST_ARGUMENTS" + cat "$output" + exit 1 + fi +} + set -e print_info "Building base image" @@ -108,6 +118,13 @@ assertOutputIncludesMessage "\[ERROR\] \"Name\" parameter not provided. You must print_success " Missing name, OK" executeWithArguments docker run launchpad-examples:sut launchpad-start greeter assertOutputIncludesMessage "\[ERROR\] \"Name\" parameter not provided. You must provide one." err +print_success " Missing name and title, OK" +executeWithArguments docker run launchpad-examples:sut launchpad-start --dry-run greeter --name=Juan --title=Mr +assertOutputIsEmpty err +print_success " Dry run with valid parameters, OK" +executeWithArguments docker run launchpad-examples:sut launchpad-start --dry-run greeter +assertOutputIncludesMessage "\[ERROR\] \"Name\" parameter not provided. You must provide one." err +print_success " Dry run with missing parameters, OK" print_success "OK" print_info "Running launchpad-start broken test" @@ -115,6 +132,10 @@ executeWithArguments docker run launchpad-examples:sut launchpad-start broken -- assertOutputIncludesMessage "\[INFO\] Obtaining configuration... \[DONE\]" out assertOutputIncludesMessage "\[ERROR\] Unexpected startup error: \"Doh!\"" err print_success "OK" +executeWithArguments docker run launchpad-examples:sut launchpad-start --dry-run broken --raise-error +assertOutputIsEmpty err +assertOutputIncludesMessage "\[INFO\] Obtaining configuration... \[DONE\]" out +print_success "Dry run, OK" print_info "Running launchpad-start command server test" # broken app keeps running when passed and invalid option diff --git a/docs/explanation/Application-start-up.md b/docs/explanation/Application-start-up.md index d729b4d..7239b49 100644 --- a/docs/explanation/Application-start-up.md +++ b/docs/explanation/Application-start-up.md @@ -20,7 +20,7 @@ the logging infrastructure: `stdout` on Unix); because there's no way to access the `stderr` handle attached to the VM process. -As a second step, it instantiates a `LaunchpadCommandLineProcessingContext` with +As a second step, it instantiates a `LaunchpadApplicationStartingContext` with the command-line and a reference to `stdout`. This context is later available in all the required methods and ultimately accessible by the application in its `basicStartWithin:` method. diff --git a/docs/reference/CLI.md b/docs/reference/CLI.md index cac3464..b3edf3b 100644 --- a/docs/reference/CLI.md +++ b/docs/reference/CLI.md @@ -197,6 +197,7 @@ The `start` sub-command will start the selected application. launchpad start [--help|-h] [--debug-mode] [--settings-file=] [--enable-tcp-command-server=] [--enable-structured-logging] + [--dry-run] [] ``` @@ -247,7 +248,7 @@ $ launchpad start greeter launchpad-start - Start the selected application SYNOPSYS launchpad start [--help|-h] [--debug-mode] - [--settings-file=] [] + [--settings-file=] [--dry-run] [] DESCRIPTION Start the application selected via . @@ -268,6 +269,10 @@ $ launchpad start greeter This option can occur several times to configure more than one settings file. Supported file settings formats are INI and JSON. + --dry-run + Perform a dry run of the application. + All the configuration will be loaded (and validated), + but the application will not start. ``` - `debug-mode` Enable the debugging mode. @@ -290,3 +295,5 @@ $ launchpad start greeter can be used to send commands controlling the application using a TCP port. - `--enable-structured-logging` Enable structured logging. When enabled the log will be emitted in JSON format. +- `--dry-run` Perform a dry run of the application. All the configuration will + be loaded (and validated), but the application will not start. diff --git a/source/Launchpad-Applications/LaunchpadApplication.class.st b/source/Launchpad-Applications/LaunchpadApplication.class.st index b3cca05..a92b253 100644 --- a/source/Launchpad-Applications/LaunchpadApplication.class.st +++ b/source/Launchpad-Applications/LaunchpadApplication.class.st @@ -188,16 +188,14 @@ LaunchpadApplication >> stackTraceDumper [ LaunchpadApplication >> startWithin: context [ mode - value: [ + value: [ commandServer start. LogRecord emitInfo: self class summary. - self - logConfigurationWithin: context; - basicStartWithin: context + self logConfigurationWithin: context. + context run: [ self basicStartWithin: context ] ] - onErrorDo: [ :error | - LogRecord emitError: - ( 'Unexpected startup error: "<1s>"' expandMacrosWith: error messageText ). + onErrorDo: [ :error | + LogRecord emitError: ( 'Unexpected startup error: "<1s>"' expandMacrosWith: error messageText ). self stackTraceDumper dumpStackTraceFor: error. self exitFailure ] diff --git a/source/Launchpad-Commands-Pharo/LaunchpadStartApplicationCommand.extension.st b/source/Launchpad-Commands-Pharo/LaunchpadStartApplicationCommand.extension.st index 2df8cf0..48cba5f 100644 --- a/source/Launchpad-Commands-Pharo/LaunchpadStartApplicationCommand.extension.st +++ b/source/Launchpad-Commands-Pharo/LaunchpadStartApplicationCommand.extension.st @@ -1,6 +1,6 @@ -Extension { #name : #LaunchpadStartApplicationCommand } +Extension { #name : 'LaunchpadStartApplicationCommand' } -{ #category : #'*Launchpad-Commands-Pharo' } +{ #category : '*Launchpad-Commands-Pharo' } LaunchpadStartApplicationCommand >> enableTCPCommandServerListeningOn: listeningPort [ commandServer := TCPCommandServer listeningOn: listeningPort. diff --git a/source/Launchpad-Commands-Pharo/LaunchpadTCPCommandServerOption.class.st b/source/Launchpad-Commands-Pharo/LaunchpadTCPCommandServerOption.class.st index 38da792..82769d8 100644 --- a/source/Launchpad-Commands-Pharo/LaunchpadTCPCommandServerOption.class.st +++ b/source/Launchpad-Commands-Pharo/LaunchpadTCPCommandServerOption.class.st @@ -1,65 +1,67 @@ Class { - #name : #LaunchpadTCPCommandServerOption, - #superclass : #LaunchpadOption, + #name : 'LaunchpadTCPCommandServerOption', + #superclass : 'LaunchpadOption', #instVars : [ 'command' ], - #category : #'Launchpad-Commands-Pharo' + #category : 'Launchpad-Commands-Pharo', + #package : 'Launchpad-Commands-Pharo' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } LaunchpadTCPCommandServerOption class >> for: aCommand [ ^ self new initializeFor: aCommand ] -{ #category : #testing } +{ #category : 'testing' } LaunchpadTCPCommandServerOption class >> isExtendedStartingOption [ ^ true ] -{ #category : #testing } +{ #category : 'testing' } LaunchpadTCPCommandServerOption >> canHandle: argument [ ^ argument beginsWith: '--' , self name , '=' ] -{ #category : #evaluating } +{ #category : 'evaluating' } LaunchpadTCPCommandServerOption >> evaluateWithin: context handling: argument [ | listeningPort | listeningPort := ( argument withoutFirst: self name size + 3 ) asNumber. - command enableTCPCommandServerListeningOn: listeningPort + command enableTCPCommandServerListeningOn: listeningPort. + ^ context ] -{ #category : #initialization } +{ #category : 'initialization' } LaunchpadTCPCommandServerOption >> initializeFor: aCommand [ command := aCommand ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadTCPCommandServerOption >> name [ ^ 'enable-tcp-command-server' ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadTCPCommandServerOption >> printHelpOn: stream [ super printHelpOn: stream. self printSuffixOn: stream ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadTCPCommandServerOption >> printSuffixOn: stream [ stream nextPutAll: '=' ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadTCPCommandServerOption >> summary [ ^ 'Enable a TCP command server. This can be used to send commands controlling the application using a TCP port.' diff --git a/source/Launchpad-Commands-Pharo/TCPCommandServer.class.st b/source/Launchpad-Commands-Pharo/TCPCommandServer.class.st index c7cf0fd..3fefcff 100644 --- a/source/Launchpad-Commands-Pharo/TCPCommandServer.class.st +++ b/source/Launchpad-Commands-Pharo/TCPCommandServer.class.st @@ -1,28 +1,29 @@ Class { - #name : #TCPCommandServer, - #superclass : #CommandServer, + #name : 'TCPCommandServer', + #superclass : 'CommandServer', #instVars : [ 'listeningPort', 'commmands', 'connectionSocket', 'serverProcess' ], - #category : #'Launchpad-Commands-Pharo' + #category : 'Launchpad-Commands-Pharo', + #package : 'Launchpad-Commands-Pharo' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } TCPCommandServer class >> listeningOn: port [ ^ self new initializeListeningOn: port ] -{ #category : #private } +{ #category : 'private' } TCPCommandServer >> initializeConnectionSocket [ connectionSocket := Socket newTCP ] -{ #category : #initialize } +{ #category : 'initialize' } TCPCommandServer >> initializeListeningOn: port [ listeningPort := port. @@ -30,19 +31,19 @@ TCPCommandServer >> initializeListeningOn: port [ self initializeConnectionSocket ] -{ #category : #accessing } +{ #category : 'accessing' } TCPCommandServer >> listeningPort [ ^ listeningPort ] -{ #category : #registering } +{ #category : 'registering' } TCPCommandServer >> registerCommandNamed: commandName executing: aBlock [ commmands at: commandName put: aBlock ] -{ #category : #private } +{ #category : 'private' } TCPCommandServer >> serverLoop [ ^ [ @@ -57,7 +58,7 @@ TCPCommandServer >> serverLoop [ ] repeat ] -{ #category : #controlling } +{ #category : 'controlling' } TCPCommandServer >> start [ LogRecord emitInfo: @@ -74,7 +75,7 @@ TCPCommandServer >> start [ serverProcess resume ] -{ #category : #controlling } +{ #category : 'controlling' } TCPCommandServer >> stop [ serverProcess ifNotNil: #terminate. diff --git a/source/Launchpad-Commands-Pharo/package.st b/source/Launchpad-Commands-Pharo/package.st index d1fc72f..8e9cba9 100644 --- a/source/Launchpad-Commands-Pharo/package.st +++ b/source/Launchpad-Commands-Pharo/package.st @@ -1 +1 @@ -Package { #name : #'Launchpad-Commands-Pharo' } +Package { #name : 'Launchpad-Commands-Pharo' } diff --git a/source/Launchpad-Commands-Tests/LaunchpadApplicationDryRunContextTest.class.st b/source/Launchpad-Commands-Tests/LaunchpadApplicationDryRunContextTest.class.st new file mode 100644 index 0000000..eefa779 --- /dev/null +++ b/source/Launchpad-Commands-Tests/LaunchpadApplicationDryRunContextTest.class.st @@ -0,0 +1,19 @@ +" +A LaunchpadApplicationDryRunContextTest is a test class for testing the behavior of LaunchpadApplicationDryRunContext +" +Class { + #name : 'LaunchpadApplicationDryRunContextTest', + #superclass : 'TestCase', + #category : 'Launchpad-Commands-Tests', + #package : 'Launchpad-Commands-Tests' +} + +{ #category : 'tests' } +LaunchpadApplicationDryRunContextTest >> testConverting [ + + | context | + + context := LaunchpadApplicationDryRunContext handling: ( CommandLineArguments withArguments: #( ) ). + + self assert: context asDryRunContext equals: context +] diff --git a/source/Launchpad-Commands-Tests/LaunchpadCommandLineHandlerTest.class.st b/source/Launchpad-Commands-Tests/LaunchpadCommandLineHandlerTest.class.st index f5fecf5..0186b7f 100644 --- a/source/Launchpad-Commands-Tests/LaunchpadCommandLineHandlerTest.class.st +++ b/source/Launchpad-Commands-Tests/LaunchpadCommandLineHandlerTest.class.st @@ -2,39 +2,87 @@ A LaunchpadCommandLineHandlerTest is a test class for testing the behavior of LaunchpadCommandLineHandler " Class { - #name : #LaunchpadCommandLineHandlerTest, - #superclass : #LaunchpadTest, - #category : #'Launchpad-Commands-Tests' + #name : 'LaunchpadCommandLineHandlerTest', + #superclass : 'LaunchpadTest', + #category : 'Launchpad-Commands-Tests', + #package : 'Launchpad-Commands-Tests' } -{ #category : #tests } +{ #category : 'tests' } +LaunchpadCommandLineHandlerTest >> testApplicationConfiguration [ + + self dryRun: LaunchpadGreeterApplication withAll: #( '--name=John' ). + + self + assert: runningApplication configuration name equals: 'John'; + assert: runningApplication configuration title isEmpty; + assert: ( runningApplication configuration valueAt: #name ) equals: 'John'; + assert: ( runningApplication configuration valueAt: #title ) isEmpty. + + self dryRun: LaunchpadGreeterApplication withAll: #( '--name=John' '--title=Dr.' ). + + self + assert: runningApplication configuration name equals: 'John'; + assert: runningApplication configuration title equals: 'Dr.'; + assert: ( runningApplication configuration valueAt: #name ) equals: 'John'; + assert: ( runningApplication configuration valueAt: #title ) equals: 'Dr.'; + should: [ runningApplication configuration valueAt: #unknown ] raise: Error +] + +{ #category : 'tests' } LaunchpadCommandLineHandlerTest >> testDescription [ self assert: LaunchpadCommandLineHandler description equals: 'A minimal application launcher' ] -{ #category : #tests } -LaunchpadCommandLineHandlerTest >> testHandlingHelpOption [ +{ #category : 'tests' } +LaunchpadCommandLineHandlerTest >> testDryRunApplication [ + + self + should: [ + LaunchpadCommandLineHandler activateWithArguments: + #( 'launchpad' 'start' '--dry-run' 'greeter' '--name=John' ) + ] + raise: Exit + withExceptionDo: [ :exit | self assert: exit isSuccess ] - | commandLine | + "When a mandatory argument is missing the dry-run option makes the application exit with error". + self + should: [ + LaunchpadCommandLineHandler activateWithArguments: #( 'launchpad' 'start' '--dry-run' 'greeter' ) ] + raise: Exit + withExceptionDo: [ :exit | self deny: exit isSuccess ] +] - commandLine := CommandLineArguments withArguments: #( 'launchpad' '--help' ). +{ #category : 'tests' } +LaunchpadCommandLineHandlerTest >> testDryRunBrokenApplication [ - self should: [ LaunchpadCommandLineHandler activateWith: commandLine ] + "Starting an application that will fail in dry-run mode, but not missing any configuration shouldn't fail" + + self + should: [ + LaunchpadCommandLineHandler activateWithArguments: #( 'launchpad' 'start' '--dry-run' 'broken' ) ] raise: Exit withExceptionDo: [ :exit | self assert: exit isSuccess ] ] -{ #category : #tests } -LaunchpadCommandLineHandlerTest >> testStartingApplication [ +{ #category : 'tests' } +LaunchpadCommandLineHandlerTest >> testHandlingHelpOption [ - | commandLine | + self + should: [ LaunchpadCommandLineHandler activateWithArguments: #( 'launchpad' '--help' ) ] + raise: Exit + withExceptionDo: [ :exit | self assert: exit isSuccess ] +] - commandLine := CommandLineArguments withArguments: #( 'launchpad' 'start' 'greeter' '--name=John' ). +{ #category : 'tests' } +LaunchpadCommandLineHandlerTest >> testStartingApplication [ self - should: [ LaunchpadCommandLineHandler activateWith: commandLine ] + should: [ + LaunchpadCommandLineHandler activateWithArguments: + #( 'launchpad' 'start' 'greeter' '--name=John' ) ] raise: Exit withExceptionDo: [ :exit | self assert: exit isSuccess ]. diff --git a/source/Launchpad-Commands-Tests/LaunchpadRootCommandTest.class.st b/source/Launchpad-Commands-Tests/LaunchpadRootCommandTest.class.st index 50f6925..f2065b8 100644 --- a/source/Launchpad-Commands-Tests/LaunchpadRootCommandTest.class.st +++ b/source/Launchpad-Commands-Tests/LaunchpadRootCommandTest.class.st @@ -2,15 +2,16 @@ A LaunchpadMainCommandTest is a test class for testing the behavior of LaunchpadMainCommand " Class { - #name : #LaunchpadRootCommandTest, - #superclass : #LaunchpadTest, + #name : 'LaunchpadRootCommandTest', + #superclass : 'LaunchpadTest', #instVars : [ 'command' ], - #category : #'Launchpad-Commands-Tests' + #category : 'Launchpad-Commands-Tests', + #package : 'Launchpad-Commands-Tests' } -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> assert: string isLineEndingInsensitiveEqualsTo: anotherString [ self @@ -18,20 +19,20 @@ LaunchpadRootCommandTest >> assert: string isLineEndingInsensitiveEqualsTo: anot equals: (anotherString withLineEndings: String lf) ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> assertCommandCanHandleNextArgumentIn: context [ self assert: ( command canHandle: ( context nextCommandLineArgumentIfNone: [ self fail ] ) ) ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> contextWithArguments: arguments writingTo: outputStream [ - ^ LaunchpadCommandLineProcessingContext handling: ( CommandLineArguments withArguments: arguments ) + ^ LaunchpadApplicationStartingContext handling: ( CommandLineArguments withArguments: arguments ) writingTo: outputStream ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> createFileNamed: fileName containing: fileContents during: aBlock [ | fileReference | @@ -44,60 +45,60 @@ LaunchpadRootCommandTest >> createFileNamed: fileName containing: fileContents d ] ensure: [ fileReference ensureDelete ] ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> existsExtendedStartingOptions [ ^ LaunchpadOption allLeafSubclasses anySatisfy: [ :optionClass | optionClass isExtendedStartingOption ] ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> expectedExplainBrokenHelpOutput [ ^ 'NAME broken [v0.0.1] - A broken applicationSYNOPSYS broken [--raise-error]COMMANDS --raise-error Raises an unexpected error. Useful to test stack trace generation.' expandMacros ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> expectedExplainGreeterHelpOutput [ ^ 'NAME greeter [v1.0.0] - A greetings applicationSYNOPSYS greeter --name=% [--title=%]<n>PARAMETERS<n> --name=%<name><n> The name of the user to greet.<n> --title=%<title><n> The title of the user to greet. Defaults to nothing.<n>ENVIRONMENT<n> NAME<n> The name of the user to greet.<n> TITLE<n> The title of the user to greet. Defaults to nothing.<n>' expandMacros ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> expectedExplainHelpOutput [ ^ 'NAME<n> launchpad-explain - Give details about the selected application<n>SYNOPSYS<n> launchpad explain [--help|-h] %<app><n>DESCRIPTION<n> Give details about the application selected via %<app> including its configuration options.<n>OPTIONS<n> -h, --help<n> Print this help message and exit.<n>' expandMacros ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> expectedHelpOutput [ ^ 'NAME<n> launchpad - A minimal application launcher<n>SYNOPSYS<n> launchpad [--version] [--help|-h] %<command><n>DESCRIPTION<n> A command-line interface to start, list, and explain the applications available within the image.<n>OPTIONS<n> --version<n> Print the version and exit.<n> -h, --help<n> Print this help message and exit.<n>COMMANDS<n> start<n> Start the selected application<n> list<n> List available applications<n> explain<n> Give details about the selected application<n>' expandMacros ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> expectedListHelpOutput [ ^ 'NAME<n> launchpad-list - List available applications<n>SYNOPSYS<n> launchpad list [--verbose|-v] [--help|-h]<n>DESCRIPTION<n> Lists the available applications contained in the image.<n>OPTIONS<n> -v, --verbose<n> Produce more verbose output.<n> -h, --help<n> Print this help message and exit.<n>' expandMacros ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> expectedStartHelpOutput [ ^ (self existsExtendedStartingOptions ifTrue: [ - 'NAME<n> launchpad-start - Start the selected application<n>SYNOPSYS<n> launchpad start [--help|-h] [--debug-mode] [--settings-file=%<filename>] [--enable-structured-logging] [--enable-tcp-command-server=%<listeningPort>] %<app> [%<parameters>]<n>DESCRIPTION<n> Start the application selected via %<app>.<n><n><t><t>Application configuration is made by the command-line via %<parameters>, using environment variables or settings files.<n><n><t><t>Execute launchpad explain %<app> to get a list of valid configuration parameters.<n>OPTIONS<n> -h, --help<n> Print this help message and exit.<n> --debug-mode<n> Enable the debugging mode. The image will not quit on unexpected errors. This configuration can be used in the application to improve the debugging experience.<n> --settings-file=%<filename><n> Provide application configuration via a settings file. This option can occur several times to configure more than one settings file. Supported file settings formats are INI and JSON.<n> --enable-structured-logging<n> Enable structured logging. When enabled the log will be emitted in JSON format.<n> --enable-tcp-command-server=%<listeningPort><n> Enable a TCP command server. This can be used to send commands controlling the application using a TCP port.<n>' ] + 'NAME<n> launchpad-start - Start the selected application<n>SYNOPSYS<n> launchpad start [--help|-h] [--debug-mode] [--settings-file=%<filename>] [--enable-structured-logging] [--dry-run] [--enable-tcp-command-server=%<listeningPort>] %<app> [%<parameters>]<n>DESCRIPTION<n> Start the application selected via %<app>.<n><n><t><t>Application configuration is made by the command-line via %<parameters>, using environment variables or settings files.<n><n><t><t>Execute launchpad explain %<app> to get a list of valid configuration parameters.<n>OPTIONS<n> -h, --help<n> Print this help message and exit.<n> --debug-mode<n> Enable the debugging mode. The image will not quit on unexpected errors. This configuration can be used in the application to improve the debugging experience.<n> --settings-file=%<filename><n> Provide application configuration via a settings file. This option can occur several times to configure more than one settings file. Supported file settings formats are INI and JSON.<n> --enable-structured-logging<n> Enable structured logging. When enabled the log will be emitted in JSON format.<n><t><t>--dry-run<n><t><t><t>Perform a dry run of the application. All the configuration will be loaded (and validated), but the application will not start.<n> --enable-tcp-command-server=%<listeningPort><n> Enable a TCP command server. This can be used to send commands controlling the application using a TCP port.<n>' ] ifFalse: [ - 'NAME<n> launchpad-start - Start the selected application<n>SYNOPSYS<n> launchpad start [--help|-h] [--debug-mode] [--settings-file=%<filename>] [--enable-structured-logging] %<app> [%<parameters>]<n>DESCRIPTION<n> Start the application selected via %<app>.<n><n><t><t>Application configuration is made by the command-line via %<parameters>, using environment variables or settings files.<n><n><t><t>Execute launchpad explain %<app> to get a list of valid configuration parameters.<n>OPTIONS<n> -h, --help<n> Print this help message and exit.<n> --debug-mode<n> Enable the debugging mode. The image will not quit on unexpected errors. This configuration can be used in the application to improve the debugging experience.<n> --settings-file=%<filename><n> Provide application configuration via a settings file. This option can occur several times to configure more than one settings file. Supported file settings formats are INI and JSON.<n> --enable-structured-logging<n> Enable structured logging. When enabled the log will be emitted in JSON format.<n>' ]) + 'NAME<n> launchpad-start - Start the selected application<n>SYNOPSYS<n> launchpad start [--help|-h] [--debug-mode] [--settings-file=%<filename>] [--enable-structured-logging] [--dry-run] %<app> [%<parameters>]<n>DESCRIPTION<n> Start the application selected via %<app>.<n><n><t><t>Application configuration is made by the command-line via %<parameters>, using environment variables or settings files.<n><n><t><t>Execute launchpad explain %<app> to get a list of valid configuration parameters.<n>OPTIONS<n> -h, --help<n> Print this help message and exit.<n> --debug-mode<n> Enable the debugging mode. The image will not quit on unexpected errors. This configuration can be used in the application to improve the debugging experience.<n> --settings-file=%<filename><n> Provide application configuration via a settings file. This option can occur several times to configure more than one settings file. Supported file settings formats are INI and JSON.<n> --enable-structured-logging<n> Enable structured logging. When enabled the log will be emitted in JSON format.<n><t><t>--dry-run<n><t><t><t>Perform a dry run of the application. All the configuration will be loaded (and validated), but the application will not start.<n>' ]) expandMacros ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> expectedVerboseListOutput [ ^ String streamContents: [ :stream | @@ -115,7 +116,7 @@ LaunchpadRootCommandTest >> expectedVerboseListOutput [ ] ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> handle: arguments [ ^ String streamContents: [ :stream | @@ -129,7 +130,7 @@ LaunchpadRootCommandTest >> handle: arguments [ ] ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> handle: arguments onExitDo: aBlock [ ^ String streamContents: [ :stream | @@ -146,7 +147,7 @@ LaunchpadRootCommandTest >> handle: arguments onExitDo: aBlock [ ] ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> set: environmentVariableName to: value during: aBlock [ LanguagePlatform current os @@ -157,14 +158,14 @@ LaunchpadRootCommandTest >> set: environmentVariableName to: value during: aBloc environmentVariableName ] ] -{ #category : #running } +{ #category : 'running' } LaunchpadRootCommandTest >> setUp [ super setUp. command := LaunchpadRootCommand new ] -{ #category : #tests } +{ #category : 'tests' } LaunchpadRootCommandTest >> testAccessing [ | options subcommands | @@ -194,7 +195,7 @@ LaunchpadRootCommandTest >> testAccessing [ assert: subcommands last name equals: 'explain' ] -{ #category : #'tests - handling explain subcommand' } +{ #category : 'tests - handling explain subcommand' } LaunchpadRootCommandTest >> testHandlingExplainBrokenApplication [ | output | @@ -208,7 +209,7 @@ LaunchpadRootCommandTest >> testHandlingExplainBrokenApplication [ assertThereAreNoLogRecords ] -{ #category : #'tests - handling explain subcommand' } +{ #category : 'tests - handling explain subcommand' } LaunchpadRootCommandTest >> testHandlingExplainGreeterApplication [ | output | @@ -222,7 +223,7 @@ LaunchpadRootCommandTest >> testHandlingExplainGreeterApplication [ assertThereAreNoLogRecords ] -{ #category : #'tests - handling explain subcommand' } +{ #category : 'tests - handling explain subcommand' } LaunchpadRootCommandTest >> testHandlingExplainSubcommandHelp [ | output | @@ -235,7 +236,7 @@ LaunchpadRootCommandTest >> testHandlingExplainSubcommandHelp [ assertThereAreNoLogRecords ] -{ #category : #'tests - handling explain subcommand' } +{ #category : 'tests - handling explain subcommand' } LaunchpadRootCommandTest >> testHandlingExplainSubcommandShortHelp [ | output | @@ -248,7 +249,7 @@ LaunchpadRootCommandTest >> testHandlingExplainSubcommandShortHelp [ assertThereAreNoLogRecords ] -{ #category : #'tests - handling main command' } +{ #category : 'tests - handling main command' } LaunchpadRootCommandTest >> testHandlingHelpOption [ | output | @@ -260,7 +261,7 @@ LaunchpadRootCommandTest >> testHandlingHelpOption [ assertThereAreNoLogRecords ] -{ #category : #'tests - handling explain subcommand' } +{ #category : 'tests - handling explain subcommand' } LaunchpadRootCommandTest >> testHandlingInvalidExplainSubcommandApp [ | output | @@ -273,7 +274,7 @@ LaunchpadRootCommandTest >> testHandlingInvalidExplainSubcommandApp [ assertLogRecordsMatch: #( '[ERROR] explain unknown application: wrong' ) ] -{ #category : #'tests - handling explain subcommand' } +{ #category : 'tests - handling explain subcommand' } LaunchpadRootCommandTest >> testHandlingInvalidExplainSubcommandOption [ | output | @@ -286,7 +287,7 @@ LaunchpadRootCommandTest >> testHandlingInvalidExplainSubcommandOption [ assertLogRecordsMatch: #( '[ERROR] explain unknown option: --wrong' ) ] -{ #category : #'tests - handling list subcommand' } +{ #category : 'tests - handling list subcommand' } LaunchpadRootCommandTest >> testHandlingInvalidListSubcommandOption [ | output | @@ -299,7 +300,7 @@ LaunchpadRootCommandTest >> testHandlingInvalidListSubcommandOption [ assertLogRecordsMatch: #( '[ERROR] list unknown option: --wrong' ) ] -{ #category : #'tests - handling main command' } +{ #category : 'tests - handling main command' } LaunchpadRootCommandTest >> testHandlingInvalidOption [ | output | @@ -311,7 +312,7 @@ LaunchpadRootCommandTest >> testHandlingInvalidOption [ assertLogRecordsMatch: #( '[ERROR] launchpad unknown option: --wrong' ) ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingInvalidStartSubcommandApp [ | output | @@ -325,7 +326,7 @@ LaunchpadRootCommandTest >> testHandlingInvalidStartSubcommandApp [ assertLogRecordsMatch: #( '[ERROR] start unknown application: wrong' ) ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingInvalidStartSubcommandOption [ | output | @@ -339,7 +340,7 @@ LaunchpadRootCommandTest >> testHandlingInvalidStartSubcommandOption [ assertLogRecordsMatch: #( '[ERROR] start unknown option: --wrong' ) ] -{ #category : #tests } +{ #category : 'tests' } LaunchpadRootCommandTest >> testHandlingInvalidSubcommand [ | output | @@ -351,7 +352,7 @@ LaunchpadRootCommandTest >> testHandlingInvalidSubcommand [ assertLogRecordsMatch: #( '[ERROR] launchpad unknown command: wrong' ) ] -{ #category : #'tests - handling list subcommand' } +{ #category : 'tests - handling list subcommand' } LaunchpadRootCommandTest >> testHandlingListSubcommand [ | output | @@ -368,7 +369,7 @@ LaunchpadRootCommandTest >> testHandlingListSubcommand [ assertThereAreNoLogRecords ] -{ #category : #'tests - handling list subcommand' } +{ #category : 'tests - handling list subcommand' } LaunchpadRootCommandTest >> testHandlingListSubcommandHelp [ | output | @@ -382,7 +383,7 @@ LaunchpadRootCommandTest >> testHandlingListSubcommandHelp [ assertThereAreNoLogRecords ] -{ #category : #'tests - handling list subcommand' } +{ #category : 'tests - handling list subcommand' } LaunchpadRootCommandTest >> testHandlingListSubcommandShortHelp [ | output | @@ -396,7 +397,7 @@ LaunchpadRootCommandTest >> testHandlingListSubcommandShortHelp [ assertThereAreNoLogRecords ] -{ #category : #'tests - handling list subcommand' } +{ #category : 'tests - handling list subcommand' } LaunchpadRootCommandTest >> testHandlingListSubcommandShortVerboseMode [ | output | @@ -410,7 +411,7 @@ LaunchpadRootCommandTest >> testHandlingListSubcommandShortVerboseMode [ assertThereAreNoLogRecords ] -{ #category : #'tests - handling list subcommand' } +{ #category : 'tests - handling list subcommand' } LaunchpadRootCommandTest >> testHandlingListSubcommandVerboseMode [ | output | @@ -424,7 +425,7 @@ LaunchpadRootCommandTest >> testHandlingListSubcommandVerboseMode [ assertThereAreNoLogRecords ] -{ #category : #tests } +{ #category : 'tests' } LaunchpadRootCommandTest >> testHandlingMissingSubcommandAndOption [ | output | @@ -436,7 +437,7 @@ LaunchpadRootCommandTest >> testHandlingMissingSubcommandAndOption [ assertLogRecordsMatch: #( '[ERROR] Missing command or option.' ) ] -{ #category : #'tests - handling main command' } +{ #category : 'tests - handling main command' } LaunchpadRootCommandTest >> testHandlingShortHelpOption [ | output | @@ -448,7 +449,7 @@ LaunchpadRootCommandTest >> testHandlingShortHelpOption [ assertThereAreNoLogRecords ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStartBrokenApplication [ | output | @@ -465,7 +466,7 @@ LaunchpadRootCommandTest >> testHandlingStartBrokenApplication [ '[INFO] Obtaining configuration... [DONE]' ) ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStartBrokenApplicationInDebugMode [ | output | @@ -481,7 +482,7 @@ LaunchpadRootCommandTest >> testHandlingStartBrokenApplicationInDebugMode [ '[ERROR] Exit application' ) ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStartBrokenApplicationRaisingUnexpectedError [ | output | @@ -499,7 +500,7 @@ LaunchpadRootCommandTest >> testHandlingStartBrokenApplicationRaisingUnexpectedE '[ERROR] Unexpected startup error: "Doh!"' ) ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStartBrokenApplicationRaisingUnexpectedErrorInDebugMode [ self @@ -514,7 +515,7 @@ LaunchpadRootCommandTest >> testHandlingStartBrokenApplicationRaisingUnexpectedE '[INFO] Obtaining configuration... [DONE]' ) ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStartGreeterApplication [ | output | @@ -538,7 +539,7 @@ LaunchpadRootCommandTest >> testHandlingStartGreeterApplication [ '[INFO] Obtaining configuration... [DONE]' ) ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationEnablingStructuredLogging [ | output | @@ -563,7 +564,7 @@ LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationEnablingStructure '[INFO] Exit application' ) ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationInDebugMode [ | output | @@ -587,7 +588,7 @@ LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationInDebugMode [ '[INFO] Exit application' ) ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationLoadingSettingsFile [ | fileName | @@ -621,7 +622,7 @@ LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationLoadingSettingsFi ] ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationLoadingSeveralSettingsFile [ | jsonFileName | @@ -659,7 +660,7 @@ LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationLoadingSeveralSet ] ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationMissingMandatoryParameter [ | output | @@ -681,7 +682,7 @@ LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationMissingMandatoryP '[ERROR] Obtaining configuration... [FAILED]' ) ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationMissingMandatoryParameterInDebugMode [ self @@ -705,7 +706,7 @@ LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationMissingMandatoryP '[ERROR] "Name" parameter not provided. You must provide one.' ) ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationWithAllParameters [ | output | @@ -729,7 +730,7 @@ LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationWithAllParameters '[INFO] Obtaining configuration... [DONE]' ) ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationWithMixedConfiguration [ | fileName | @@ -764,7 +765,7 @@ LaunchpadRootCommandTest >> testHandlingStartGreeterApplicationWithMixedConfigur ] ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStartSubcommandHelp [ | output | @@ -778,7 +779,7 @@ LaunchpadRootCommandTest >> testHandlingStartSubcommandHelp [ assertThereAreNoLogRecords ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStartSubcommandShortHelp [ | output | @@ -792,7 +793,7 @@ LaunchpadRootCommandTest >> testHandlingStartSubcommandShortHelp [ assertThereAreNoLogRecords ] -{ #category : #'tests - handling start subcommand' } +{ #category : 'tests - handling start subcommand' } LaunchpadRootCommandTest >> testHandlingStopBrokenApplicationWhileRunning [ | semaphore | @@ -819,7 +820,7 @@ LaunchpadRootCommandTest >> testHandlingStopBrokenApplicationWhileRunning [ '[INFO] Obtaining configuration... [DONE]' ) ] -{ #category : #'tests - handling main command' } +{ #category : 'tests - handling main command' } LaunchpadRootCommandTest >> testHandlingVersionOption [ | output | @@ -833,7 +834,7 @@ LaunchpadRootCommandTest >> testHandlingVersionOption [ assertThereAreNoLogRecords ] -{ #category : #tests } +{ #category : 'tests' } LaunchpadRootCommandTest >> testPrintHelpOn [ | help | @@ -861,7 +862,7 @@ COMMANDS ' ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommandTest >> use: version asVersionDuring: aBlock [ | currentVersion | diff --git a/source/Launchpad-Commands-Tests/NullCommandServerTest.class.st b/source/Launchpad-Commands-Tests/NullCommandServerTest.class.st index 418eb9a..fbe985e 100644 --- a/source/Launchpad-Commands-Tests/NullCommandServerTest.class.st +++ b/source/Launchpad-Commands-Tests/NullCommandServerTest.class.st @@ -2,12 +2,13 @@ A NullCommandServerTest is a test class for testing the behavior of NullCommandServer " Class { - #name : #NullCommandServerTest, - #superclass : #TestCase, - #category : #'Launchpad-Commands-Tests' + #name : 'NullCommandServerTest', + #superclass : 'TestCase', + #category : 'Launchpad-Commands-Tests', + #package : 'Launchpad-Commands-Tests' } -{ #category : #tests } +{ #category : 'tests' } NullCommandServerTest >> testStop [ NullCommandServer new diff --git a/source/Launchpad-Commands-Tests/package.st b/source/Launchpad-Commands-Tests/package.st index f4afafb..cc6c03d 100644 --- a/source/Launchpad-Commands-Tests/package.st +++ b/source/Launchpad-Commands-Tests/package.st @@ -1 +1 @@ -Package { #name : #'Launchpad-Commands-Tests' } +Package { #name : 'Launchpad-Commands-Tests' } diff --git a/source/Launchpad-Commands/CommandServer.class.st b/source/Launchpad-Commands/CommandServer.class.st index 49c5095..8a12288 100644 --- a/source/Launchpad-Commands/CommandServer.class.st +++ b/source/Launchpad-Commands/CommandServer.class.st @@ -1,16 +1,17 @@ Class { - #name : #CommandServer, - #superclass : #Object, - #category : #'Launchpad-Commands' + #name : 'CommandServer', + #superclass : 'Object', + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #controlling } +{ #category : 'controlling' } CommandServer >> start [ self subclassResponsibility ] -{ #category : #controlling } +{ #category : 'controlling' } CommandServer >> stop [ self subclassResponsibility diff --git a/source/Launchpad-Commands/LaunchpadApplicationCommand.class.st b/source/Launchpad-Commands/LaunchpadApplicationCommand.class.st index 1ac6864..f2f81df 100644 --- a/source/Launchpad-Commands/LaunchpadApplicationCommand.class.st +++ b/source/Launchpad-Commands/LaunchpadApplicationCommand.class.st @@ -1,36 +1,37 @@ Class { - #name : #LaunchpadApplicationCommand, - #superclass : #LaunchpadCommand, - #category : #'Launchpad-Commands' + #name : 'LaunchpadApplicationCommand', + #superclass : 'LaunchpadCommand', + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #testing } +{ #category : 'testing' } LaunchpadApplicationCommand class >> isAbstract [ <ignoreForCoverage> ^ self = LaunchpadApplicationCommand ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadApplicationCommand >> fullCommandName [ ^ 'launchpad <1s>' expandMacrosWith: self name ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadApplicationCommand >> fullName [ ^ 'launchpad-<1s>' expandMacrosWith: self name ] -{ #category : #private } +{ #category : 'private' } LaunchpadApplicationCommand >> nextCommandLineArgumentIn: context [ ^ context nextCommandLineArgumentIfNone: [ context emitErrorAndExit: 'Missing application name or option.' ] ] -{ #category : #private } +{ #category : 'private' } LaunchpadApplicationCommand >> unknownOptionOrApplicationMessageFor: argument [ ^ '<1s> unknown <2?option:application>: <3s>' expandMacrosWith: self name diff --git a/source/Launchpad-Commands/LaunchpadApplicationContext.class.st b/source/Launchpad-Commands/LaunchpadApplicationContext.class.st new file mode 100644 index 0000000..92239bc --- /dev/null +++ b/source/Launchpad-Commands/LaunchpadApplicationContext.class.st @@ -0,0 +1,101 @@ +Class { + #name : 'LaunchpadApplicationContext', + #superclass : 'Object', + #instVars : [ + 'commandLine', + 'output' + ], + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' +} + +{ #category : 'instance creation' } +LaunchpadApplicationContext class >> handling: aCommandLine [ + + ^ self handling: aCommandLine writingTo: String new writeStream +] + +{ #category : 'instance creation' } +LaunchpadApplicationContext class >> handling: aCommandLine writingTo: outputStream [ + + ^ self new initializeHandling: aCommandLine writingTo: outputStream +] + +{ #category : 'testing' } +LaunchpadApplicationContext class >> isAbstract [ + + <ignoreForCoverage> + ^ self = LaunchpadApplicationContext +] + +{ #category : 'converting' } +LaunchpadApplicationContext >> asDryRunContext [ + + ^ self subclassResponsibility +] + +{ #category : 'accessing' } +LaunchpadApplicationContext >> commandLine [ + + ^ commandLine +] + +{ #category : 'accessing' } +LaunchpadApplicationContext >> configurationProviderChainedWith: aConfigurationProvider [ + + ^ ConfigurationFromCommandLineProvider over: commandLine chainedWith: aConfigurationProvider +] + +{ #category : 'utilities' } +LaunchpadApplicationContext >> emitErrorAndExit: message [ + + LogRecord emitError: message. + self exitFailure +] + +{ #category : 'utilities' } +LaunchpadApplicationContext >> exitFailure [ + + Exit signalFailure +] + +{ #category : 'utilities' } +LaunchpadApplicationContext >> exitSuccess [ + + Exit signalSuccess +] + +{ #category : 'initialize' } +LaunchpadApplicationContext >> initializeHandling: aCommandLine writingTo: outputStream [ + + commandLine := aCommandLine. + output := ZnNewLineWriterStream on: outputStream +] + +{ #category : 'accessing' } +LaunchpadApplicationContext >> nextCommandLineArgumentIfNone: aFailBlock [ + + commandLine withFirstArgument: [ :argument | + commandLine := commandLine copySubcommand. + ^ argument + ]. + ^ aFailBlock value +] + +{ #category : 'enumerating' } +LaunchpadApplicationContext >> outputStreamDo: aBlock [ + + aBlock value: output +] + +{ #category : 'running' } +LaunchpadApplicationContext >> run: startupBlock [ + + ^ self subclassResponsibility +] + +{ #category : 'configuration' } +LaunchpadApplicationContext >> usePlatformLineEnding [ + + output forPlatformLineEnding +] diff --git a/source/Launchpad-Commands/LaunchpadApplicationDryRunContext.class.st b/source/Launchpad-Commands/LaunchpadApplicationDryRunContext.class.st new file mode 100644 index 0000000..5f7e3e6 --- /dev/null +++ b/source/Launchpad-Commands/LaunchpadApplicationDryRunContext.class.st @@ -0,0 +1,18 @@ +Class { + #name : 'LaunchpadApplicationDryRunContext', + #superclass : 'LaunchpadApplicationContext', + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' +} + +{ #category : 'converting' } +LaunchpadApplicationDryRunContext >> asDryRunContext [ + + ^ self +] + +{ #category : 'running' } +LaunchpadApplicationDryRunContext >> run: startupBlock [ + + self exitSuccess +] diff --git a/source/Launchpad-Commands/LaunchpadApplicationStartingContext.class.st b/source/Launchpad-Commands/LaunchpadApplicationStartingContext.class.st new file mode 100644 index 0000000..320a1a7 --- /dev/null +++ b/source/Launchpad-Commands/LaunchpadApplicationStartingContext.class.st @@ -0,0 +1,18 @@ +Class { + #name : 'LaunchpadApplicationStartingContext', + #superclass : 'LaunchpadApplicationContext', + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' +} + +{ #category : 'converting' } +LaunchpadApplicationStartingContext >> asDryRunContext [ + + ^ LaunchpadApplicationDryRunContext handling: commandLine writingTo: output +] + +{ #category : 'running' } +LaunchpadApplicationStartingContext >> run: startUpBlock [ + + startUpBlock value +] diff --git a/source/Launchpad-Commands/LaunchpadCommand.class.st b/source/Launchpad-Commands/LaunchpadCommand.class.st index 9992f97..a6634b1 100644 --- a/source/Launchpad-Commands/LaunchpadCommand.class.st +++ b/source/Launchpad-Commands/LaunchpadCommand.class.st @@ -1,47 +1,48 @@ Class { - #name : #LaunchpadCommand, - #superclass : #Object, - #category : #'Launchpad-Commands' + #name : 'LaunchpadCommand', + #superclass : 'Object', + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #testing } +{ #category : 'testing' } LaunchpadCommand class >> isAbstract [ <ignoreForCoverage> ^ self = LaunchpadCommand ] -{ #category : #testing } +{ #category : 'testing' } LaunchpadCommand >> canHandle: argument [ ^ argument = self name ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadCommand >> description [ ^ self subclassResponsibility ] -{ #category : #evaluating } +{ #category : 'evaluating' } LaunchpadCommand >> evaluateWithin: context [ self subclassResponsibility ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadCommand >> fullCommandName [ ^ self subclassResponsibility ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadCommand >> fullName [ ^ self subclassResponsibility ] -{ #category : #private } +{ #category : 'private' } LaunchpadCommand >> handleOptionsAndWithNextArgumentIn: context do: aFailBlock [ | nextArgument | @@ -50,32 +51,30 @@ LaunchpadCommand >> handleOptionsAndWithNextArgumentIn: context do: aFailBlock [ ^ self options detect: [ :option | option canHandle: nextArgument ] - ifFound: [ :option | - option evaluateWithin: context handling: nextArgument. - self evaluateWithin: context - ] + ifFound: [ :option | + self evaluateWithin: ( option evaluateWithin: context handling: nextArgument ) ] ifNone: [ aFailBlock cull: nextArgument ] ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadCommand >> name [ ^ self subclassResponsibility ] -{ #category : #private } +{ #category : 'private' } LaunchpadCommand >> nextCommandLineArgumentIn: context [ ^ self subclassResponsibility ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadCommand >> options [ ^ self subclassResponsibility ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadCommand >> printCommandArgumentsOn: stream [ self options do: [ :option | @@ -89,7 +88,7 @@ LaunchpadCommand >> printCommandArgumentsOn: stream [ ] ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadCommand >> printHelpOn: stream [ ( LaunchpadHelpPrinter on: stream ) @@ -100,13 +99,13 @@ LaunchpadCommand >> printHelpOn: stream [ commandsSectionDescribing: self subcommands ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadCommand >> subcommands [ ^ self subclassResponsibility ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadCommand >> summary [ ^ self subclassResponsibility diff --git a/source/Launchpad-Commands/LaunchpadCommandLineHandler.class.st b/source/Launchpad-Commands/LaunchpadCommandLineHandler.class.st index 1a10314..d15c168 100644 --- a/source/Launchpad-Commands/LaunchpadCommandLineHandler.class.st +++ b/source/Launchpad-Commands/LaunchpadCommandLineHandler.class.st @@ -1,25 +1,56 @@ Class { - #name : #LaunchpadCommandLineHandler, - #superclass : #CommandLineHandler, - #category : #'Launchpad-Commands' + #name : 'LaunchpadCommandLineHandler', + #superclass : 'CommandLineHandler', + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #accessing } +{ #category : 'instance creation' } +LaunchpadCommandLineHandler class >> activateInContext: aProcessingContext [ + + ^ self new + commandLine: aProcessingContext commandLine; + activateWithContext: aProcessingContext +] + +{ #category : 'instance creation' } +LaunchpadCommandLineHandler class >> activateWith: aCommandLine [ + + ^ self activateInContext: (self defaultContextForCommandLine: + (self prepareSubcommand: aCommandLine)) +] + +{ #category : 'accessing' } LaunchpadCommandLineHandler class >> commandName [ ^ LaunchpadRootCommand commandName ] -{ #category : #accessing } +{ #category : 'instance creation' } +LaunchpadCommandLineHandler class >> defaultContextForCommandLine: commandLine [ + + ^ (LaunchpadApplicationStartingContext + handling: commandLine + writingTo: Stdio stdout) + usePlatformLineEnding; + yourself +] + +{ #category : 'accessing' } LaunchpadCommandLineHandler class >> description [ ^ LaunchpadRootCommand summary ] -{ #category : #activation } +{ #category : 'activation' } LaunchpadCommandLineHandler >> activate [ - | context | + <ignoreForCoverage> + self shouldNotImplement +] + +{ #category : 'activation' } +LaunchpadCommandLineHandler >> activateWithContext: context [ Processor activeProcess name: 'Launchpad CLI'. @@ -28,7 +59,5 @@ LaunchpadCommandLineHandler >> activate [ StandardStreamLogger onStandardError startFor: ( LogRecord where: [ :record | record isInformational not ] ). - context := LaunchpadCommandLineProcessingContext handling: commandLine writingTo: self stdout. - context usePlatformLineEnding. - LaunchpadRootCommand new evaluateWithin: context + ^ LaunchpadRootCommand new evaluateWithin: context ] diff --git a/source/Launchpad-Commands/LaunchpadCommandLineProcessingContext.class.st b/source/Launchpad-Commands/LaunchpadCommandLineProcessingContext.class.st deleted file mode 100644 index 1960af9..0000000 --- a/source/Launchpad-Commands/LaunchpadCommandLineProcessingContext.class.st +++ /dev/null @@ -1,69 +0,0 @@ -Class { - #name : #LaunchpadCommandLineProcessingContext, - #superclass : #Object, - #instVars : [ - 'commandLine', - 'output' - ], - #category : #'Launchpad-Commands' -} - -{ #category : #'instance creation' } -LaunchpadCommandLineProcessingContext class >> handling: aCommandLine writingTo: outputStream [ - - ^ self new initializeHandling: aCommandLine writingTo: outputStream -] - -{ #category : #accessing } -LaunchpadCommandLineProcessingContext >> configurationProviderChainedWith: aConfigurationProvider [ - - ^ ConfigurationFromCommandLineProvider over: commandLine chainedWith: aConfigurationProvider -] - -{ #category : #utilities } -LaunchpadCommandLineProcessingContext >> emitErrorAndExit: message [ - - LogRecord emitError: message. - self exitFailure -] - -{ #category : #utilities } -LaunchpadCommandLineProcessingContext >> exitFailure [ - - Exit signalFailure -] - -{ #category : #utilities } -LaunchpadCommandLineProcessingContext >> exitSuccess [ - - Exit signalSuccess -] - -{ #category : #initialize } -LaunchpadCommandLineProcessingContext >> initializeHandling: aCommandLine writingTo: outputStream [ - - commandLine := aCommandLine. - output := ZnNewLineWriterStream on: outputStream -] - -{ #category : #accessing } -LaunchpadCommandLineProcessingContext >> nextCommandLineArgumentIfNone: aFailBlock [ - - commandLine withFirstArgument: [ :argument | - commandLine := commandLine copySubcommand. - ^ argument - ]. - ^ aFailBlock value -] - -{ #category : #enumerating } -LaunchpadCommandLineProcessingContext >> outputStreamDo: aBlock [ - - aBlock value: output -] - -{ #category : #configuration } -LaunchpadCommandLineProcessingContext >> usePlatformLineEnding [ - - output forPlatformLineEnding -] diff --git a/source/Launchpad-Commands/LaunchpadDebugModeOption.class.st b/source/Launchpad-Commands/LaunchpadDebugModeOption.class.st index 202c6eb..3580cbc 100644 --- a/source/Launchpad-Commands/LaunchpadDebugModeOption.class.st +++ b/source/Launchpad-Commands/LaunchpadDebugModeOption.class.st @@ -1,37 +1,39 @@ Class { - #name : #LaunchpadDebugModeOption, - #superclass : #LaunchpadOption, + #name : 'LaunchpadDebugModeOption', + #superclass : 'LaunchpadOption', #instVars : [ 'command' ], - #category : #'Launchpad-Commands' + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } LaunchpadDebugModeOption class >> for: aCommand [ ^ self new initializeFor: aCommand ] -{ #category : #evaluating } +{ #category : 'evaluating' } LaunchpadDebugModeOption >> evaluateWithin: context handling: argument [ - command setDebugMode + command setDebugMode. + ^ context ] -{ #category : #initialization } +{ #category : 'initialization' } LaunchpadDebugModeOption >> initializeFor: aCommand [ command := aCommand ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadDebugModeOption >> name [ ^ 'debug-mode' ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadDebugModeOption >> summary [ ^ 'Enable the debugging mode. The image will not quit on unexpected errors. This configuration can be used in the application to improve the debugging experience.' diff --git a/source/Launchpad-Commands/LaunchpadDryRunOption.class.st b/source/Launchpad-Commands/LaunchpadDryRunOption.class.st new file mode 100644 index 0000000..77e5fa0 --- /dev/null +++ b/source/Launchpad-Commands/LaunchpadDryRunOption.class.st @@ -0,0 +1,24 @@ +Class { + #name : 'LaunchpadDryRunOption', + #superclass : 'LaunchpadOption', + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' +} + +{ #category : 'evaluating' } +LaunchpadDryRunOption >> evaluateWithin: context handling: argument [ + + ^ context asDryRunContext +] + +{ #category : 'accessing' } +LaunchpadDryRunOption >> name [ + + ^ 'dry-run' +] + +{ #category : 'accessing' } +LaunchpadDryRunOption >> summary [ + + ^ 'Perform a dry run of the application. All the configuration will be loaded (and validated), but the application will not start.' +] diff --git a/source/Launchpad-Commands/LaunchpadExplainApplicationCommand.class.st b/source/Launchpad-Commands/LaunchpadExplainApplicationCommand.class.st index e16e3dd..ad7958f 100644 --- a/source/Launchpad-Commands/LaunchpadExplainApplicationCommand.class.st +++ b/source/Launchpad-Commands/LaunchpadExplainApplicationCommand.class.st @@ -1,19 +1,20 @@ Class { - #name : #LaunchpadExplainApplicationCommand, - #superclass : #LaunchpadApplicationCommand, + #name : 'LaunchpadExplainApplicationCommand', + #superclass : 'LaunchpadApplicationCommand', #instVars : [ 'options' ], - #category : #'Launchpad-Commands' + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadExplainApplicationCommand >> description [ ^ 'Give details about the application selected via <app> including its configuration options.' ] -{ #category : #evaluating } +{ #category : 'evaluating' } LaunchpadExplainApplicationCommand >> evaluateWithin: context [ self handleOptionsAndWithNextArgumentIn: context do: [ :argument | @@ -23,33 +24,33 @@ LaunchpadExplainApplicationCommand >> evaluateWithin: context [ ] ] -{ #category : #private } +{ #category : 'private' } LaunchpadExplainApplicationCommand >> explain: application within: context [ context outputStreamDo: [ :stream | application printHelpOn: stream ]. context exitSuccess ] -{ #category : #initialization } +{ #category : 'initialization' } LaunchpadExplainApplicationCommand >> initialize [ super initialize. options := Array with: ( LaunchpadHelpOption for: self ) ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadExplainApplicationCommand >> name [ ^ 'explain' ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadExplainApplicationCommand >> options [ ^ options ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadExplainApplicationCommand >> printCommandArgumentsOn: stream [ super printCommandArgumentsOn: stream. @@ -58,13 +59,13 @@ LaunchpadExplainApplicationCommand >> printCommandArgumentsOn: stream [ nextPutAll: '<app>' ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadExplainApplicationCommand >> subcommands [ ^ #() ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadExplainApplicationCommand >> summary [ ^ 'Give details about the selected application' diff --git a/source/Launchpad-Commands/LaunchpadHelpOption.class.st b/source/Launchpad-Commands/LaunchpadHelpOption.class.st index 02924ba..3695dd3 100644 --- a/source/Launchpad-Commands/LaunchpadHelpOption.class.st +++ b/source/Launchpad-Commands/LaunchpadHelpOption.class.st @@ -1,45 +1,46 @@ Class { - #name : #LaunchpadHelpOption, - #superclass : #LaunchpadShortOption, + #name : 'LaunchpadHelpOption', + #superclass : 'LaunchpadShortOption', #instVars : [ 'command' ], - #category : #'Launchpad-Commands' + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } LaunchpadHelpOption class >> for: aCommand [ ^ self new initializeFor: aCommand ] -{ #category : #evaluating } +{ #category : 'evaluating' } LaunchpadHelpOption >> evaluateWithin: context handling: argument [ - context outputStreamDo: [ :stream | - command printHelpOn: stream ]. - context exitSuccess + context outputStreamDo: [ :stream | command printHelpOn: stream ]. + context exitSuccess. + ^ context ] -{ #category : #initialization } +{ #category : 'initialization' } LaunchpadHelpOption >> initializeFor: aCommand [ command := aCommand ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadHelpOption >> name [ ^ 'help' ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadHelpOption >> shortName [ ^ 'h' ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadHelpOption >> summary [ ^ 'Print this help message and exit.' diff --git a/source/Launchpad-Commands/LaunchpadListApplicationsCommand.class.st b/source/Launchpad-Commands/LaunchpadListApplicationsCommand.class.st index dab4558..f5149f4 100644 --- a/source/Launchpad-Commands/LaunchpadListApplicationsCommand.class.st +++ b/source/Launchpad-Commands/LaunchpadListApplicationsCommand.class.st @@ -1,19 +1,20 @@ Class { - #name : #LaunchpadListApplicationsCommand, - #superclass : #LaunchpadApplicationCommand, + #name : 'LaunchpadListApplicationsCommand', + #superclass : 'LaunchpadApplicationCommand', #instVars : [ 'options' ], - #category : #'Launchpad-Commands' + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadListApplicationsCommand >> description [ ^ 'Lists the available applications contained in the image.' ] -{ #category : #private } +{ #category : 'private' } LaunchpadListApplicationsCommand >> evaluateInVerboseModeWithin: context [ context outputStreamDo: [ :stream | @@ -32,7 +33,7 @@ LaunchpadListApplicationsCommand >> evaluateInVerboseModeWithin: context [ context exitSuccess ] -{ #category : #evaluating } +{ #category : 'evaluating' } LaunchpadListApplicationsCommand >> evaluateWithin: context [ self handleOptionsAndWithNextArgumentIn: context do: [ :argument | @@ -40,14 +41,14 @@ LaunchpadListApplicationsCommand >> evaluateWithin: context [ ( '<1s> unknown option: <2s>' expandMacrosWith: self name with: argument ) ] ] -{ #category : #initialization } +{ #category : 'initialization' } LaunchpadListApplicationsCommand >> initialize [ super initialize. options := Array with: ( LaunchpadVerboseOption for: self ) with: ( LaunchpadHelpOption for: self ) ] -{ #category : #private } +{ #category : 'private' } LaunchpadListApplicationsCommand >> listAvailableApplicationsWithin: context [ context outputStreamDo: [ :stream | @@ -59,31 +60,31 @@ LaunchpadListApplicationsCommand >> listAvailableApplicationsWithin: context [ ^ context exitSuccess ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadListApplicationsCommand >> name [ ^ 'list' ] -{ #category : #private } +{ #category : 'private' } LaunchpadListApplicationsCommand >> nextCommandLineArgumentIn: context [ ^ context nextCommandLineArgumentIfNone: [ self listAvailableApplicationsWithin: context ] ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadListApplicationsCommand >> options [ ^ options ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadListApplicationsCommand >> subcommands [ ^ #() ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadListApplicationsCommand >> summary [ ^ 'List available applications' diff --git a/source/Launchpad-Commands/LaunchpadOption.class.st b/source/Launchpad-Commands/LaunchpadOption.class.st index 04940d4..ae6e99b 100644 --- a/source/Launchpad-Commands/LaunchpadOption.class.st +++ b/source/Launchpad-Commands/LaunchpadOption.class.st @@ -1,10 +1,11 @@ Class { - #name : #LaunchpadOption, - #superclass : #Object, - #category : #'Launchpad-Commands' + #name : 'LaunchpadOption', + #superclass : 'Object', + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #querying } +{ #category : 'querying' } LaunchpadOption class >> additionalStartingOptionsFor: startApplicationCommand [ ^ self allLeafSubclasses @@ -13,38 +14,38 @@ LaunchpadOption class >> additionalStartingOptionsFor: startApplicationCommand [ optionClass for: startApplicationCommand ] ] -{ #category : #testing } +{ #category : 'testing' } LaunchpadOption class >> isAbstract [ <ignoreForCoverage> ^ self = LaunchpadOption ] -{ #category : #testing } +{ #category : 'testing' } LaunchpadOption class >> isExtendedStartingOption [ ^ false ] -{ #category : #testing } +{ #category : 'testing' } LaunchpadOption >> canHandle: argument [ ^ argument = ( '--' , self name ) ] -{ #category : #evaluating } +{ #category : 'evaluating' } LaunchpadOption >> evaluateWithin: context handling: argument [ self subclassResponsibility ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadOption >> name [ ^ self subclassResponsibility ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadOption >> printAsCommandLineArgumentTemplateOn: stream [ stream @@ -54,7 +55,7 @@ LaunchpadOption >> printAsCommandLineArgumentTemplateOn: stream [ stream nextPut: $] ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadOption >> printHelpOn: stream [ stream @@ -62,13 +63,13 @@ LaunchpadOption >> printHelpOn: stream [ nextPutAll: self name ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadOption >> printSuffixOn: stream [ ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadOption >> summary [ ^ self subclassResponsibility diff --git a/source/Launchpad-Commands/LaunchpadRootCommand.class.st b/source/Launchpad-Commands/LaunchpadRootCommand.class.st index ca8072b..a0fc4ca 100644 --- a/source/Launchpad-Commands/LaunchpadRootCommand.class.st +++ b/source/Launchpad-Commands/LaunchpadRootCommand.class.st @@ -1,6 +1,6 @@ Class { - #name : #LaunchpadRootCommand, - #superclass : #LaunchpadCommand, + #name : 'LaunchpadRootCommand', + #superclass : 'LaunchpadCommand', #instVars : [ 'options', 'subcommands' @@ -8,69 +8,71 @@ Class { #classVars : [ 'Version' ], - #category : #'Launchpad-Commands' + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadRootCommand class >> commandName [ ^ 'launchpad' ] -{ #category : #'class initialization' } +{ #category : 'class initialization' } LaunchpadRootCommand class >> initialize [ <ignoreForCoverage> self version: ( VersionFromRepositoryResolver new valueFor: 'Launchpad' ) ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadRootCommand class >> summary [ ^ 'A minimal application launcher' ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadRootCommand class >> version [ ^ Version ifNil: [ '' ] ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadRootCommand class >> version: aVersion [ Version := aVersion ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadRootCommand >> description [ ^ 'A command-line interface to start, list, and explain the applications available within the image.' ] -{ #category : #evaluating } +{ #category : 'evaluating' } LaunchpadRootCommand >> evaluateWithin: context [ - self handleOptionsAndWithNextArgumentIn: context do: [ :argument | - subcommands detect: [ :subcommand | subcommand canHandle: argument ] - ifFound: [ :subcommand | subcommand evaluateWithin: context ] - ifNone: [ context emitErrorAndExit: ( self unkownCommandMessageFor: argument ) ] - ] + ^ self handleOptionsAndWithNextArgumentIn: context do: [ :argument | + subcommands + detect: [ :subcommand | subcommand canHandle: argument ] + ifFound: [ :subcommand | subcommand evaluateWithin: context ] + ifNone: [ context emitErrorAndExit: ( self unkownCommandMessageFor: argument ) ] + ] ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadRootCommand >> fullCommandName [ ^ self name ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadRootCommand >> fullName [ ^ self name ] -{ #category : #initialization } +{ #category : 'initialization' } LaunchpadRootCommand >> initialize [ super initialize. @@ -80,37 +82,37 @@ LaunchpadRootCommand >> initialize [ with: LaunchpadExplainApplicationCommand new ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadRootCommand >> name [ ^ self class commandName ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommand >> nextCommandLineArgumentIn: context [ ^ context nextCommandLineArgumentIfNone: [ context emitErrorAndExit: 'Missing command or option.' ] ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadRootCommand >> options [ ^options ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadRootCommand >> subcommands [ ^ subcommands ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadRootCommand >> summary [ ^ self class summary ] -{ #category : #private } +{ #category : 'private' } LaunchpadRootCommand >> unkownCommandMessageFor: argument [ ^ '<1s> unknown <2?option:command>: <3s>' expandMacrosWith: self name @@ -118,7 +120,7 @@ LaunchpadRootCommand >> unkownCommandMessageFor: argument [ with: argument ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadRootCommand >> version [ ^ self class version diff --git a/source/Launchpad-Commands/LaunchpadSettingsFileOption.class.st b/source/Launchpad-Commands/LaunchpadSettingsFileOption.class.st index ccd8f53..b437aa6 100644 --- a/source/Launchpad-Commands/LaunchpadSettingsFileOption.class.st +++ b/source/Launchpad-Commands/LaunchpadSettingsFileOption.class.st @@ -1,60 +1,62 @@ Class { - #name : #LaunchpadSettingsFileOption, - #superclass : #LaunchpadOption, + #name : 'LaunchpadSettingsFileOption', + #superclass : 'LaunchpadOption', #instVars : [ 'command' ], - #category : #'Launchpad-Commands' + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } LaunchpadSettingsFileOption class >> for: aCommand [ ^ self new initializeFor: aCommand ] -{ #category : #testing } +{ #category : 'testing' } LaunchpadSettingsFileOption >> canHandle: argument [ ^ argument beginsWith: '--' , self name , '=' ] -{ #category : #evaluating } +{ #category : 'evaluating' } LaunchpadSettingsFileOption >> evaluateWithin: context handling: argument [ | fileName | fileName := argument withoutFirst: self name size + 3. - command addConfigurationProviderFromFile: fileName asFileReference + command addConfigurationProviderFromFile: fileName asFileReference. + ^ context ] -{ #category : #initialization } +{ #category : 'initialization' } LaunchpadSettingsFileOption >> initializeFor: aCommand [ command := aCommand ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadSettingsFileOption >> name [ ^ 'settings-file' ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadSettingsFileOption >> printHelpOn: stream [ super printHelpOn: stream. self printSuffixOn: stream ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadSettingsFileOption >> printSuffixOn: stream [ stream nextPutAll: '=<filename>' ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadSettingsFileOption >> summary [ ^ 'Provide application configuration via a settings file. This option can occur several times to configure more than one settings file. Supported file settings formats are INI and JSON.' diff --git a/source/Launchpad-Commands/LaunchpadShortOption.class.st b/source/Launchpad-Commands/LaunchpadShortOption.class.st index feb985c..d166b41 100644 --- a/source/Launchpad-Commands/LaunchpadShortOption.class.st +++ b/source/Launchpad-Commands/LaunchpadShortOption.class.st @@ -1,23 +1,24 @@ Class { - #name : #LaunchpadShortOption, - #superclass : #LaunchpadOption, - #category : #'Launchpad-Commands' + #name : 'LaunchpadShortOption', + #superclass : 'LaunchpadOption', + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #testing } +{ #category : 'testing' } LaunchpadShortOption class >> isAbstract [ <ignoreForCoverage> ^ self = LaunchpadShortOption ] -{ #category : #testing } +{ #category : 'testing' } LaunchpadShortOption >> canHandle: argument [ ^ ( super canHandle: argument ) or: [ argument = ( '-' , self shortName ) ] ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadShortOption >> printHelpOn: stream [ stream @@ -28,7 +29,7 @@ LaunchpadShortOption >> printHelpOn: stream [ super printHelpOn: stream ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadShortOption >> printSuffixOn: stream [ stream @@ -36,7 +37,7 @@ LaunchpadShortOption >> printSuffixOn: stream [ nextPutAll: self shortName ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadShortOption >> shortName [ ^ self subclassResponsibility diff --git a/source/Launchpad-Commands/LaunchpadStartApplicationCommand.class.st b/source/Launchpad-Commands/LaunchpadStartApplicationCommand.class.st index 8e77fa1..80c1051 100644 --- a/source/Launchpad-Commands/LaunchpadStartApplicationCommand.class.st +++ b/source/Launchpad-Commands/LaunchpadStartApplicationCommand.class.st @@ -1,23 +1,24 @@ Class { - #name : #LaunchpadStartApplicationCommand, - #superclass : #LaunchpadApplicationCommand, + #name : 'LaunchpadStartApplicationCommand', + #superclass : 'LaunchpadApplicationCommand', #instVars : [ 'options', 'baseConfigurationProvider', 'applicationMode', 'commandServer' ], - #category : #'Launchpad-Commands' + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #configuring } +{ #category : 'configuring' } LaunchpadStartApplicationCommand >> addConfigurationProviderFromFile: aFileReference [ baseConfigurationProvider := ConfigurationFromSettingsFileProvider loading: aFileReference chainedWith: baseConfigurationProvider ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadStartApplicationCommand >> description [ ^ 'Start the application selected via <app>. @@ -25,7 +26,7 @@ Application configuration is made by the command-line via <parameters>, using en Execute launchpad explain <app> to get a list of valid configuration parameters.' ] -{ #category : #configuring } +{ #category : 'configuring' } LaunchpadStartApplicationCommand >> enableStructuredLogging [ [ @@ -39,44 +40,46 @@ LaunchpadStartApplicationCommand >> enableStructuredLogging [ ] ensure: [ StandardStreamLogger onStandardError stop ] ] -{ #category : #evaluating } +{ #category : 'evaluating' } LaunchpadStartApplicationCommand >> evaluateWithin: context [ - self handleOptionsAndWithNextArgumentIn: context do: [ :argument | - LaunchpadApplication applicationFor: argument - ifFound: [ :application | self start: application within: context ] - ifNone: [ context emitErrorAndExit: ( self unknownOptionOrApplicationMessageFor: argument ) ] - ] + ^ self handleOptionsAndWithNextArgumentIn: context do: [ :argument | + LaunchpadApplication + applicationFor: argument + ifFound: [ :application | self start: application within: context ] + ifNone: [ context emitErrorAndExit: ( self unknownOptionOrApplicationMessageFor: argument ) ] + ] ] -{ #category : #initialization } +{ #category : 'initialization' } LaunchpadStartApplicationCommand >> initialize [ super initialize. - options := OrderedCollection - with: (LaunchpadHelpOption for: self) - with: (LaunchpadDebugModeOption for: self) - with: (LaunchpadSettingsFileOption for: self) - with: (LaunchpadStructuredLoggingOption for: self). - options addAll: (LaunchpadOption additionalStartingOptionsFor: self). + options := OrderedCollection new. + options add: ( LaunchpadHelpOption for: self ). + options add: ( LaunchpadDebugModeOption for: self ). + options add: ( LaunchpadSettingsFileOption for: self ). + options add: ( LaunchpadStructuredLoggingOption for: self ). + options add: LaunchpadDryRunOption new. + options addAll: ( LaunchpadOption additionalStartingOptionsFor: self ). baseConfigurationProvider := NullConfigurationProvider new. applicationMode := ReleasedApplicationMode new. commandServer := NullCommandServer new ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadStartApplicationCommand >> name [ ^ 'start' ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadStartApplicationCommand >> options [ ^ options ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadStartApplicationCommand >> printCommandArgumentsOn: stream [ super printCommandArgumentsOn: stream. @@ -85,13 +88,13 @@ LaunchpadStartApplicationCommand >> printCommandArgumentsOn: stream [ nextPutAll: '<app> [<parameters>]' ] -{ #category : #configuring } +{ #category : 'configuring' } LaunchpadStartApplicationCommand >> setDebugMode [ applicationMode := DebuggingApplicationMode new ] -{ #category : #private } +{ #category : 'private' } LaunchpadStartApplicationCommand >> start: anApplication within: context [ | configurationProvider applicationToStart | @@ -104,16 +107,17 @@ LaunchpadStartApplicationCommand >> start: anApplication within: context [ configuredBy: configurationProvider controlledBy: commandServer. LaunchpadApplication setAsCurrentlyRunning: applicationToStart. - applicationToStart startWithin: context + applicationToStart startWithin: context. + ^ applicationToStart ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadStartApplicationCommand >> subcommands [ ^ #() ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadStartApplicationCommand >> summary [ ^ 'Start the selected application' diff --git a/source/Launchpad-Commands/LaunchpadStructuredLoggingOption.class.st b/source/Launchpad-Commands/LaunchpadStructuredLoggingOption.class.st index 6e56a53..eff7c9a 100644 --- a/source/Launchpad-Commands/LaunchpadStructuredLoggingOption.class.st +++ b/source/Launchpad-Commands/LaunchpadStructuredLoggingOption.class.st @@ -1,37 +1,39 @@ Class { - #name : #LaunchpadStructuredLoggingOption, - #superclass : #LaunchpadOption, + #name : 'LaunchpadStructuredLoggingOption', + #superclass : 'LaunchpadOption', #instVars : [ 'command' ], - #category : #'Launchpad-Commands' + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } LaunchpadStructuredLoggingOption class >> for: aCommand [ ^ self new initializeFor: aCommand ] -{ #category : #evaluating } +{ #category : 'evaluating' } LaunchpadStructuredLoggingOption >> evaluateWithin: context handling: argument [ - command enableStructuredLogging + command enableStructuredLogging. + ^ context ] -{ #category : #initialization } +{ #category : 'initialization' } LaunchpadStructuredLoggingOption >> initializeFor: aCommand [ command := aCommand ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadStructuredLoggingOption >> name [ ^ 'enable-structured-logging' ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadStructuredLoggingOption >> summary [ ^ 'Enable structured logging. When enabled the log will be emitted in JSON format.' diff --git a/source/Launchpad-Commands/LaunchpadVerboseOption.class.st b/source/Launchpad-Commands/LaunchpadVerboseOption.class.st index d2b8851..c008359 100644 --- a/source/Launchpad-Commands/LaunchpadVerboseOption.class.st +++ b/source/Launchpad-Commands/LaunchpadVerboseOption.class.st @@ -1,43 +1,44 @@ Class { - #name : #LaunchpadVerboseOption, - #superclass : #LaunchpadShortOption, + #name : 'LaunchpadVerboseOption', + #superclass : 'LaunchpadShortOption', #instVars : [ 'command' ], - #category : #'Launchpad-Commands' + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } LaunchpadVerboseOption class >> for: aCommand [ ^ self new initializeFor: aCommand ] -{ #category : #evaluating } +{ #category : 'evaluating' } LaunchpadVerboseOption >> evaluateWithin: context handling: argument [ command evaluateInVerboseModeWithin: context ] -{ #category : #initialization } +{ #category : 'initialization' } LaunchpadVerboseOption >> initializeFor: aCommand [ command := aCommand ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadVerboseOption >> name [ ^ 'verbose' ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadVerboseOption >> shortName [ ^ 'v' ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadVerboseOption >> summary [ ^ 'Produce more verbose output.' diff --git a/source/Launchpad-Commands/LaunchpadVersionOption.class.st b/source/Launchpad-Commands/LaunchpadVersionOption.class.st index e496fea..4c51086 100644 --- a/source/Launchpad-Commands/LaunchpadVersionOption.class.st +++ b/source/Launchpad-Commands/LaunchpadVersionOption.class.st @@ -1,19 +1,20 @@ Class { - #name : #LaunchpadVersionOption, - #superclass : #LaunchpadOption, + #name : 'LaunchpadVersionOption', + #superclass : 'LaunchpadOption', #instVars : [ 'command' ], - #category : #'Launchpad-Commands' + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } LaunchpadVersionOption class >> for: aCommand [ ^ self new initializeFor: aCommand ] -{ #category : #evaluating } +{ #category : 'evaluating' } LaunchpadVersionOption >> evaluateWithin: context handling: argument [ context outputStreamDo: [ :stream | @@ -26,19 +27,19 @@ LaunchpadVersionOption >> evaluateWithin: context handling: argument [ context exitSuccess ] -{ #category : #initialization } +{ #category : 'initialization' } LaunchpadVersionOption >> initializeFor: aCommand [ command := aCommand ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadVersionOption >> name [ ^ 'version' ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadVersionOption >> summary [ ^ 'Print the version and exit.' diff --git a/source/Launchpad-Commands/NullCommandServer.class.st b/source/Launchpad-Commands/NullCommandServer.class.st index 58b64bd..f42262a 100644 --- a/source/Launchpad-Commands/NullCommandServer.class.st +++ b/source/Launchpad-Commands/NullCommandServer.class.st @@ -1,16 +1,17 @@ Class { - #name : #NullCommandServer, - #superclass : #CommandServer, - #category : #'Launchpad-Commands' + #name : 'NullCommandServer', + #superclass : 'CommandServer', + #category : 'Launchpad-Commands', + #package : 'Launchpad-Commands' } -{ #category : #controlling } +{ #category : 'controlling' } NullCommandServer >> start [ ] -{ #category : #controlling } +{ #category : 'controlling' } NullCommandServer >> stop [ diff --git a/source/Launchpad-Commands/package.st b/source/Launchpad-Commands/package.st index e22d192..0449bff 100644 --- a/source/Launchpad-Commands/package.st +++ b/source/Launchpad-Commands/package.st @@ -1 +1 @@ -Package { #name : #'Launchpad-Commands' } +Package { #name : 'Launchpad-Commands' } diff --git a/source/Launchpad-Configuration-Pharo-Extensions/Boolean.extension.st b/source/Launchpad-Configuration-Pharo-Extensions/Boolean.extension.st new file mode 100644 index 0000000..68b7c2a --- /dev/null +++ b/source/Launchpad-Configuration-Pharo-Extensions/Boolean.extension.st @@ -0,0 +1,8 @@ +Extension { #name : #Boolean } + +{ #category : #'*Launchpad-Configuration-Pharo-Extensions' } +Boolean >> asBoolean [ + "For easier configuation parameter handling of boolean value" + + ^self +] diff --git a/source/Launchpad-Configuration-Tests/ApplicationConfigurationTest.class.st b/source/Launchpad-Configuration-Tests/ApplicationConfigurationTest.class.st index 69edb0a..46d90a3 100644 --- a/source/Launchpad-Configuration-Tests/ApplicationConfigurationTest.class.st +++ b/source/Launchpad-Configuration-Tests/ApplicationConfigurationTest.class.st @@ -2,12 +2,13 @@ An ApplicationConfigurationTest is a test class for testing the behavior of ApplicationConfiguration " Class { - #name : #ApplicationConfigurationTest, - #superclass : #LaunchpadTest, - #category : #'Launchpad-Configuration-Tests' + #name : 'ApplicationConfigurationTest', + #superclass : 'LaunchpadTest', + #category : 'Launchpad-Configuration-Tests', + #package : 'Launchpad-Configuration-Tests' } -{ #category : #private } +{ #category : 'private' } ApplicationConfigurationTest >> assert: string isLineEndingInsensitiveEqualsTo: anotherString [ self @@ -15,13 +16,13 @@ ApplicationConfigurationTest >> assert: string isLineEndingInsensitiveEqualsTo: equals: (anotherString withLineEndings: String lf) ] -{ #category : #private } +{ #category : 'private' } ApplicationConfigurationTest >> commandLineProviderOver: arguments [ ^ ConfigurationFromCommandLineProvider over: ( CommandLineArguments withArguments: arguments ) ] -{ #category : #private } +{ #category : 'private' } ApplicationConfigurationTest >> createFileNamed: fileName containing: fileContents during: aBlock [ | fileReference | @@ -34,7 +35,7 @@ ApplicationConfigurationTest >> createFileNamed: fileName containing: fileConten ] ensure: [ fileReference ensureDelete ] ] -{ #category : #private } +{ #category : 'private' } ApplicationConfigurationTest >> newApplicationConfiguration [ | provider parameters | @@ -61,7 +62,7 @@ ApplicationConfigurationTest >> newApplicationConfiguration [ ^ ApplicationConfiguration forAll: parameters providedBy: provider ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testAccessing [ | configuration parameters provider | @@ -90,7 +91,7 @@ ApplicationConfigurationTest >> testAccessing [ assert: configuration communications http scheme equals: 'https' ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testAsCommandLine [ | configuration commandLine | @@ -102,7 +103,7 @@ ApplicationConfigurationTest >> testAsCommandLine [ ' --communications.http.port=8086 --communications.http.scheme=https --public-url=https://api.example.com/ --service-discovery.consul-agent-location=localhost' ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testAsEnvironment [ | configuration env | @@ -120,7 +121,7 @@ SERVICE_DISCOVERY__CONSUL_AGENT_LOCATION=localhost ' ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testAsIniFile [ | configuration ini | @@ -142,7 +143,7 @@ consulAgentLocation = localhost ' ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testAsJson [ | configuration json | @@ -156,7 +157,7 @@ ApplicationConfigurationTest >> testAsJson [ assert: ( json atPath: #( #serviceDiscovery #consulAgentLocation ) ) equals: 'localhost' ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testCantCreateConfigurationWhenParameterConflictsWithSection [ | parameters provider | @@ -174,7 +175,7 @@ ApplicationConfigurationTest >> testCantCreateConfigurationWhenParameterConflict withMessageText: 'Section conflicting with parameter: "Port"' ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testCantCreateConfigurationWithOverlappingParameters [ | parameters provider | @@ -191,7 +192,7 @@ ApplicationConfigurationTest >> testCantCreateConfigurationWithOverlappingParame withMessageText: 'Conflicting parameter: "Port"' ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testDoNotWarnOnOptionalParametersWhenUsingDefault [ | configuration parameter provider logger | @@ -208,7 +209,7 @@ ApplicationConfigurationTest >> testDoNotWarnOnOptionalParametersWhenUsingDefaul self assert: logger recordings isEmpty ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testLoadingIniBasedSettings [ | configuration iniFile provider | @@ -226,7 +227,7 @@ ApplicationConfigurationTest >> testLoadingIniBasedSettings [ assert: configuration communications http scheme equals: 'https' ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testLoadingJsonSettings [ | configuration jsonFile provider | @@ -244,7 +245,7 @@ ApplicationConfigurationTest >> testLoadingJsonSettings [ assert: configuration communications http scheme equals: 'https' ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testLogging [ | configuration parameters provider | @@ -272,7 +273,7 @@ ApplicationConfigurationTest >> testLogging [ '[INFO] Scheme: https' ) ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testLoggingWhenUsingConverters [ | configuration parameters provider | @@ -305,7 +306,7 @@ ApplicationConfigurationTest >> testLoggingWhenUsingConverters [ '[INFO] Target port: 9999' ) ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testMissingParameterValue [ | parameter | @@ -320,7 +321,7 @@ ApplicationConfigurationTest >> testMissingParameterValue [ withMessageText: '"Port" parameter not present.' ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testReloadingConfiguration [ | fileName configuration | @@ -354,7 +355,7 @@ ApplicationConfigurationTest >> testReloadingConfiguration [ assert: configuration serviceDiscovery consulAgentLocation equals: 'consul.example.com' ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testReloadingEmptyConfiguration [ | fileName configuration | @@ -387,7 +388,7 @@ ApplicationConfigurationTest >> testReloadingEmptyConfiguration [ assert: configuration serviceDiscovery consulAgentLocation equals: 'localhost' ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testReloadingEnvironmentVariableSettings [ | configuration provider | @@ -406,7 +407,7 @@ ApplicationConfigurationTest >> testReloadingEnvironmentVariableSettings [ raise: RequiredConfigurationNotFound ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testReloadingIniBasedSettings [ | configuration iniFile provider | @@ -435,7 +436,7 @@ ApplicationConfigurationTest >> testReloadingIniBasedSettings [ assert: configuration communications http scheme equals: 'https' ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testReloadingJsonSettings [ | configuration json provider | @@ -464,7 +465,7 @@ ApplicationConfigurationTest >> testReloadingJsonSettings [ assert: configuration communications http scheme equals: 'https' ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testValueForGlobalParameter [ | configuration parameter provider | @@ -480,7 +481,7 @@ ApplicationConfigurationTest >> testValueForGlobalParameter [ self assert: ( configuration valueFor: parameter ) equals: 8086 ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testValueForParameterInSection [ | configuration parameter provider | @@ -497,7 +498,7 @@ ApplicationConfigurationTest >> testValueForParameterInSection [ self assert: ( configuration valueFor: parameter ) equals: 8086 ] -{ #category : #tests } +{ #category : 'tests' } ApplicationConfigurationTest >> testWarningOnOptionalParametersWhenUsingTheDefault [ | parameter | diff --git a/source/Launchpad-Configuration-Tests/ConfigurationFromCommandLineProviderTest.class.st b/source/Launchpad-Configuration-Tests/ConfigurationFromCommandLineProviderTest.class.st index 7f7cc45..0cc7165 100644 --- a/source/Launchpad-Configuration-Tests/ConfigurationFromCommandLineProviderTest.class.st +++ b/source/Launchpad-Configuration-Tests/ConfigurationFromCommandLineProviderTest.class.st @@ -2,18 +2,19 @@ A ConfigurationFromCommandLineProviderTest is a test class for testing the behavior of ConfigurationFromCommandLineProvider " Class { - #name : #ConfigurationFromCommandLineProviderTest, - #superclass : #TestCase, - #category : #'Launchpad-Configuration-Tests' + #name : 'ConfigurationFromCommandLineProviderTest', + #superclass : 'TestCase', + #category : 'Launchpad-Configuration-Tests', + #package : 'Launchpad-Configuration-Tests' } -{ #category : #private } +{ #category : 'private' } ConfigurationFromCommandLineProviderTest >> providerOver: arguments [ ^ ConfigurationFromCommandLineProvider over: ( CommandLineArguments withArguments: arguments ) ] -{ #category : #tests } +{ #category : 'tests' } ConfigurationFromCommandLineProviderTest >> testMandatoryConfigurationParameterValue [ | provider mandatoryParameter | @@ -27,7 +28,7 @@ ConfigurationFromCommandLineProviderTest >> testMandatoryConfigurationParameterV equals: 'localhost' ] -{ #category : #tests } +{ #category : 'tests' } ConfigurationFromCommandLineProviderTest >> testMandatoryConfigurationParameterValueMissing [ | provider mandatoryParameter | @@ -41,7 +42,7 @@ ConfigurationFromCommandLineProviderTest >> testMandatoryConfigurationParameterV equals: 'example.com' ] -{ #category : #tests } +{ #category : 'tests' } ConfigurationFromCommandLineProviderTest >> testOptionalConfigurationParameterValue [ | provider parameter | @@ -56,7 +57,7 @@ ConfigurationFromCommandLineProviderTest >> testOptionalConfigurationParameterVa equals: 'https://example.com' ] -{ #category : #tests } +{ #category : 'tests' } ConfigurationFromCommandLineProviderTest >> testOptionalConfigurationParameterValueUsingDefault [ | provider parameter | @@ -71,7 +72,7 @@ ConfigurationFromCommandLineProviderTest >> testOptionalConfigurationParameterVa equals: 'localhost' ] -{ #category : #tests } +{ #category : 'tests' } ConfigurationFromCommandLineProviderTest >> testSensitiveMandatoryConfigurationParameterValue [ | provider mandatoryParameter | @@ -85,7 +86,7 @@ ConfigurationFromCommandLineProviderTest >> testSensitiveMandatoryConfigurationP equals: 'localhost' ] -{ #category : #tests } +{ #category : 'tests' } ConfigurationFromCommandLineProviderTest >> testSensitiveOptionalConfigurationParameterValue [ | provider parameter | diff --git a/source/Launchpad-Configuration-Tests/ConfigurationFromEnvironmentProviderTest.class.st b/source/Launchpad-Configuration-Tests/ConfigurationFromEnvironmentProviderTest.class.st index 69f5735..64a3f3e 100644 --- a/source/Launchpad-Configuration-Tests/ConfigurationFromEnvironmentProviderTest.class.st +++ b/source/Launchpad-Configuration-Tests/ConfigurationFromEnvironmentProviderTest.class.st @@ -2,12 +2,13 @@ A ConfigurationFromEnvironmentProviderTest is a test class for testing the behavior of ConfigurationFromEnvironmentProvider " Class { - #name : #ConfigurationFromEnvironmentProviderTest, - #superclass : #TestCase, - #category : #'Launchpad-Configuration-Tests' + #name : 'ConfigurationFromEnvironmentProviderTest', + #superclass : 'TestCase', + #category : 'Launchpad-Configuration-Tests', + #package : 'Launchpad-Configuration-Tests' } -{ #category : #private } +{ #category : 'private' } ConfigurationFromEnvironmentProviderTest >> set: environmentVariableName to: value during: aBlock [ LanguagePlatform current os @@ -18,7 +19,7 @@ ConfigurationFromEnvironmentProviderTest >> set: environmentVariableName to: val environmentVariableName ] ] -{ #category : #tests } +{ #category : 'tests' } ConfigurationFromEnvironmentProviderTest >> testMandatoryConfigurationParameterValue [ | provider parameter | @@ -33,7 +34,7 @@ ConfigurationFromEnvironmentProviderTest >> testMandatoryConfigurationParameterV self assert: ( parameter resolveValueUsing: provider ifUnable: [ self fail ] ) equals: 'localhost' ] ] -{ #category : #tests } +{ #category : 'tests' } ConfigurationFromEnvironmentProviderTest >> testMandatoryConfigurationParameterValueMissing [ | provider parameter | @@ -48,7 +49,7 @@ ConfigurationFromEnvironmentProviderTest >> testMandatoryConfigurationParameterV equals: 'example.com' ] -{ #category : #tests } +{ #category : 'tests' } ConfigurationFromEnvironmentProviderTest >> testOptionalConfigurationParameterValue [ | provider parameter | @@ -66,7 +67,7 @@ ConfigurationFromEnvironmentProviderTest >> testOptionalConfigurationParameterVa ] ] -{ #category : #tests } +{ #category : 'tests' } ConfigurationFromEnvironmentProviderTest >> testOptionalConfigurationParameterValueUsingDefault [ | provider parameter | @@ -81,7 +82,7 @@ ConfigurationFromEnvironmentProviderTest >> testOptionalConfigurationParameterVa self assert: ( parameter resolveValueUsing: provider ifUnable: [ self fail ] ) equals: 'localhost' ] -{ #category : #tests } +{ #category : 'tests' } ConfigurationFromEnvironmentProviderTest >> testSensitiveMandatoryConfigurationParameterValue [ | provider parameter | @@ -96,7 +97,7 @@ ConfigurationFromEnvironmentProviderTest >> testSensitiveMandatoryConfigurationP self assert: ( parameter resolveValueUsing: provider ifUnable: [ self fail ] ) equals: 'localhost' ] ] -{ #category : #tests } +{ #category : 'tests' } ConfigurationFromEnvironmentProviderTest >> testSensitiveOptionalConfigurationParameterValue [ | provider parameter | @@ -114,7 +115,7 @@ ConfigurationFromEnvironmentProviderTest >> testSensitiveOptionalConfigurationPa ] ] -{ #category : #tests } +{ #category : 'tests' } ConfigurationFromEnvironmentProviderTest >> testValueResolutionDelegatesToNextInChainWhenMissing [ | provider parameter | diff --git a/source/Launchpad-Configuration-Tests/ConfigurationFromSettingsFileProviderTest.class.st b/source/Launchpad-Configuration-Tests/ConfigurationFromSettingsFileProviderTest.class.st index 253e2d7..42a4efe 100644 --- a/source/Launchpad-Configuration-Tests/ConfigurationFromSettingsFileProviderTest.class.st +++ b/source/Launchpad-Configuration-Tests/ConfigurationFromSettingsFileProviderTest.class.st @@ -2,12 +2,13 @@ A ConfigurationFromSettingsFileProviderTest is a test class for testing the behavior of ConfigurationFromSettingsFileProvider " Class { - #name : #ConfigurationFromSettingsFileProviderTest, - #superclass : #TestCase, - #category : #'Launchpad-Configuration-Tests' + #name : 'ConfigurationFromSettingsFileProviderTest', + #superclass : 'TestCase', + #category : 'Launchpad-Configuration-Tests', + #package : 'Launchpad-Configuration-Tests' } -{ #category : #tests } +{ #category : 'tests' } ConfigurationFromSettingsFileProviderTest >> testCannotLoadInvalidFormat [ self should: [ ConfigurationFromSettingsFileProvider loading: 'invalid.dat' asFileReference ] diff --git a/source/Launchpad-Configuration-Tests/MandatoryConfigurationParameterTest.class.st b/source/Launchpad-Configuration-Tests/MandatoryConfigurationParameterTest.class.st index a45836c..7d8a750 100644 --- a/source/Launchpad-Configuration-Tests/MandatoryConfigurationParameterTest.class.st +++ b/source/Launchpad-Configuration-Tests/MandatoryConfigurationParameterTest.class.st @@ -2,12 +2,13 @@ A MandatoryConfigurationParameterTest is a test class for testing the behavior of MandatoryConfigurationParameter " Class { - #name : #MandatoryConfigurationParameterTest, - #superclass : #TestCase, - #category : #'Launchpad-Configuration-Tests' + #name : 'MandatoryConfigurationParameterTest', + #superclass : 'TestCase', + #category : 'Launchpad-Configuration-Tests', + #package : 'Launchpad-Configuration-Tests' } -{ #category : #private } +{ #category : 'private' } MandatoryConfigurationParameterTest >> commandLineProviderSetting: aParameter to: aString [ ^ ConfigurationFromCommandLineProvider over: ( CommandLineArguments withArguments: @@ -15,7 +16,7 @@ MandatoryConfigurationParameterTest >> commandLineProviderSetting: aParameter to ( '--<1s>=<2s>' expandMacrosWith: aParameter commandLineArgumentName with: aString ) ) ) ] -{ #category : #private } +{ #category : 'private' } MandatoryConfigurationParameterTest >> numberConversionAction [ ^ [ :value | @@ -25,7 +26,7 @@ MandatoryConfigurationParameterTest >> numberConversionAction [ value asNumber ] ] -{ #category : #tests } +{ #category : 'tests' } MandatoryConfigurationParameterTest >> testAccessing [ | parameter | @@ -41,7 +42,7 @@ MandatoryConfigurationParameterTest >> testAccessing [ assert: parameter attributeName equals: 'publicURL' ] -{ #category : #tests } +{ #category : 'tests' } MandatoryConfigurationParameterTest >> testAccessingInInnerSection [ | parameter | @@ -58,7 +59,7 @@ MandatoryConfigurationParameterTest >> testAccessingInInnerSection [ assert: parameter attributeName equals: 'publicURL' ] -{ #category : #tests } +{ #category : 'tests' } MandatoryConfigurationParameterTest >> testAccessingInSection [ | parameter | @@ -75,7 +76,7 @@ MandatoryConfigurationParameterTest >> testAccessingInSection [ assert: parameter attributeName equals: 'publicURL' ] -{ #category : #tests } +{ #category : 'tests' } MandatoryConfigurationParameterTest >> testBooleanTransformation [ | parameter | @@ -101,7 +102,7 @@ MandatoryConfigurationParameterTest >> testBooleanTransformation [ withMessageText: 'unclear can''t be interpreted as a boolean' ] -{ #category : #tests } +{ #category : 'tests' } MandatoryConfigurationParameterTest >> testNumberTransformation [ | parameter | @@ -126,7 +127,7 @@ MandatoryConfigurationParameterTest >> testNumberTransformation [ withMessageText: 'Expected a number' ] -{ #category : #tests } +{ #category : 'tests' } MandatoryConfigurationParameterTest >> testPrintString [ | parameter | @@ -145,7 +146,7 @@ MandatoryConfigurationParameterTest >> testPrintString [ [Mandatory] The service''s public URL.' ] -{ #category : #tests } +{ #category : 'tests' } MandatoryConfigurationParameterTest >> testUrlTransformation [ | parameter | @@ -161,7 +162,7 @@ MandatoryConfigurationParameterTest >> testUrlTransformation [ self assert: ( self valueWhenSetting: parameter to: '' ) equals: ( ZnUrl fromString: '/' ) ] -{ #category : #private } +{ #category : 'private' } MandatoryConfigurationParameterTest >> valueWhenSetting: aParameter to: aString [ | provider | diff --git a/source/Launchpad-Configuration-Tests/OptionalConfigurationParameterTest.class.st b/source/Launchpad-Configuration-Tests/OptionalConfigurationParameterTest.class.st index d250865..f6b5423 100644 --- a/source/Launchpad-Configuration-Tests/OptionalConfigurationParameterTest.class.st +++ b/source/Launchpad-Configuration-Tests/OptionalConfigurationParameterTest.class.st @@ -2,12 +2,13 @@ An OptionalConfigurationParameterTest is a test class for testing the behavior of OptionalConfigurationParameter " Class { - #name : #OptionalConfigurationParameterTest, - #superclass : #TestCase, - #category : #'Launchpad-Configuration-Tests' + #name : 'OptionalConfigurationParameterTest', + #superclass : 'TestCase', + #category : 'Launchpad-Configuration-Tests', + #package : 'Launchpad-Configuration-Tests' } -{ #category : #private } +{ #category : 'private' } OptionalConfigurationParameterTest >> commandLineProviderSetting: aParameter to: aString [ ^ ConfigurationFromCommandLineProvider over: ( CommandLineArguments withArguments: @@ -15,7 +16,7 @@ OptionalConfigurationParameterTest >> commandLineProviderSetting: aParameter to: ( '--<1s>=<2s>' expandMacrosWith: aParameter commandLineArgumentName with: aString ) ) ) ] -{ #category : #private } +{ #category : 'private' } OptionalConfigurationParameterTest >> numberConversionAction [ ^ [ :value | @@ -25,7 +26,7 @@ OptionalConfigurationParameterTest >> numberConversionAction [ value asNumber ] ] -{ #category : #tests } +{ #category : 'tests' } OptionalConfigurationParameterTest >> testAccessing [ | parameter | @@ -42,7 +43,7 @@ OptionalConfigurationParameterTest >> testAccessing [ assert: parameter attributeName equals: 'port' ] -{ #category : #tests } +{ #category : 'tests' } OptionalConfigurationParameterTest >> testAccessingInInnerSection [ | parameter | @@ -60,7 +61,7 @@ OptionalConfigurationParameterTest >> testAccessingInInnerSection [ assert: parameter attributeName equals: 'port' ] -{ #category : #tests } +{ #category : 'tests' } OptionalConfigurationParameterTest >> testAccessingInSection [ | parameter | @@ -78,7 +79,7 @@ OptionalConfigurationParameterTest >> testAccessingInSection [ assert: parameter attributeName equals: 'port' ] -{ #category : #tests } +{ #category : 'tests' } OptionalConfigurationParameterTest >> testBooleanTransformation [ | parameter | @@ -105,7 +106,7 @@ OptionalConfigurationParameterTest >> testBooleanTransformation [ withMessageText: 'unclear can''t be interpreted as a boolean' ] -{ #category : #tests } +{ #category : 'tests' } OptionalConfigurationParameterTest >> testNumberTransformation [ | parameter | @@ -131,7 +132,7 @@ OptionalConfigurationParameterTest >> testNumberTransformation [ withMessageText: 'Expected a number' ] -{ #category : #tests } +{ #category : 'tests' } OptionalConfigurationParameterTest >> testPrintString [ | parameter | @@ -152,7 +153,7 @@ OptionalConfigurationParameterTest >> testPrintString [ [Optional] The service''s listening port. Defaults to 8080.' ] -{ #category : #tests } +{ #category : 'tests' } OptionalConfigurationParameterTest >> testUrlTransformation [ | parameter | @@ -169,7 +170,7 @@ OptionalConfigurationParameterTest >> testUrlTransformation [ self assert: ( self valueWhenSetting: parameter to: '' ) equals: ( ZnUrl fromString: '/' ) ] -{ #category : #private } +{ #category : 'private' } OptionalConfigurationParameterTest >> valueWhenSetting: aParameter to: aString [ | provider | diff --git a/source/Launchpad-Configuration-Tests/SensitiveConfigurationParameterTest.class.st b/source/Launchpad-Configuration-Tests/SensitiveConfigurationParameterTest.class.st index d4d8d15..5b7298e 100644 --- a/source/Launchpad-Configuration-Tests/SensitiveConfigurationParameterTest.class.st +++ b/source/Launchpad-Configuration-Tests/SensitiveConfigurationParameterTest.class.st @@ -2,12 +2,13 @@ A SensitiveConfigurationParameterTest is a test class for testing the behavior of SensitiveConfigurationParameter " Class { - #name : #SensitiveConfigurationParameterTest, - #superclass : #TestCase, - #category : #'Launchpad-Configuration-Tests' + #name : 'SensitiveConfigurationParameterTest', + #superclass : 'TestCase', + #category : 'Launchpad-Configuration-Tests', + #package : 'Launchpad-Configuration-Tests' } -{ #category : #tests } +{ #category : 'tests' } SensitiveConfigurationParameterTest >> testAccessing [ | parameter | @@ -23,7 +24,7 @@ SensitiveConfigurationParameterTest >> testAccessing [ assert: parameter attributeName equals: 'publicURL' ] -{ #category : #tests } +{ #category : 'tests' } SensitiveConfigurationParameterTest >> testConverting [ | parameter | @@ -34,7 +35,7 @@ SensitiveConfigurationParameterTest >> testConverting [ self assert: parameter asSensitive identicalTo: parameter ] -{ #category : #tests } +{ #category : 'tests' } SensitiveConfigurationParameterTest >> testPrintAsCommandLineArgumentTemplate [ | parameter | @@ -47,7 +48,7 @@ SensitiveConfigurationParameterTest >> testPrintAsCommandLineArgumentTemplate [ equals: '--public-url=<publicURL>' ] -{ #category : #tests } +{ #category : 'tests' } SensitiveConfigurationParameterTest >> testPrintString [ | parameter | diff --git a/source/Launchpad-Configuration-Tests/package.st b/source/Launchpad-Configuration-Tests/package.st index 5553562..f7fb3c7 100644 --- a/source/Launchpad-Configuration-Tests/package.st +++ b/source/Launchpad-Configuration-Tests/package.st @@ -1 +1 @@ -Package { #name : #'Launchpad-Configuration-Tests' } +Package { #name : 'Launchpad-Configuration-Tests' } diff --git a/source/Launchpad-Configuration/ApplicationConfiguration.class.st b/source/Launchpad-Configuration/ApplicationConfiguration.class.st index ed59232..83a0dc5 100644 --- a/source/Launchpad-Configuration/ApplicationConfiguration.class.st +++ b/source/Launchpad-Configuration/ApplicationConfiguration.class.st @@ -129,7 +129,7 @@ ApplicationConfiguration >> containingSectionFor: parameter startingAt: resolved { #category : 'reflective operations' } ApplicationConfiguration >> doesNotUnderstand: message [ - ^ values at: message selector ifAbsent: [ super doesNotUnderstand: message ] + ^ self valueAt: message selector ifAbsent: [ super doesNotUnderstand: message ] ] { #category : 'initialization' } @@ -199,6 +199,20 @@ ApplicationConfiguration >> synchronizeValuesWith: resolvedValues [ values := resolvedValues ] +{ #category : 'accessing' } +ApplicationConfiguration >> valueAt: aKey [ + + ^ self valueAt: aKey ifAbsent: [ KeyNotFound signalFor: aKey ] +] + +{ #category : 'accessing' } +ApplicationConfiguration >> valueAt: aKey ifAbsent: aBlock [ + "For configuration access without DNU handling, provide standard Dictionary api. + With normal configuration parameters, there should never be an absent value, but provide the standard ifAbsent option for correctness" + + ^ values at: aKey ifAbsent: aBlock +] + { #category : 'accessing' } ApplicationConfiguration >> valueFor: aParameter [ diff --git a/source/Launchpad-Examples/LaunchpadBrokenApplication.class.st b/source/Launchpad-Examples/LaunchpadBrokenApplication.class.st index 5a1572a..654e69d 100644 --- a/source/Launchpad-Examples/LaunchpadBrokenApplication.class.st +++ b/source/Launchpad-Examples/LaunchpadBrokenApplication.class.st @@ -1,31 +1,32 @@ Class { - #name : #LaunchpadBrokenApplication, - #superclass : #LaunchpadApplication, + #name : 'LaunchpadBrokenApplication', + #superclass : 'LaunchpadApplication', #instVars : [ 'stackTraceDumper' ], - #category : #'Launchpad-Examples' + #category : 'Launchpad-Examples', + #package : 'Launchpad-Examples' } -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadBrokenApplication class >> commandName [ ^ 'broken' ] -{ #category : #'private - accessing' } +{ #category : 'private - accessing' } LaunchpadBrokenApplication class >> configurationParameters [ ^ #( ) ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadBrokenApplication class >> description [ ^ 'A broken application' ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadBrokenApplication class >> printCommandArgumentsOn: stream [ super printCommandArgumentsOn: stream. @@ -36,7 +37,7 @@ LaunchpadBrokenApplication class >> printCommandArgumentsOn: stream [ nextPutAll: ']' ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadBrokenApplication class >> printHelpOn: stream [ super printHelpOn: stream. @@ -51,19 +52,19 @@ LaunchpadBrokenApplication class >> printHelpOn: stream [ cr ] -{ #category : #printing } +{ #category : 'printing' } LaunchpadBrokenApplication class >> raiseErrorOption [ ^ '--raise-error' ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadBrokenApplication class >> version [ ^ 'v0.0.1' ] -{ #category : #'private - activation' } +{ #category : 'private - activation' } LaunchpadBrokenApplication >> basicStartWithin: context [ | nextArgument | @@ -72,7 +73,7 @@ LaunchpadBrokenApplication >> basicStartWithin: context [ nextArgument = self class raiseErrorOption ifTrue: [ Error signal: 'Doh!' ] ] -{ #category : #initialization } +{ #category : 'initialization' } LaunchpadBrokenApplication >> initializeRunningIn: anApplicationMode configuredBy: aConfigurationProvider controlledBy: aCommandServer [ super @@ -82,7 +83,7 @@ LaunchpadBrokenApplication >> initializeRunningIn: anApplicationMode configuredB stackTraceDumper := self newStackTraceDumperOnStandardError ] -{ #category : #'error handling' } +{ #category : 'error handling' } LaunchpadBrokenApplication >> stackTraceDumper [ ^ stackTraceDumper diff --git a/source/Launchpad-Examples/LaunchpadGreeterApplication.class.st b/source/Launchpad-Examples/LaunchpadGreeterApplication.class.st index fc06335..74f66de 100644 --- a/source/Launchpad-Examples/LaunchpadGreeterApplication.class.st +++ b/source/Launchpad-Examples/LaunchpadGreeterApplication.class.st @@ -1,16 +1,17 @@ Class { - #name : #LaunchpadGreeterApplication, - #superclass : #LaunchpadApplication, - #category : #'Launchpad-Examples' + #name : 'LaunchpadGreeterApplication', + #superclass : 'LaunchpadApplication', + #category : 'Launchpad-Examples', + #package : 'Launchpad-Examples' } -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadGreeterApplication class >> commandName [ ^ 'greeter' ] -{ #category : #'private - accessing' } +{ #category : 'private - accessing' } LaunchpadGreeterApplication class >> configurationParameters [ ^ Array with: @@ -20,19 +21,19 @@ LaunchpadGreeterApplication class >> configurationParameters [ defaultingTo: '' ) ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadGreeterApplication class >> description [ ^ 'A greetings application' ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadGreeterApplication class >> version [ ^ 'v1.0.0' ] -{ #category : #'private - activation' } +{ #category : 'private - activation' } LaunchpadGreeterApplication >> basicStartWithin: context [ context outputStreamDo: [ :stream | @@ -44,19 +45,19 @@ LaunchpadGreeterApplication >> basicStartWithin: context [ self exitSuccess ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadGreeterApplication >> name [ ^ self configuration name ] -{ #category : #'error handling' } +{ #category : 'error handling' } LaunchpadGreeterApplication >> stackTraceDumper [ ^ NullStackTraceDumper new ] -{ #category : #accessing } +{ #category : 'accessing' } LaunchpadGreeterApplication >> title [ ^ self configuration title diff --git a/source/Launchpad-Examples/package.st b/source/Launchpad-Examples/package.st index f0c5c6c..dd9d013 100644 --- a/source/Launchpad-Examples/package.st +++ b/source/Launchpad-Examples/package.st @@ -1 +1 @@ -Package { #name : #'Launchpad-Examples' } +Package { #name : 'Launchpad-Examples' } diff --git a/source/Launchpad-SUnit/LaunchpadCommandLineHandler.extension.st b/source/Launchpad-SUnit/LaunchpadCommandLineHandler.extension.st new file mode 100644 index 0000000..ff7c7c4 --- /dev/null +++ b/source/Launchpad-SUnit/LaunchpadCommandLineHandler.extension.st @@ -0,0 +1,7 @@ +Extension { #name : 'LaunchpadCommandLineHandler' } + +{ #category : '*Launchpad-SUnit' } +LaunchpadCommandLineHandler class >> activateWithArguments: arguments [ + + ^ self activateWith: ( CommandLineArguments withArguments: arguments ) +] diff --git a/source/Launchpad-SUnit/LaunchpadTest.class.st b/source/Launchpad-SUnit/LaunchpadTest.class.st index 2db6163..27f0cc0 100644 --- a/source/Launchpad-SUnit/LaunchpadTest.class.st +++ b/source/Launchpad-SUnit/LaunchpadTest.class.st @@ -1,44 +1,61 @@ Class { - #name : #LaunchpadTest, - #superclass : #TestCase, + #name : 'LaunchpadTest', + #superclass : 'TestCase', #instVars : [ 'runningApplication', 'loggingAsserter' ], - #category : #'Launchpad-SUnit' + #category : 'Launchpad-SUnit', + #package : 'Launchpad-SUnit' } -{ #category : #testing } +{ #category : 'testing' } LaunchpadTest class >> isAbstract [ ^ self = LaunchpadTest ] -{ #category : #private } +{ #category : 'private' } LaunchpadTest >> assertLogRecordsMatch: expectedLogEntries [ loggingAsserter assertLogRecordsMatch: expectedLogEntries ] -{ #category : #private } +{ #category : 'private' } LaunchpadTest >> assertThereAreNoLogRecords [ self assertLogRecordsMatch: #( ) ] -{ #category : #running } +{ #category : 'private' } +LaunchpadTest >> dryRun: aLaunchpadApplication withAll: arguments [ + + self runMemoryLoggerDuring: [ + [ + runningApplication := LaunchpadCommandLineHandler activateWithArguments: { + 'start'. + '--debug-mode'. + '--dry-run'. + aLaunchpadApplication commandName } , arguments + ] + on: Exit + do: [ :exit | exit resume ] + ] +] + +{ #category : 'running' } LaunchpadTest >> runCase [ self shouldnt: [ super runCase ] raise: Exit ] -{ #category : #private } +{ #category : 'private' } LaunchpadTest >> runMemoryLoggerDuring: aBlock [ loggingAsserter runMemoryLoggerDuring: aBlock ] -{ #category : #private } +{ #category : 'private' } LaunchpadTest >> runMemoryLoggerDuring: aBlock assertingLogRecordsMatch: expectedLogEntries [ self @@ -46,35 +63,26 @@ LaunchpadTest >> runMemoryLoggerDuring: aBlock assertingLogRecordsMatch: expecte assertLogRecordsMatch: expectedLogEntries ] -{ #category : #running } +{ #category : 'running' } LaunchpadTest >> setUp [ super setUp. loggingAsserter := LoggingAsserter on: self ] -{ #category : #private } +{ #category : 'private' } LaunchpadTest >> start: aLaunchpadApplication withAll: arguments [ - self runMemoryLoggerDuring: [ - String streamContents: [ :output | - | rootCommand commandLine context | - - rootCommand := LaunchpadRootCommand new. - commandLine := CommandLineArguments withArguments: { - 'launchpad'. - 'start'. - '--debug-mode'. - aLaunchpadApplication commandName } , arguments. - context := LaunchpadCommandLineProcessingContext handling: commandLine writingTo: output. - self assert: ( rootCommand canHandle: ( context nextCommandLineArgumentIfNone: [ self fail ] ) ). - rootCommand evaluateWithin: context. - runningApplication := LaunchpadApplication currentlyRunning - ] + self runMemoryLoggerDuring: [ + runningApplication := LaunchpadCommandLineHandler activateWithArguments: { + 'launchpad'. + 'start'. + '--debug-mode'. + aLaunchpadApplication commandName } , arguments ] ] -{ #category : #running } +{ #category : 'running' } LaunchpadTest >> tearDown [ loggingAsserter stopLoggers. diff --git a/source/Launchpad-SUnit/package.st b/source/Launchpad-SUnit/package.st index 5136f49..7efccae 100644 --- a/source/Launchpad-SUnit/package.st +++ b/source/Launchpad-SUnit/package.st @@ -1 +1 @@ -Package { #name : #'Launchpad-SUnit' } +Package { #name : 'Launchpad-SUnit' }