From 2e3bc6dfef26cf6cf9fda2c4aeff7015656358f0 Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Tue, 30 Dec 2025 11:03:00 -0500 Subject: [PATCH] fix(shorebird_cli): check logged in before shorebird create (#3447) --- .../lib/src/commands/create_command.dart | 16 ++++++- .../src/commands/create_command_test.dart | 42 ++++++++++++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/packages/shorebird_cli/lib/src/commands/create_command.dart b/packages/shorebird_cli/lib/src/commands/create_command.dart index 3f1e3e0b..eb7d0802 100644 --- a/packages/shorebird_cli/lib/src/commands/create_command.dart +++ b/packages/shorebird_cli/lib/src/commands/create_command.dart @@ -6,6 +6,7 @@ import 'package:scoped_deps/scoped_deps.dart'; import 'package:shorebird_cli/src/shorebird_command.dart'; import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:shorebird_cli/src/shorebird_process.dart'; +import 'package:shorebird_cli/src/shorebird_validator.dart'; /// {@template shorebird_create_command} /// `shorebird create` @@ -20,14 +21,27 @@ class CreateCommand extends ShorebirdProxyCommand { @override Future run() async { + try { + await shorebirdValidator.validatePreconditions( + checkUserIsAuthenticated: true, + ); + } on PreconditionFailedException catch (e) { + return e.exitCode.code; + } + final createExitCode = await process.stream('flutter', [ 'create', ...results.rest, ]); - if (createExitCode != ExitCode.success.code) return createExitCode; + + if (createExitCode != ExitCode.success.code) { + return createExitCode; + } + if (results.rest.contains('-h') || results.rest.contains('--help')) { return createExitCode; } + return runScoped( () => runner!.run(['init']), values: { diff --git a/packages/shorebird_cli/test/src/commands/create_command_test.dart b/packages/shorebird_cli/test/src/commands/create_command_test.dart index 77e3cdba..b31c954d 100644 --- a/packages/shorebird_cli/test/src/commands/create_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/create_command_test.dart @@ -7,6 +7,7 @@ import 'package:shorebird_cli/src/commands/commands.dart'; import 'package:shorebird_cli/src/shorebird_cli_command_runner.dart'; import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:shorebird_cli/src/shorebird_process.dart'; +import 'package:shorebird_cli/src/shorebird_validator.dart'; import 'package:test/test.dart'; import '../mocks.dart'; @@ -17,27 +18,43 @@ void main() { late ShorebirdProcess process; late ArgResults argResults; late ShorebirdCliCommandRunner runner; + late ShorebirdValidator shorebirdValidator; late CreateCommand command; R runWithOverrides(R Function() body) { - return runScoped(body, values: {processRef.overrideWith(() => process)}); + return runScoped( + body, + values: { + processRef.overrideWith(() => process), + shorebirdValidatorRef.overrideWith(() => shorebirdValidator), + }, + ); } setUp(() { argResults = MockArgResults(); process = MockShorebirdProcess(); runner = MockShorebirdCliCommandRunner(); + shorebirdValidator = MockShorebirdValidator(); command = runWithOverrides(CreateCommand.new) ..testArgResults = argResults ..testRunner = runner; when(() => argResults.rest).thenReturn(args); + when( () => runner.run(any()), ).thenAnswer((_) async => ExitCode.success.code); + when( () => process.stream('flutter', ['create', ...args]), ).thenAnswer((_) async => ExitCode.success.code); + + when( + () => shorebirdValidator.validatePreconditions( + checkUserIsAuthenticated: true, + ), + ).thenAnswer((_) async {}); }); test('has correct name and description', () { @@ -57,6 +74,29 @@ void main() { verify(() => process.stream('flutter', ['create', ...args])).called(1); }); + group('when validation fails', () { + setUp(() { + when( + () => shorebirdValidator.validatePreconditions( + checkUserIsAuthenticated: true, + ), + ).thenThrow(ValidationFailedException()); + }); + + test('exits with code 70', () async { + await expectLater( + runWithOverrides(command.run), + completion(equals(ExitCode.config.code)), + ); + + verify( + () => shorebirdValidator.validatePreconditions( + checkUserIsAuthenticated: true, + ), + ).called(1); + }); + }); + test('runs the shorebird init command', () async { when(() => runner.run(any())).thenAnswer((invocation) async { final runnerArgs = invocation.positionalArguments.first as List;