From c501a48cadd85e77ac829ead0867dd2189a99baa Mon Sep 17 00:00:00 2001 From: Pascal Welsch Date: Sun, 8 Jan 2023 14:37:07 +0100 Subject: [PATCH 1/8] Add BashCommand --- sidekick_core/lib/sidekick_core.dart | 1 + sidekick_core/lib/src/cli_util.dart | 14 ++++- .../lib/src/commands/bash_command.dart | 60 +++++++++++++++++++ sidekick_core/lib/src/forward_command.dart | 2 +- 4 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 sidekick_core/lib/src/commands/bash_command.dart diff --git a/sidekick_core/lib/sidekick_core.dart b/sidekick_core/lib/sidekick_core.dart index 135f311f..f930a40c 100644 --- a/sidekick_core/lib/sidekick_core.dart +++ b/sidekick_core/lib/sidekick_core.dart @@ -20,6 +20,7 @@ export 'package:dcli/dcli.dart' hide run, start, startFromArgs, absolute; export 'package:pub_semver/pub_semver.dart' show Version; export 'package:sidekick_core/src/cli_util.dart'; export 'package:sidekick_core/src/commands/analyze_command.dart'; +export 'package:sidekick_core/src/commands/bash_command.dart'; export 'package:sidekick_core/src/commands/dart_command.dart'; export 'package:sidekick_core/src/commands/deps_command.dart'; export 'package:sidekick_core/src/commands/flutter_command.dart'; diff --git a/sidekick_core/lib/src/cli_util.dart b/sidekick_core/lib/src/cli_util.dart index d49934ec..f7855f47 100644 --- a/sidekick_core/lib/src/cli_util.dart +++ b/sidekick_core/lib/src/cli_util.dart @@ -36,21 +36,33 @@ io.File tempExecutableScriptFile(String content, {Directory? tempDir}) { } /// Executes a script by first writing it as file and then running it as shell script +/// +/// Use [args] to pass arguments to the script +/// +/// Use [workingDirectory] to set the working directory of the script, default +/// to current working directory +/// +/// When [terminal] is `true` (default: `false`) Stdio handles are inherited by +/// the child process. This allows stdin to read by the script dcli.Progress writeAndRunShellScript( String scriptContent, { + List args = const [], Directory? workingDirectory, dcli.Progress? progress, + bool terminal = false, }) { final script = tempExecutableScriptFile(scriptContent); final Progress scriptProgress = progress ?? Progress(print, stderr: printerr, captureStderr: true); try { - return dcli.start( + return dcli.startFromArgs( script.absolute.path, + args, workingDirectory: workingDirectory?.absolute.path ?? entryWorkingDirectory.path, progress: scriptProgress, + terminal: terminal, ); } catch (e) { print( diff --git a/sidekick_core/lib/src/commands/bash_command.dart b/sidekick_core/lib/src/commands/bash_command.dart new file mode 100644 index 00000000..b2cb6335 --- /dev/null +++ b/sidekick_core/lib/src/commands/bash_command.dart @@ -0,0 +1,60 @@ +import 'dart:async'; + +import 'package:sidekick_core/sidekick_core.dart'; + +/// A Command that wraps a bash script +/// +/// Easy way to convert an existing bash script into a command for sidekick +/// +/// This makes it easy to handle paths within the bash script. You can define a +/// static [workingDirectory] and always know where the script is executed. +/// +/// Usage: +/// ```dart +/// runner +/// ..addCommand( +/// BashCommand( +/// name: 'test-bash-command', +/// description: 'Prints inputs of a sidekick BashCommand', +/// workingDirectory: runner.repository.root, +/// script: () => ''' +/// echo "arguments: \$@" +/// echo "workingDirectory: \$(pwd)" +/// # Access paths from sidekick +/// ${systemFlutterSdkPath()}/bin/flutter --version +/// ''', +/// ); +/// ``` +class BashCommand extends ForwardCommand { + BashCommand({ + required this.script, + required this.description, + required this.name, + this.workingDirectory, + }); + + @override + final String name; + + @override + final String description; + + /// The script to be executed. + /// + /// You may load this script from a file or generate it on the fly. + final FutureOr Function() script; + + /// The directory the bash script is running in. + final Directory? workingDirectory; + + @override + Future run() async { + final bashScript = await script(); + writeAndRunShellScript( + bashScript, + args: argResults!.arguments, + workingDirectory: workingDirectory, + terminal: true, + ); + } +} diff --git a/sidekick_core/lib/src/forward_command.dart b/sidekick_core/lib/src/forward_command.dart index 0fb912ad..bb8c69df 100644 --- a/sidekick_core/lib/src/forward_command.dart +++ b/sidekick_core/lib/src/forward_command.dart @@ -3,7 +3,7 @@ import 'package:args/command_runner.dart'; /// A [Command] which accepts all arguments and forwards everything to another cli app /// -/// Arguments to format are available via `argResults!.arguments` +/// Arguments are available via `argResults!.arguments`, not `argResults!.rest` abstract class ForwardCommand extends Command { ForwardCommand() { // recreate the _argParser and change it to allowAnything From 8ff18e2fe9bcf3638a9fd0cea63e36c3a3d56da5 Mon Sep 17 00:00:00 2001 From: Pascal Welsch Date: Sun, 8 Jan 2023 14:51:13 +0100 Subject: [PATCH 2/8] Example how to load from file --- .../lib/src/commands/bash_command.dart | 34 ++++++++++++++----- sk_sidekick/scripts/test-bash-command.sh | 0 2 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 sk_sidekick/scripts/test-bash-command.sh diff --git a/sidekick_core/lib/src/commands/bash_command.dart b/sidekick_core/lib/src/commands/bash_command.dart index b2cb6335..223bd385 100644 --- a/sidekick_core/lib/src/commands/bash_command.dart +++ b/sidekick_core/lib/src/commands/bash_command.dart @@ -9,21 +9,37 @@ import 'package:sidekick_core/sidekick_core.dart'; /// This makes it easy to handle paths within the bash script. You can define a /// static [workingDirectory] and always know where the script is executed. /// -/// Usage: +/// Usage as plain text /// ```dart /// runner -/// ..addCommand( -/// BashCommand( -/// name: 'test-bash-command', -/// description: 'Prints inputs of a sidekick BashCommand', -/// workingDirectory: runner.repository.root, -/// script: () => ''' +/// ..addCommand( +/// BashCommand( +/// name: 'test-bash-command', +/// description: 'Prints inputs of a sidekick BashCommand', +/// workingDirectory: runner.repository.root, +/// script: () => ''' /// echo "arguments: \$@" /// echo "workingDirectory: \$(pwd)" /// # Access paths from sidekick /// ${systemFlutterSdkPath()}/bin/flutter --version -/// ''', -/// ); +/// ''', +/// ), +/// ); +/// ``` +/// +/// Or load your script from a file +/// ```dart +/// runner +/// ..addCommand( +/// BashCommand( +/// name: 'test-bash-command', +/// description: 'Prints inputs of a sidekick BashCommand', +/// workingDirectory: runner.repository.root, +/// script: () => runner.repository.root +/// .file('scripts/test-bash-command.sh') +/// .readAsString(), +/// ), +/// ) /// ``` class BashCommand extends ForwardCommand { BashCommand({ diff --git a/sk_sidekick/scripts/test-bash-command.sh b/sk_sidekick/scripts/test-bash-command.sh new file mode 100644 index 00000000..e69de29b From 5dd4771c10e3e8451f239896088216735f389f28 Mon Sep 17 00:00:00 2001 From: Pascal Welsch Date: Sun, 8 Jan 2023 17:15:55 +0100 Subject: [PATCH 3/8] Add tests --- .../lib/src/commands/bash_command.dart | 6 +- sidekick_core/test/bash_command_test.dart | 80 +++++++++++++++++++ sk_sidekick/scripts/test-bash-command.sh | 0 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 sidekick_core/test/bash_command_test.dart delete mode 100644 sk_sidekick/scripts/test-bash-command.sh diff --git a/sidekick_core/lib/src/commands/bash_command.dart b/sidekick_core/lib/src/commands/bash_command.dart index 223bd385..352cc6dd 100644 --- a/sidekick_core/lib/src/commands/bash_command.dart +++ b/sidekick_core/lib/src/commands/bash_command.dart @@ -47,6 +47,7 @@ class BashCommand extends ForwardCommand { required this.description, required this.name, this.workingDirectory, + this.withStdIn = true, }); @override @@ -63,6 +64,9 @@ class BashCommand extends ForwardCommand { /// The directory the bash script is running in. final Directory? workingDirectory; + /// Whether to forward stdin to the bash script, default to true + final bool withStdIn; + @override Future run() async { final bashScript = await script(); @@ -70,7 +74,7 @@ class BashCommand extends ForwardCommand { bashScript, args: argResults!.arguments, workingDirectory: workingDirectory, - terminal: true, + terminal: withStdIn, ); } } diff --git a/sidekick_core/test/bash_command_test.dart b/sidekick_core/test/bash_command_test.dart new file mode 100644 index 00000000..faff9a6f --- /dev/null +++ b/sidekick_core/test/bash_command_test.dart @@ -0,0 +1,80 @@ +import 'package:sidekick_core/sidekick_core.dart'; +import 'package:sidekick_test/fake_stdio.dart'; +import 'package:sidekick_test/sidekick_test.dart'; +import 'package:test/test.dart'; + +void main() { + test('bash command receives arguments', () async { + await insideFakeProjectWithSidekick((dir) async { + final runner = initializeSidekick( + name: 'dash', + dartSdkPath: fakeDartSdk().path, + ); + runner.addCommand( + BashCommand( + script: () => 'echo \$@', + description: 'description', + name: 'script', + withStdIn: false, + ), + ); + final fakeStdOut = FakeStdoutStream(); + await overrideIoStreams( + stdout: () => fakeStdOut, + body: () => runner.run(['script', 'asdf', 'qwer']), + ); + + expect(fakeStdOut.lines, contains('asdf qwer')); + }); + }); + + test('workingDirectory default to cwd', () async { + await insideFakeProjectWithSidekick((dir) async { + final runner = initializeSidekick( + name: 'dash', + dartSdkPath: fakeDartSdk().path, + ); + runner.addCommand( + BashCommand( + script: () => 'echo \$PWD', + description: 'description', + name: 'script', + withStdIn: false, + ), + ); + final fakeStdOut = FakeStdoutStream(); + await overrideIoStreams( + stdout: () => fakeStdOut, + body: () => runner.run(['script']), + ); + + expect(fakeStdOut.lines.join(), endsWith(Directory.current.path)); + }); + }); + + test('workingDirectory can be set', () async { + await insideFakeProjectWithSidekick((dir) async { + final subDir = dir.directory('someSubDir')..createSync(); + final runner = initializeSidekick( + name: 'dash', + dartSdkPath: fakeDartSdk().path, + ); + runner.addCommand( + BashCommand( + script: () => 'echo \$PWD', + description: 'description', + name: 'script', + withStdIn: false, + workingDirectory: subDir, + ), + ); + final fakeStdOut = FakeStdoutStream(); + await overrideIoStreams( + stdout: () => fakeStdOut, + body: () => runner.run(['script']), + ); + + expect(fakeStdOut.lines.join(), endsWith(subDir.path)); + }); + }); +} diff --git a/sk_sidekick/scripts/test-bash-command.sh b/sk_sidekick/scripts/test-bash-command.sh deleted file mode 100644 index e69de29b..00000000 From 7c6dc2536096b4e2cc93a81b5525db6d04c04c17 Mon Sep 17 00:00:00 2001 From: Pascal Welsch Date: Mon, 9 Jan 2023 13:56:49 +0100 Subject: [PATCH 4/8] Default to withStdIn:false --- sidekick_core/lib/src/commands/bash_command.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sidekick_core/lib/src/commands/bash_command.dart b/sidekick_core/lib/src/commands/bash_command.dart index 352cc6dd..4aa6d42c 100644 --- a/sidekick_core/lib/src/commands/bash_command.dart +++ b/sidekick_core/lib/src/commands/bash_command.dart @@ -41,13 +41,16 @@ import 'package:sidekick_core/sidekick_core.dart'; /// ), /// ) /// ``` +/// +/// If your script is interactive, set [withStdIn] to `true` to allow stdin to +/// be connected to the script. class BashCommand extends ForwardCommand { BashCommand({ required this.script, required this.description, required this.name, this.workingDirectory, - this.withStdIn = true, + this.withStdIn = false, }); @override From a77e4b4dd6958c390c68aa1593da2095b63ec0ed Mon Sep 17 00:00:00 2001 From: Pascal Welsch Date: Mon, 9 Jan 2023 13:57:21 +0100 Subject: [PATCH 5/8] Make error message easier to understand --- .../lib/src/commands/bash_command.dart | 31 ++++++++++--- sidekick_core/test/bash_command_test.dart | 43 +++++++++++++++++-- 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/sidekick_core/lib/src/commands/bash_command.dart b/sidekick_core/lib/src/commands/bash_command.dart index 4aa6d42c..0fe9d17f 100644 --- a/sidekick_core/lib/src/commands/bash_command.dart +++ b/sidekick_core/lib/src/commands/bash_command.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:sidekick_core/sidekick_core.dart'; +import 'package:dcli/dcli.dart' as dcli; /// A Command that wraps a bash script /// @@ -73,11 +74,29 @@ class BashCommand extends ForwardCommand { @override Future run() async { final bashScript = await script(); - writeAndRunShellScript( - bashScript, - args: argResults!.arguments, - workingDirectory: workingDirectory, - terminal: withStdIn, - ); + + final scriptFile = tempExecutableScriptFile(bashScript); + final Progress progress = + Progress(print, stderr: printerr, captureStderr: true); + + try { + dcli.startFromArgs( + scriptFile.absolute.path, + argResults!.arguments, + workingDirectory: + workingDirectory?.absolute.path ?? entryWorkingDirectory.path, + progress: progress, + terminal: withStdIn, + ); + } catch (e) { + printerr( + "\nError executing script '$name' (exitCode=${progress.exitCode}):\n" + "$bashScript\n\n" + "Error executing script '$name' (exitCode=${progress.exitCode})", + ); + rethrow; + } finally { + scriptFile.deleteSync(recursive: true); + } } } diff --git a/sidekick_core/test/bash_command_test.dart b/sidekick_core/test/bash_command_test.dart index faff9a6f..7a947286 100644 --- a/sidekick_core/test/bash_command_test.dart +++ b/sidekick_core/test/bash_command_test.dart @@ -15,7 +15,6 @@ void main() { script: () => 'echo \$@', description: 'description', name: 'script', - withStdIn: false, ), ); final fakeStdOut = FakeStdoutStream(); @@ -39,7 +38,6 @@ void main() { script: () => 'echo \$PWD', description: 'description', name: 'script', - withStdIn: false, ), ); final fakeStdOut = FakeStdoutStream(); @@ -64,7 +62,6 @@ void main() { script: () => 'echo \$PWD', description: 'description', name: 'script', - withStdIn: false, workingDirectory: subDir, ), ); @@ -77,4 +74,44 @@ void main() { expect(fakeStdOut.lines.join(), endsWith(subDir.path)); }); }); + + test('print error code and script on error', () async { + await insideFakeProjectWithSidekick((dir) async { + final runner = initializeSidekick( + name: 'dash', + dartSdkPath: fakeDartSdk().path, + ); + runner.addCommand( + BashCommand( + script: () => '#scriptContent\nexit 34', + description: 'description', + name: 'script', + ), + ); + final fakeStdOut = FakeStdoutStream(); + final fakeStdErr = FakeStdoutStream(); + try { + await overrideIoStreams( + stdout: () => fakeStdOut, + stderr: () => fakeStdErr, + body: () => runner.run(['script']), + ); + fail('should throw'); + } catch (e) { + expect( + e, + isA().having((it) => it.exitCode, 'exitCode', 34), + ); + } + + expect(fakeStdErr.lines.join(), contains('exitCode=34')); + expect(fakeStdErr.lines.join(), contains('#scriptContent')); + expect(fakeStdErr.lines.join(), contains('exit 34')); + expect( + fakeStdErr.lines.join(), + contains("Error executing script 'script'"), + ); + expect(fakeStdOut.lines.join(), ""); + }); + }); } From 80bf080679058baff52d7506d8522293250d5686 Mon Sep 17 00:00:00 2001 From: Pascal Welsch Date: Tue, 10 Jan 2023 15:44:28 +0100 Subject: [PATCH 6/8] Throw BashCommandException --- .../lib/src/commands/bash_command.dart | 58 +++++++++++++++++-- sidekick_core/test/bash_command_test.dart | 17 +++--- 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/sidekick_core/lib/src/commands/bash_command.dart b/sidekick_core/lib/src/commands/bash_command.dart index 0fe9d17f..d643e5ee 100644 --- a/sidekick_core/lib/src/commands/bash_command.dart +++ b/sidekick_core/lib/src/commands/bash_command.dart @@ -88,15 +88,61 @@ class BashCommand extends ForwardCommand { progress: progress, terminal: withStdIn, ); - } catch (e) { - printerr( - "\nError executing script '$name' (exitCode=${progress.exitCode}):\n" - "$bashScript\n\n" - "Error executing script '$name' (exitCode=${progress.exitCode})", + } catch (e, stack) { + throw BashCommandException( + script: bashScript, + commandName: name, + arguments: argResults!.arguments, + exitCode: progress.exitCode!, + cause: e, + stack: stack, ); - rethrow; } finally { scriptFile.deleteSync(recursive: true); } } } + +/// Exception thrown when a [BashCommand] fails containing all the information +/// about the script and its error +class BashCommandException implements Exception { + /// The actual script content that was executed + final String script; + + /// The name of the command that executed this script + final String commandName; + + /// The arguments passed into the command + final List arguments; + + /// The exit code of the script that caused the error. (Always != `0`) + final int exitCode; + + /// The complete stacktrace, going into dcli which was ultimately executing this script + final StackTrace stack; + + /// The original exception from dcli + final Object? cause; + + const BashCommandException({ + required this.script, + required this.commandName, + required this.arguments, + required this.exitCode, + required this.stack, + required this.cause, + }); + + @override + String toString() { + String args = arguments.joinToString(); + if (args.isBlank) { + args = ''; + } + return "Error (exitCode=$exitCode) executing script of command '$commandName' " + "with arguments: $args\n\n" + "'''bash\n" + "${script.trimRight()}\n" + "'''\n\n"; + } +} diff --git a/sidekick_core/test/bash_command_test.dart b/sidekick_core/test/bash_command_test.dart index 7a947286..fb8aa629 100644 --- a/sidekick_core/test/bash_command_test.dart +++ b/sidekick_core/test/bash_command_test.dart @@ -100,18 +100,17 @@ void main() { } catch (e) { expect( e, - isA().having((it) => it.exitCode, 'exitCode', 34), + isA() + .having((it) => it.exitCode, 'exitCode', 34) + .having((it) => it.script, 'script', contains('#scriptContent')) + .having( + (it) => it.toString(), 'toString()', contains('exitCode=34')) + .having((it) => it.toString(), 'toString()', + contains('')), ); } - - expect(fakeStdErr.lines.join(), contains('exitCode=34')); - expect(fakeStdErr.lines.join(), contains('#scriptContent')); - expect(fakeStdErr.lines.join(), contains('exit 34')); - expect( - fakeStdErr.lines.join(), - contains("Error executing script 'script'"), - ); expect(fakeStdOut.lines.join(), ""); + expect(fakeStdErr.lines.join(), ""); }); }); } From 268729263b357d91ebef78f1a59a096021a3abd4 Mon Sep 17 00:00:00 2001 From: Pascal Welsch Date: Tue, 10 Jan 2023 15:48:29 +0100 Subject: [PATCH 7/8] Test arguments --- .../lib/src/commands/bash_command.dart | 8 ++- sidekick_core/test/bash_command_test.dart | 59 +++++++++++++++++-- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/sidekick_core/lib/src/commands/bash_command.dart b/sidekick_core/lib/src/commands/bash_command.dart index d643e5ee..52f3aaa7 100644 --- a/sidekick_core/lib/src/commands/bash_command.dart +++ b/sidekick_core/lib/src/commands/bash_command.dart @@ -1,7 +1,7 @@ import 'dart:async'; -import 'package:sidekick_core/sidekick_core.dart'; import 'package:dcli/dcli.dart' as dcli; +import 'package:sidekick_core/sidekick_core.dart'; /// A Command that wraps a bash script /// @@ -135,8 +135,10 @@ class BashCommandException implements Exception { @override String toString() { - String args = arguments.joinToString(); - if (args.isBlank) { + String args = arguments.joinToString(separator: ' '); + if (!args.isBlank) { + args = "($args)"; + } else { args = ''; } return "Error (exitCode=$exitCode) executing script of command '$commandName' " diff --git a/sidekick_core/test/bash_command_test.dart b/sidekick_core/test/bash_command_test.dart index fb8aa629..14f7e550 100644 --- a/sidekick_core/test/bash_command_test.dart +++ b/sidekick_core/test/bash_command_test.dart @@ -75,7 +75,7 @@ void main() { }); }); - test('print error code and script on error', () async { + test('throw BashCommandException on error', () async { await insideFakeProjectWithSidekick((dir) async { final runner = initializeSidekick( name: 'dash', @@ -104,9 +104,60 @@ void main() { .having((it) => it.exitCode, 'exitCode', 34) .having((it) => it.script, 'script', contains('#scriptContent')) .having( - (it) => it.toString(), 'toString()', contains('exitCode=34')) - .having((it) => it.toString(), 'toString()', - contains('')), + (it) => it.toString(), + 'toString()', + contains('exitCode=34'), + ) + .having( + (it) => it.toString(), + 'toString()', + contains(''), + ), + ); + } + expect(fakeStdOut.lines.join(), ""); + expect(fakeStdErr.lines.join(), ""); + }); + }); + + test('BashCommandException contains arguments', () async { + await insideFakeProjectWithSidekick((dir) async { + final runner = initializeSidekick( + name: 'dash', + dartSdkPath: fakeDartSdk().path, + ); + runner.addCommand( + BashCommand( + script: () => '#scriptContent\nexit 34', + description: 'description', + name: 'script', + ), + ); + final fakeStdOut = FakeStdoutStream(); + final fakeStdErr = FakeStdoutStream(); + try { + await overrideIoStreams( + stdout: () => fakeStdOut, + stderr: () => fakeStdErr, + body: () => runner.run(['script', 'asdf', 'qwer']), + ); + fail('should throw'); + } catch (e) { + expect( + e, + isA() + .having((it) => it.exitCode, 'exitCode', 34) + .having((it) => it.script, 'script', contains('#scriptContent')) + .having( + (it) => it.toString(), + 'toString()', + contains('exitCode=34'), + ) + .having( + (it) => it.toString(), + 'toString()', + contains('asdf qwer'), + ), ); } expect(fakeStdOut.lines.join(), ""); From 04aa41df6bb654d8427ed4fe8f007e5a11befdd4 Mon Sep 17 00:00:00 2001 From: Pascal Welsch Date: Tue, 10 Jan 2023 15:56:18 +0100 Subject: [PATCH 8/8] Test all exception properties --- .../lib/src/commands/bash_command.dart | 2 +- sidekick_core/test/bash_command_test.dart | 46 ++++++++----------- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/sidekick_core/lib/src/commands/bash_command.dart b/sidekick_core/lib/src/commands/bash_command.dart index 52f3aaa7..1f1820a4 100644 --- a/sidekick_core/lib/src/commands/bash_command.dart +++ b/sidekick_core/lib/src/commands/bash_command.dart @@ -122,7 +122,7 @@ class BashCommandException implements Exception { final StackTrace stack; /// The original exception from dcli - final Object? cause; + final Object cause; const BashCommandException({ required this.script, diff --git a/sidekick_core/test/bash_command_test.dart b/sidekick_core/test/bash_command_test.dart index 14f7e550..d07cd460 100644 --- a/sidekick_core/test/bash_command_test.dart +++ b/sidekick_core/test/bash_command_test.dart @@ -88,14 +88,8 @@ void main() { name: 'script', ), ); - final fakeStdOut = FakeStdoutStream(); - final fakeStdErr = FakeStdoutStream(); try { - await overrideIoStreams( - stdout: () => fakeStdOut, - stderr: () => fakeStdErr, - body: () => runner.run(['script']), - ); + await runner.run(['script']); fail('should throw'); } catch (e) { expect( @@ -103,6 +97,17 @@ void main() { isA() .having((it) => it.exitCode, 'exitCode', 34) .having((it) => it.script, 'script', contains('#scriptContent')) + .having((it) => it.commandName, 'commandName', 'script') + .having((it) => it.arguments, 'arguments', []) + .having((it) => it.cause, 'cause', isA()) + .having( + (it) => it.stack, + 'stack', + isA().having( + (it) => it.toString(), + 'toString', + contains('bash_command_test.dart'), + )) .having( (it) => it.toString(), 'toString()', @@ -115,8 +120,6 @@ void main() { ), ); } - expect(fakeStdOut.lines.join(), ""); - expect(fakeStdErr.lines.join(), ""); }); }); @@ -133,35 +136,22 @@ void main() { name: 'script', ), ); - final fakeStdOut = FakeStdoutStream(); - final fakeStdErr = FakeStdoutStream(); try { - await overrideIoStreams( - stdout: () => fakeStdOut, - stderr: () => fakeStdErr, - body: () => runner.run(['script', 'asdf', 'qwer']), - ); + await runner.run(['script', 'asdf', 'qwer']); fail('should throw'); } catch (e) { expect( e, isA() .having((it) => it.exitCode, 'exitCode', 34) - .having((it) => it.script, 'script', contains('#scriptContent')) - .having( - (it) => it.toString(), - 'toString()', - contains('exitCode=34'), - ) .having( - (it) => it.toString(), - 'toString()', - contains('asdf qwer'), - ), + (it) => it.arguments, 'arguments', ['asdf', 'qwer']).having( + (it) => it.toString(), + 'toString()', + contains('asdf qwer'), + ), ); } - expect(fakeStdOut.lines.join(), ""); - expect(fakeStdErr.lines.join(), ""); }); }); }