From 394eda75bd51a25992782105b571938623b12d8f Mon Sep 17 00:00:00 2001 From: Jochum van der Ploeg Date: Fri, 20 Dec 2024 17:33:34 +0100 Subject: [PATCH] feat(dart_frog_cli): allow pass through of arguments (#1630) Co-authored-by: Alejandro Santiago Co-authored-by: Tom Arra --- docs/docs/overview.md | 4 +-- .../lib/src/commands/dev/dev.dart | 2 +- .../dev_server_runner/dev_server_runner.dart | 20 ++++++++++-- .../test/src/commands/dev/dev_test.dart | 31 +++++++++---------- 4 files changed, 35 insertions(+), 22 deletions(-) diff --git a/docs/docs/overview.md b/docs/docs/overview.md index 6ad83add6..e96a5cbcd 100644 --- a/docs/docs/overview.md +++ b/docs/docs/overview.md @@ -53,8 +53,8 @@ To customize the running dev server, you can use the following options: - `--port` - The port to run the dev server on. Defaults to `8080`. - `--dart-vm-service-port` - The port to run the Dart VM service on. Defaults to `8181`. This is required when trying to run multiple dev servers simultaneously on the same host. - `--host` - The host to run the dev server on. Defaults to `localhost`. - -::: + To customize it further, a `--` signals the **end of options** and disables further option processing from `dart_frog dev`. Any arguments after the `--` are passed into the [Dart tool](https://dart.dev/tools/dart-tool) process. For example, you could use the `--` to enable [experimental flags](https://dart.dev/tools/experiment-flags) such as macros by doing `dart_frog dev -- --enable-experiment=macros`. + ::: :::caution Each release of the `dart_frog_cli` supports a specific version range of the `dart_frog` runtime. If the current version of the `dart_frog` runtime is incompatible with the installed `dart_frog_cli` version, an error will be reported and you will need to update your `dart_frog_cli` version or `dart_frog` version accordingly. diff --git a/packages/dart_frog_cli/lib/src/commands/dev/dev.dart b/packages/dart_frog_cli/lib/src/commands/dev/dev.dart index 80f60cd90..fc3aa6c8d 100644 --- a/packages/dart_frog_cli/lib/src/commands/dev/dev.dart +++ b/packages/dart_frog_cli/lib/src/commands/dev/dev.dart @@ -131,7 +131,7 @@ class DevCommand extends DartFrogCommand { ); try { - await _devServerRunner.start(); + await _devServerRunner.start(results.rest); return (await _devServerRunner.exitCode).code; } catch (e) { logger.err(e.toString()); diff --git a/packages/dart_frog_cli/lib/src/dev_server_runner/dev_server_runner.dart b/packages/dart_frog_cli/lib/src/dev_server_runner/dev_server_runner.dart index a31000b26..313c9cad2 100644 --- a/packages/dart_frog_cli/lib/src/dev_server_runner/dev_server_runner.dart +++ b/packages/dart_frog_cli/lib/src/dev_server_runner/dev_server_runner.dart @@ -233,7 +233,16 @@ class DevServerRunner { /// /// This method will throw a [DartFrogDevServerException] if called after /// [stop] has been called. - Future start() async { + /// + /// The [arguments] are optional and usually expected to be those from + /// `ArgResults.rest`; since a `--` signals the **end of options** and + /// disables further option processing from `dart_frog dev`. Any [arguments] + /// after the `--` are passed into the [Dart tool](https://dart.dev/tools/dart-tool) + /// process. + /// + /// For example, you could use the `--` to enable [experimental flags](https://dart.dev/tools/experiment-flags) + /// such as macros by doing `dart_frog dev -- --enable-experiment=macros`. + Future start([List arguments = const []]) async { if (isCompleted) { throw DartFrogDevServerException( 'Cannot start a dev server after it has been stopped.', @@ -258,12 +267,17 @@ class DevServerRunner { ); logger.detail( - '''[process] dart $enableVmServiceFlag $serverDartFilePath''', + '''[process] dart $enableVmServiceFlag $serverDartFilePath ${arguments.join(' ')}''', ); final process = _serverProcess = await _startProcess( 'dart', - [enableVmServiceFlag, '--enable-asserts', serverDartFilePath], + [ + enableVmServiceFlag, + '--enable-asserts', + ...arguments, + serverDartFilePath, + ], runInShell: true, ); diff --git a/packages/dart_frog_cli/test/src/commands/dev/dev_test.dart b/packages/dart_frog_cli/test/src/commands/dev/dev_test.dart index 8600435d2..0edfe8b56 100644 --- a/packages/dart_frog_cli/test/src/commands/dev/dev_test.dart +++ b/packages/dart_frog_cli/test/src/commands/dev/dev_test.dart @@ -36,6 +36,7 @@ void main() { when(() => argResults['port']).thenReturn('8080'); when(() => argResults['dart-vm-service-port']) .thenReturn('8181'); + when(() => argResults.rest).thenReturn(['--enable-experiment=macros']); when(() => stdin.hasTerminal).thenReturn(false); }); @@ -45,7 +46,7 @@ void main() { }); test('run the dev server with the given parameters', () async { - when(() => runner.start()).thenAnswer((_) => Future.value()); + when(() => runner.start(any())).thenAnswer((_) => Future.value()); when(() => runner.exitCode).thenAnswer( (_) => Future.value(ExitCode.success), ); @@ -53,6 +54,7 @@ void main() { when(() => argResults['hostname']).thenReturn('192.168.1.2'); when(() => argResults['port']).thenReturn('1234'); when(() => argResults['dart-vm-service-port']).thenReturn('5678'); + when(() => argResults.rest).thenReturn(['--enable-experiment=macros']); final cwd = Directory.systemTemp; @@ -90,7 +92,9 @@ void main() { await expectLater(command.run(), completion(ExitCode.success.code)); - verify(() => runner.start()).called(1); + verify( + () => runner.start(any(that: equals(['--enable-experiment=macros']))), + ).called(1); expect(givenPort, equals('1234')); expect(givenAddress, InternetAddress.tryParse('192.168.1.2')); @@ -119,12 +123,7 @@ void main() { ..testArgResults = argResults ..testStdin = stdin; - when(() => runner.start()).thenAnswer((_) => Future.value()); - when(() => runner.exitCode).thenAnswer( - (_) => Future.value(ExitCode.success), - ); - - when(() => runner.start()).thenAnswer((_) => Future.value()); + when(() => runner.start(any())).thenAnswer((_) => Future.value()); when(() => runner.exitCode).thenAnswer((_) async => ExitCode.unavailable); await expectLater(command.run(), completion(ExitCode.unavailable.code)); @@ -149,7 +148,7 @@ void main() { ..testArgResults = argResults ..testStdin = stdin; - when(() => runner.start()).thenAnswer((_) async { + when(() => runner.start(any())).thenAnswer((_) async { throw DartFrogDevServerException('oops'); }); @@ -158,7 +157,7 @@ void main() { }); test('fails if hostname is invalid', () async { - when(() => runner.start()).thenAnswer((_) => Future.value()); + when(() => runner.start(any())).thenAnswer((_) => Future.value()); when(() => runner.exitCode).thenAnswer( (_) => Future.value(ExitCode.success), ); @@ -196,7 +195,7 @@ void main() { ), ).called(1); - verifyNever(() => runner.start()); + verifyNever(() => runner.start(any())); }); group('listening to stdin', () { @@ -233,7 +232,7 @@ void main() { ), ); - when(() => runner.start()).thenAnswer((_) => Future.value()); + when(() => runner.start(any())).thenAnswer((_) => Future.value()); when(() => runner.reload()).thenAnswer((_) => Future.value()); when(() => runner.exitCode).thenAnswer( @@ -332,9 +331,9 @@ void main() { }); test('cancels subscription when dev server throws', () async { - final startComplter = Completer(); - when(() => runner.start()).thenAnswer((_) async { - await startComplter.future; + final startCompleter = Completer(); + when(() => runner.start(any())).thenAnswer((_) async { + await startCompleter.future; }); command.run().ignore(); @@ -347,7 +346,7 @@ void main() { verify(() => stdin.echoMode = false).called(1); verify(() => stdin.lineMode = false).called(1); - startComplter.completeError(Exception('oops')); + startCompleter.completeError(Exception('oops')); await Future.delayed(Duration.zero); expect(stdinController.hasListener, isFalse);