From b6d69dfee8efe5dcdc304400d631c7fbffd877c0 Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Wed, 31 May 2023 11:26:29 -0400 Subject: [PATCH] feat(shorebird_cli): recognize flavors in Flutter modules --- .../lib/src/shorebird_flavor_mixin.dart | 17 ++++++- .../test/src/commands/init_command_test.dart | 48 ++++++++++++++++--- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/packages/shorebird_cli/lib/src/shorebird_flavor_mixin.dart b/packages/shorebird_cli/lib/src/shorebird_flavor_mixin.dart index e510754af..c63febbf8 100644 --- a/packages/shorebird_cli/lib/src/shorebird_flavor_mixin.dart +++ b/packages/shorebird_cli/lib/src/shorebird_flavor_mixin.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:collection/collection.dart'; import 'package:path/path.dart' as p; import 'package:platform/platform.dart'; @@ -12,13 +14,24 @@ mixin ShorebirdFlavorMixin on ShorebirdJavaMixin { String appRoot, { Platform platform = const LocalPlatform(), }) async { + // Flutter apps have android files in root/android + // Flutter modules have android files in root/.android + final androidRoot = [ + Directory(p.join(appRoot, 'android')), + Directory(p.join(appRoot, '.android')), + ].firstWhereOrNull((dir) => dir.existsSync()); + + if (androidRoot == null) { + return {}; + } + final executable = platform.isWindows ? 'gradlew.bat' : 'gradlew'; final javaHome = getJavaHome(platform); final result = await process.run( - p.join(appRoot, 'android', executable), + p.join(androidRoot.path, executable), ['app:tasks', '--all', '--console=auto'], runInShell: true, - workingDirectory: p.join(appRoot, 'android'), + workingDirectory: androidRoot.path, environment: { if (javaHome != null) 'JAVA_HOME': javaHome, }, 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 fce7b4a3b..1d4acf57b 100644 --- a/packages/shorebird_cli/test/src/commands/init_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/init_command_test.dart @@ -53,6 +53,18 @@ environment: late Progress progress; late InitCommand command; + Directory setUpAppTempDir() { + final tempDir = Directory.systemTemp.createTempSync(); + Directory(p.join(tempDir.path, 'android')).createSync(recursive: true); + return tempDir; + } + + Directory setUpModuleTempDir() { + final tempDir = Directory.systemTemp.createTempSync(); + Directory(p.join(tempDir.path, '.android')).createSync(recursive: true); + return tempDir; + } + setUp(() { httpClient = _MockHttpClient(); argResults = _MockArgResults(); @@ -108,7 +120,7 @@ environment: when(() => platform.isLinux).thenReturn(true); when(() => platform.isMacOS).thenReturn(false); when(() => platform.isWindows).thenReturn(false); - final tempDir = Directory.systemTemp.createTempSync(); + final tempDir = setUpAppTempDir(); const javaHome = 'test_java_home'; when(() => platform.environment).thenReturn({'JAVA_HOME': javaHome}); await expectLater( @@ -125,12 +137,13 @@ environment: ), ).called(1); }); + test('uses correct executable on windows', () async { final platform = _MockPlatform(); when(() => platform.isWindows).thenReturn(true); when(() => platform.isMacOS).thenReturn(false); when(() => platform.isLinux).thenReturn(false); - final tempDir = Directory.systemTemp.createTempSync(); + final tempDir = setUpAppTempDir(); when(() => platform.environment).thenReturn({ 'PROGRAMFILES': tempDir.path, 'PROGRAMFILES(X86)': tempDir.path, @@ -163,7 +176,7 @@ environment: when(() => platform.isWindows).thenReturn(false); when(() => platform.isMacOS).thenReturn(true); when(() => platform.isLinux).thenReturn(false); - final tempDir = Directory.systemTemp.createTempSync(); + final tempDir = setUpAppTempDir(); when(() => platform.environment).thenReturn({'HOME': tempDir.path}); final androidStudioDir = Directory( p.join( @@ -199,7 +212,7 @@ environment: when(() => platform.isWindows).thenReturn(false); when(() => platform.isMacOS).thenReturn(false); when(() => platform.isLinux).thenReturn(true); - final tempDir = Directory.systemTemp.createTempSync(); + final tempDir = setUpAppTempDir(); when(() => platform.environment).thenReturn({'HOME': tempDir.path}); final androidStudioDir = Directory( p.join(tempDir.path, '.AndroidStudio'), @@ -223,6 +236,29 @@ environment: ), ).called(1); }); + + test('extracts flavors from module directory structure', () async { + final platform = _MockPlatform(); + when(() => platform.isLinux).thenReturn(true); + when(() => platform.isMacOS).thenReturn(false); + when(() => platform.isWindows).thenReturn(false); + final tempDir = setUpModuleTempDir(); + 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('returns no user error when not logged in', () async { @@ -314,7 +350,7 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''', when(() => result.exitCode).thenReturn(1); when(() => result.stdout).thenReturn('error'); when(() => result.stderr).thenReturn('oops'); - final tempDir = Directory.systemTemp.createTempSync(); + final tempDir = setUpAppTempDir(); File( p.join(tempDir.path, 'pubspec.yaml'), ).writeAsStringSync(pubspecYamlContent); @@ -389,7 +425,7 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''', p.join('test', 'fixtures', 'gradle_app_tasks.txt'), ).readAsStringSync(), ); - final tempDir = Directory.systemTemp.createTempSync(); + final tempDir = setUpAppTempDir(); File( p.join(tempDir.path, 'pubspec.yaml'), ).writeAsStringSync(pubspecYamlContent);