From 7a5551cad7cc06f601ac3486db6e032d9e9ed061 Mon Sep 17 00:00:00 2001 From: Felix Angelov Date: Fri, 11 Aug 2023 12:08:07 -0500 Subject: [PATCH] feat(shorebird_cli): `shorebird doctor -v` outputs android tooling info --- .../lib/src/commands/doctor_command.dart | 44 +++++++++--- .../src/commands/doctor_command_test.dart | 70 ++++++++++++++++++- 2 files changed, 104 insertions(+), 10 deletions(-) diff --git a/packages/shorebird_cli/lib/src/commands/doctor_command.dart b/packages/shorebird_cli/lib/src/commands/doctor_command.dart index 3a85ed57e..4752ad93c 100644 --- a/packages/shorebird_cli/lib/src/commands/doctor_command.dart +++ b/packages/shorebird_cli/lib/src/commands/doctor_command.dart @@ -1,6 +1,9 @@ import 'package:mason_logger/mason_logger.dart'; +import 'package:shorebird_cli/src/android_sdk.dart'; +import 'package:shorebird_cli/src/android_studio.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/doctor.dart'; +import 'package:shorebird_cli/src/java.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:shorebird_cli/src/shorebird_flutter.dart'; @@ -14,12 +17,19 @@ import 'package:shorebird_cli/src/version.dart'; class DoctorCommand extends ShorebirdCommand { /// {@macro doctor_command} DoctorCommand() { - argParser.addFlag( - 'fix', - abbr: 'f', - help: 'Fix issues where possible.', - negatable: false, - ); + argParser + ..addFlag( + 'fix', + abbr: 'f', + help: 'Fix issues where possible.', + negatable: false, + ) + ..addFlag( + 'verbose', + abbr: 'v', + help: 'Enable verbose output.', + negatable: false, + ); } @override @@ -30,17 +40,33 @@ class DoctorCommand extends ShorebirdCommand { @override Future run() async { + final verbose = results['verbose'] == true; final shouldFix = results['fix'] == true; final flutterVersion = await _tryGetFlutterVersion(); + final output = StringBuffer(); final shorebirdFlutterPrefix = StringBuffer('Flutter'); if (flutterVersion != null) { shorebirdFlutterPrefix.write(' $flutterVersion'); } - logger.info(''' + output.writeln( + ''' Shorebird $packageVersion • git@github.com:shorebirdtech/shorebird.git $shorebirdFlutterPrefix • revision ${shorebirdEnv.flutterRevision} -Engine • revision ${shorebirdEnv.shorebirdEngineRevision} -'''); +Engine • revision ${shorebirdEnv.shorebirdEngineRevision}''', + ); + + if (verbose) { + const notDetected = 'not detected'; + output.writeln(''' + +Android Toolchain + • Android Studio: ${androidStudio.path ?? notDetected} + • Android SDK: ${androidSdk.path ?? notDetected} + • ADB: ${androidSdk.adbPath ?? notDetected} + • JAVA_HOME: ${java.home ?? notDetected}'''); + } + + logger.info(output.toString()); await doctor.runValidators(doctor.allValidators, applyFixes: shouldFix); diff --git a/packages/shorebird_cli/test/src/commands/doctor_command_test.dart b/packages/shorebird_cli/test/src/commands/doctor_command_test.dart index e2fef7018..d09ce2d24 100644 --- a/packages/shorebird_cli/test/src/commands/doctor_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/doctor_command_test.dart @@ -2,8 +2,11 @@ import 'package:args/args.dart'; import 'package:mason_logger/mason_logger.dart'; import 'package:mocktail/mocktail.dart'; import 'package:scoped/scoped.dart'; +import 'package:shorebird_cli/src/android_sdk.dart'; +import 'package:shorebird_cli/src/android_studio.dart'; import 'package:shorebird_cli/src/commands/commands.dart'; import 'package:shorebird_cli/src/doctor.dart'; +import 'package:shorebird_cli/src/java.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:shorebird_cli/src/shorebird_flutter.dart'; @@ -13,8 +16,14 @@ import 'package:test/test.dart'; class _MockArgResults extends Mock implements ArgResults {} +class _MockAndroidStudio extends Mock implements AndroidStudio {} + +class _MockAndroidSdk extends Mock implements AndroidSdk {} + class _MockDoctor extends Mock implements Doctor {} +class _MockJava extends Mock implements Java {} + class _MockLogger extends Mock implements Logger {} class _MockShorebirdEnv extends Mock implements ShorebirdEnv {} @@ -29,18 +38,24 @@ void main() { const shorebirdFlutterRevision = 'test-flutter-revision'; late ArgResults argResults; + late AndroidStudio androidStudio; + late AndroidSdk androidSdk; late Doctor doctor; - late DoctorCommand command; + late Java java; late Logger logger; late ShorebirdEnv shorebirdEnv; late ShorebirdFlutter shorebirdFlutter; late Validator validator; + late DoctorCommand command; R runWithOverrides(R Function() body) { return runScoped( body, values: { + androidStudioRef.overrideWith(() => androidStudio), + androidSdkRef.overrideWith(() => androidSdk), doctorRef.overrideWith(() => doctor), + javaRef.overrideWith(() => java), loggerRef.overrideWith(() => logger), shorebirdEnvRef.overrideWith(() => shorebirdEnv), shorebirdFlutterRef.overrideWith(() => shorebirdFlutter), @@ -50,12 +65,21 @@ void main() { setUp(() { argResults = _MockArgResults(); + androidStudio = _MockAndroidStudio(); + androidSdk = _MockAndroidSdk(); doctor = _MockDoctor(); + java = _MockJava(); logger = _MockLogger(); shorebirdEnv = _MockShorebirdEnv(); shorebirdFlutter = _MockShorebirdFlutter(); validator = _MockValidator(); + when(() => argResults['verbose']).thenReturn(false); + when(() => argResults['fix']).thenReturn(false); + when(() => androidStudio.path).thenReturn(null); + when(() => androidSdk.path).thenReturn(null); + when(() => androidSdk.adbPath).thenReturn(null); + when(() => java.home).thenReturn(null); when( () => shorebirdEnv.shorebirdEngineRevision, ).thenReturn(shorebirdEngineRevision); @@ -105,6 +129,50 @@ Engine • revision $shorebirdEngineRevision ).called(1); }); + group('--verbose', () { + test('prints additional information (not detected)', () async { + when(() => argResults['verbose']).thenReturn(true); + await runWithOverrides(command.run); + + verify( + () => logger.info(''' + +Shorebird v$packageVersion • git@github.com:shorebirdtech/shorebird.git +Flutter • revision ${shorebirdEnv.flutterRevision} +Engine • revision $shorebirdEngineRevision + +Android Toolchain + • Android Studio: not detected + • Android SDK: not detected + • ADB: not detected + • JAVA_HOME: not detected'''), + ).called(1); + }); + + test('prints additional information (detected)', () async { + when(() => argResults['verbose']).thenReturn(true); + when(() => androidStudio.path).thenReturn('test-studio-path'); + when(() => androidSdk.path).thenReturn('test-sdk-path'); + when(() => androidSdk.adbPath).thenReturn('test-adb-path'); + when(() => java.home).thenReturn('test-java-home'); + await runWithOverrides(command.run); + + verify( + () => logger.info(''' + +Shorebird v$packageVersion • git@github.com:shorebirdtech/shorebird.git +Flutter • revision ${shorebirdEnv.flutterRevision} +Engine • revision $shorebirdEngineRevision + +Android Toolchain + • Android Studio: test-studio-path + • Android SDK: test-sdk-path + • ADB: test-adb-path + • JAVA_HOME: test-java-home'''), + ).called(1); + }); + }); + test('runs validators without applying fixes if no fix flag exists', () async { when(() => argResults['fix']).thenReturn(null);