diff --git a/packages/shorebird_cli/lib/src/commands/init_command.dart b/packages/shorebird_cli/lib/src/commands/init_command.dart index ea47f963..8786ffdb 100644 --- a/packages/shorebird_cli/lib/src/commands/init_command.dart +++ b/packages/shorebird_cli/lib/src/commands/init_command.dart @@ -66,12 +66,11 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".'''); return ExitCode.software.code; } - final Set productFlavors; + var productFlavors = {}; try { productFlavors = await extractProductFlavors(Directory.current.path); } catch (error) { - logger.err('$error'); - return ExitCode.software.code; + logger.detail('Unable to extract product flavors: $error'); } final String appId; diff --git a/packages/shorebird_cli/lib/src/shorebird_flavor_mixin.dart b/packages/shorebird_cli/lib/src/shorebird_flavor_mixin.dart index df18f66b..89eeec0d 100644 --- a/packages/shorebird_cli/lib/src/shorebird_flavor_mixin.dart +++ b/packages/shorebird_cli/lib/src/shorebird_flavor_mixin.dart @@ -8,22 +8,19 @@ import 'package:shorebird_cli/src/command.dart'; /// Mixin on [ShorebirdCommand] which exposes methods for extracting /// product flavors from the current app. mixin ShorebirdFlavorMixin on ShorebirdCommand { - /// Return the set of product flavors configured for the app at [path]. + /// Return the set of product flavors configured for the app at [appRoot]. /// Returns an empty set for apps that do not use product flavors. Future> extractProductFlavors( - String path, { + String appRoot, { Platform platform = const LocalPlatform(), }) async { final executable = platform.isWindows ? 'gradlew.bat' : 'gradlew'; - final androidStudioPath = _getAndroidStudioPath(platform); - final javaPath = androidStudioPath != null - ? _getJavaPath(androidStudioPath, platform) - : null; + final javaPath = _getJavaPath(platform); final result = await process.run( - p.join(path, 'android', executable), + p.join(appRoot, 'android', executable), ['app:tasks', '--all', '--console=auto'], runInShell: true, - workingDirectory: p.join(path, 'android'), + workingDirectory: p.join(appRoot, 'android'), environment: { if (javaPath != null) 'JAVA_HOME': javaPath, }, @@ -86,6 +83,8 @@ mixin ShorebirdFlavorMixin on ShorebirdCommand { if (platform.isLinux) { final candidateLocations = [ + p.join('/', 'snap', 'bin', 'android-studio'), + p.join('/', 'opt', 'android-studio'), p.join(home, '.AndroidStudio'), p.join(home, '.cache', 'Google', 'AndroidStudio'), ]; @@ -97,12 +96,18 @@ mixin ShorebirdFlavorMixin on ShorebirdCommand { return null; } - String? _getJavaPath(String directory, Platform platform) { + String? _getJavaPath(Platform platform) { + if (platform.environment.containsKey('JAVA_HOME')) { + return platform.environment['JAVA_HOME']; + } + + final androidStudioPath = _getAndroidStudioPath(platform); + if (androidStudioPath == null) return null; if (platform.isMacOS) { final candidateLocations = [ - p.join(directory, 'jbr', 'Contents', 'Home'), - p.join(directory, 'jre', 'Contents', 'Home'), - p.join(directory, 'jre', 'jdk', 'Contents', 'Home') + p.join(androidStudioPath, 'jbr', 'Contents', 'Home'), + p.join(androidStudioPath, 'jre', 'Contents', 'Home'), + p.join(androidStudioPath, 'jre', 'jdk', 'Contents', 'Home') ]; return candidateLocations.firstWhereOrNull( @@ -111,8 +116,8 @@ mixin ShorebirdFlavorMixin on ShorebirdCommand { } final candidateLocations = [ - p.join(directory, 'jbr'), - p.join(directory, 'jre'), + p.join(androidStudioPath, 'jbr'), + p.join(androidStudioPath, 'jre'), ]; return candidateLocations.firstWhereOrNull( diff --git a/packages/shorebird_cli/test/src/commands/init_command_test.dart b/packages/shorebird_cli/test/src/commands/init_command_test.dart index 51497dd2..67b4eb71 100644 --- a/packages/shorebird_cli/test/src/commands/init_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/init_command_test.dart @@ -98,6 +98,28 @@ environment: }); group('extractProductFlavors', () { + test('uses existing JAVA_HOME when set', () async { + final platform = _MockPlatform(); + when(() => platform.isLinux).thenReturn(true); + when(() => platform.isMacOS).thenReturn(false); + when(() => platform.isWindows).thenReturn(false); + final tempDir = Directory.systemTemp.createTempSync(); + const javaHome = 'test_java_home'; + when(() => platform.environment).thenReturn({'JAVA_HOME': javaHome}); + await expectLater( + command.extractProductFlavors(tempDir.path, platform: platform), + completes, + ); + verify( + () => process.run( + p.join(tempDir.path, 'android', 'gradlew'), + ['app:tasks', '--all', '--console=auto'], + runInShell: true, + workingDirectory: p.join(tempDir.path, 'android'), + environment: {'JAVA_HOME': javaHome}, + ), + ).called(1); + }); test('uses correct executable on windows', () async { final platform = _MockPlatform(); when(() => platform.isWindows).thenReturn(true); @@ -281,7 +303,9 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''', ); }); - test('throws when extracting flavors throws', () async { + test( + 'proceeds without flavors ' + 'when an error occurs while extracting flavors', () async { when(() => result.exitCode).thenReturn(1); when(() => result.stdout).thenReturn('error'); when(() => result.stderr).thenReturn('oops'); @@ -293,8 +317,12 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''', command.run, getCurrentDirectory: () => tempDir, ); - verify(() => logger.err('Exception: error\noops')).called(1); - expect(exitCode, ExitCode.software.code); + verify( + () => logger.detail( + 'Unable to extract product flavors: Exception: error\noops', + ), + ).called(1); + expect(exitCode, ExitCode.success.code); }); test('throws software error when error occurs creating app.', () async {