Unverified Commit a15a81be authored by Emmanuel Garcia's avatar Emmanuel Garcia Committed by GitHub

Fix androidSdk NPE (#47187)

parent 1cdf0f44
...@@ -86,7 +86,7 @@ class _AndroidBuilderImpl extends AndroidBuilder { ...@@ -86,7 +86,7 @@ class _AndroidBuilderImpl extends AndroidBuilder {
buildNumber: buildNumber, buildNumber: buildNumber,
); );
} finally { } finally {
androidSdk.reinitialize(); androidSdk?.reinitialize();
} }
} }
...@@ -106,7 +106,7 @@ class _AndroidBuilderImpl extends AndroidBuilder { ...@@ -106,7 +106,7 @@ class _AndroidBuilderImpl extends AndroidBuilder {
localGradleErrors: gradleErrors, localGradleErrors: gradleErrors,
); );
} finally { } finally {
androidSdk.reinitialize(); androidSdk?.reinitialize();
} }
} }
...@@ -126,7 +126,7 @@ class _AndroidBuilderImpl extends AndroidBuilder { ...@@ -126,7 +126,7 @@ class _AndroidBuilderImpl extends AndroidBuilder {
localGradleErrors: gradleErrors, localGradleErrors: gradleErrors,
); );
} finally { } finally {
androidSdk.reinitialize(); androidSdk?.reinitialize();
} }
} }
} }
...@@ -55,7 +55,7 @@ String getAdbPath([ AndroidSdk existingSdk ]) { ...@@ -55,7 +55,7 @@ String getAdbPath([ AndroidSdk existingSdk ]) {
if (sdk?.latestVersion == null) { if (sdk?.latestVersion == null) {
return os.which('adb')?.path; return os.which('adb')?.path;
} else { } else {
return sdk.adbPath; return sdk?.adbPath;
} }
} }
......
...@@ -149,7 +149,7 @@ Future<void> checkGradleDependencies() async { ...@@ -149,7 +149,7 @@ Future<void> checkGradleDependencies() async {
workingDirectory: flutterProject.android.hostAppGradleRoot.path, workingDirectory: flutterProject.android.hostAppGradleRoot.path,
environment: gradleEnvironment, environment: gradleEnvironment,
); );
androidSdk.reinitialize(); androidSdk?.reinitialize();
progress.stop(); progress.stop();
} }
...@@ -224,9 +224,13 @@ Future<void> buildGradleApp({ ...@@ -224,9 +224,13 @@ Future<void> buildGradleApp({
bool shouldBuildPluginAsAar = false, bool shouldBuildPluginAsAar = false,
int retries = 1, int retries = 1,
}) async { }) async {
if (androidSdk == null) { assert(project != null);
exitWithNoSdkMessage(); assert(androidBuildInfo != null);
} assert(target != null);
assert(isBuildingBundle != null);
assert(localGradleErrors != null);
assert(androidSdk != null);
if (!project.android.isUsingGradle) { if (!project.android.isUsingGradle) {
_exitWithProjectNotUsingGradleMessage(); _exitWithProjectNotUsingGradleMessage();
} }
...@@ -489,10 +493,7 @@ Future<void> buildGradleAar({ ...@@ -489,10 +493,7 @@ Future<void> buildGradleAar({
assert(target != null); assert(target != null);
assert(androidBuildInfo != null); assert(androidBuildInfo != null);
assert(outputDirectory != null); assert(outputDirectory != null);
assert(androidSdk != null);
if (androidSdk == null) {
exitWithNoSdkMessage();
}
final FlutterManifest manifest = project.manifest; final FlutterManifest manifest = project.manifest;
if (!manifest.isModule && !manifest.isPlugin) { if (!manifest.isModule && !manifest.isPlugin) {
......
...@@ -41,7 +41,7 @@ class ApplicationPackageFactory { ...@@ -41,7 +41,7 @@ class ApplicationPackageFactory {
case TargetPlatform.android_arm64: case TargetPlatform.android_arm64:
case TargetPlatform.android_x64: case TargetPlatform.android_x64:
case TargetPlatform.android_x86: case TargetPlatform.android_x86:
if (androidSdk?.licensesAvailable == true && androidSdk.latestVersion == null) { if (androidSdk?.licensesAvailable == true && androidSdk?.latestVersion == null) {
await checkGradleDependencies(); await checkGradleDependencies();
} }
return applicationBinary == null return applicationBinary == null
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
import 'dart:async'; import 'dart:async';
import '../android/android_builder.dart'; import '../android/android_builder.dart';
import '../android/android_sdk.dart';
import '../android/gradle_utils.dart';
import '../base/common.dart'; import '../base/common.dart';
import '../base/os.dart'; import '../base/os.dart';
import '../build_info.dart'; import '../build_info.dart';
...@@ -85,6 +87,9 @@ class BuildAarCommand extends BuildSubCommand { ...@@ -85,6 +87,9 @@ class BuildAarCommand extends BuildSubCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
if (androidSdk == null) {
exitWithNoSdkMessage();
}
final Set<AndroidBuildInfo> androidBuildInfo = <AndroidBuildInfo>{}; final Set<AndroidBuildInfo> androidBuildInfo = <AndroidBuildInfo>{};
final Iterable<AndroidArch> targetArchitectures = final Iterable<AndroidArch> targetArchitectures =
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
import 'dart:async'; import 'dart:async';
import '../android/android_builder.dart'; import '../android/android_builder.dart';
import '../android/android_sdk.dart';
import '../android/gradle_utils.dart';
import '../base/terminal.dart'; import '../base/terminal.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../cache.dart'; import '../cache.dart';
...@@ -77,6 +79,9 @@ class BuildApkCommand extends BuildSubCommand { ...@@ -77,6 +79,9 @@ class BuildApkCommand extends BuildSubCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
if (androidSdk == null) {
exitWithNoSdkMessage();
}
final BuildInfo buildInfo = getBuildInfo(); final BuildInfo buildInfo = getBuildInfo();
final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo( final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(
buildInfo, buildInfo,
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
import 'dart:async'; import 'dart:async';
import '../android/android_builder.dart'; import '../android/android_builder.dart';
import '../android/android_sdk.dart';
import '../android/gradle_utils.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../cache.dart'; import '../cache.dart';
import '../project.dart'; import '../project.dart';
...@@ -69,6 +71,9 @@ class BuildAppBundleCommand extends BuildSubCommand { ...@@ -69,6 +71,9 @@ class BuildAppBundleCommand extends BuildSubCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
if (androidSdk == null) {
exitWithNoSdkMessage();
}
final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(getBuildInfo(), final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(getBuildInfo(),
targetArchs: stringsArg('target-platform').map<AndroidArch>(getAndroidArchForName), targetArchs: stringsArg('target-platform').map<AndroidArch>(getAndroidArchForName),
shrink: boolArg('shrink'), shrink: boolArg('shrink'),
......
...@@ -29,14 +29,15 @@ FlutterProjectFactory get projectFactory => context.get<FlutterProjectFactory>() ...@@ -29,14 +29,15 @@ FlutterProjectFactory get projectFactory => context.get<FlutterProjectFactory>()
class FlutterProjectFactory { class FlutterProjectFactory {
FlutterProjectFactory(); FlutterProjectFactory();
final Map<String, FlutterProject> _projects = @visibleForTesting
final Map<String, FlutterProject> projects =
<String, FlutterProject>{}; <String, FlutterProject>{};
/// Returns a [FlutterProject] view of the given directory or a ToolExit error, /// Returns a [FlutterProject] view of the given directory or a ToolExit error,
/// if `pubspec.yaml` or `example/pubspec.yaml` is invalid. /// if `pubspec.yaml` or `example/pubspec.yaml` is invalid.
FlutterProject fromDirectory(Directory directory) { FlutterProject fromDirectory(Directory directory) {
assert(directory != null); assert(directory != null);
return _projects.putIfAbsent(directory.path, /* ifAbsent */ () { return projects.putIfAbsent(directory.path, /* ifAbsent */ () {
final FlutterManifest manifest = FlutterProject._readManifest( final FlutterManifest manifest = FlutterProject._readManifest(
directory.childFile(bundle.defaultManifestPath).path, directory.childFile(bundle.defaultManifestPath).path,
); );
......
...@@ -5,13 +5,12 @@ ...@@ -5,13 +5,12 @@
import 'dart:io' show Process, ProcessResult; import 'dart:io' show Process, ProcessResult;
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_builder.dart'; import 'package:flutter_tools/src/android/android_builder.dart';
import 'package:flutter_tools/src/android/android_sdk.dart'; import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/build_aar.dart'; import 'package:flutter_tools/src/commands/build_aar.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
import 'package:process/process.dart'; import 'package:process/process.dart';
...@@ -90,18 +89,14 @@ void main() { ...@@ -90,18 +89,14 @@ void main() {
Directory tempDir; Directory tempDir;
AndroidSdk mockAndroidSdk; AndroidSdk mockAndroidSdk;
Usage mockUsage; Usage mockUsage;
FileSystem memoryFileSystem;
setUp(() { setUp(() {
mockUsage = MockUsage(); mockUsage = MockUsage();
when(mockUsage.isFirstRun).thenReturn(true); when(mockUsage.isFirstRun).thenReturn(true);
memoryFileSystem = MemoryFileSystem(); tempDir = fs.systemTempDirectory.createTempSync('flutter_tools_packages_test.');
tempDir = memoryFileSystem.systemTempDirectory.createTempSync('flutter_tools_packages_test.');
memoryFileSystem.currentDirectory = tempDir;
mockProcessManager = MockProcessManager(); mockProcessManager = MockProcessManager();
when(mockProcessManager.run(any, when(mockProcessManager.run(any,
workingDirectory: anyNamed('workingDirectory'), workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'))) environment: anyNamed('environment')))
...@@ -118,65 +113,49 @@ void main() { ...@@ -118,65 +113,49 @@ void main() {
when(mockAndroidSdk.directory).thenReturn('irrelevant'); when(mockAndroidSdk.directory).thenReturn('irrelevant');
}); });
tearDown(() {
tryToDelete(tempDir);
});
group('AndroidSdk', () { group('AndroidSdk', () {
testUsingContext('validateSdkWellFormed() not called, sdk reinitialized', () async { testUsingContext('validateSdkWellFormed() not called, sdk reinitialized', () async {
final Directory gradleCacheDir = memoryFileSystem final String projectPath = await createProject(tempDir,
.directory('/flutter_root/bin/cache/artifacts/gradle_wrapper') arguments: <String>['--no-pub', '--template=module']);
..createSync(recursive: true);
gradleCacheDir.childFile(platform.isWindows ? 'gradlew.bat' : 'gradlew').createSync(); await expectLater(
runBuildAarCommand(
tempDir.childFile('pubspec.yaml') projectPath,
..createSync(recursive: true) arguments: <String>['--no-pub'],
..writeAsStringSync('''name: test ),
environment: throwsToolExit(),
sdk: ">=2.1.0 <3.0.0" );
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
plugin:
androidPackage: com.example.blah
pluginClass: BlahPlugin
''');
tempDir.childFile('.packages').createSync(recursive: true);
final Directory androidDir = tempDir.childDirectory('android');
androidDir
.childFile('build.gradle')
.createSync(recursive: true);
androidDir
.childDirectory('app')
.childFile('build.gradle')
..createSync(recursive: true)
..writeAsStringSync('apply from: irrelevant/flutter.gradle');
androidDir
.childFile('gradle.properties')
.createSync(recursive: true);
androidDir
.childDirectory('gradle')
.childDirectory('wrapper')
.childFile('gradle-wrapper.properties')
.createSync(recursive: true);
tempDir
.childDirectory('build')
.childDirectory('outputs')
.childDirectory('repo')
.createSync(recursive: true);
tempDir
.childDirectory('lib')
.childFile('main.dart')
.createSync(recursive: true);
await runBuildAarCommand(tempDir.path);
verifyNever(mockAndroidSdk.validateSdkWellFormed()); verifyNever(mockAndroidSdk.validateSdkWellFormed());
verify(mockAndroidSdk.reinitialize()).called(1); verify(mockAndroidSdk.reinitialize()).called(1);
}, },
overrides: <Type, Generator>{ overrides: <Type, Generator>{
AndroidSdk: () => mockAndroidSdk, AndroidSdk: () => mockAndroidSdk,
FlutterProjectFactory: () => FakeFlutterProjectFactory(tempDir),
ProcessManager: () => mockProcessManager,
});
testUsingContext('throws throwsToolExit if AndroidSdk is null', () async {
final String projectPath = await createProject(tempDir,
arguments: <String>['--no-pub', '--template=module']);
await expectLater(() async {
await runBuildAarCommand(
projectPath,
arguments: <String>['--no-pub'],
);
}, throwsToolExit(
message: '[!] No Android SDK found. Try setting the ANDROID_HOME environment variable',
));
},
overrides: <Type, Generator>{
AndroidSdk: () => null,
FlutterProjectFactory: () => FakeFlutterProjectFactory(tempDir),
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
FileSystem: () => memoryFileSystem,
}); });
}); });
}); });
...@@ -191,7 +170,6 @@ Future<BuildAarCommand> runBuildAarCommand( ...@@ -191,7 +170,6 @@ Future<BuildAarCommand> runBuildAarCommand(
await runner.run(<String>[ await runner.run(<String>[
'aar', 'aar',
'--no-pub', '--no-pub',
'--flutter-root=/flutter_root',
...?arguments, ...?arguments,
fs.path.join(target, 'lib', 'main.dart'), fs.path.join(target, 'lib', 'main.dart'),
]); ]);
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
import 'dart:io'; import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_builder.dart'; import 'package:flutter_tools/src/android/android_builder.dart';
import 'package:flutter_tools/src/android/android_sdk.dart'; import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/base/context.dart'; import 'package:flutter_tools/src/base/context.dart';
...@@ -140,70 +139,15 @@ void main() { ...@@ -140,70 +139,15 @@ void main() {
}); });
group('AndroidSdk', () { group('AndroidSdk', () {
FileSystem memoryFileSystem;
setUp(() {
memoryFileSystem = MemoryFileSystem();
tempDir = memoryFileSystem.systemTempDirectory.createTempSync('flutter_tools_packages_test.');
memoryFileSystem.currentDirectory = tempDir;
gradlew = memoryFileSystem.path.join(tempDir.path, 'flutter_project', 'android',
platform.isWindows ? 'gradlew.bat' : 'gradlew');
});
testUsingContext('validateSdkWellFormed() not called, sdk reinitialized', () async { testUsingContext('validateSdkWellFormed() not called, sdk reinitialized', () async {
final Directory gradleCacheDir = memoryFileSystem final String projectPath = await createProject(tempDir,
.directory('/flutter_root/bin/cache/artifacts/gradle_wrapper') arguments: <String>['--no-pub', '--template=app']);
..createSync(recursive: true);
gradleCacheDir.childFile(platform.isWindows ? 'gradlew.bat' : 'gradlew').createSync();
tempDir.childFile('pubspec.yaml')
..createSync(recursive: true)
..writeAsStringSync('''name: test
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
''');
tempDir.childFile('.packages').createSync(recursive: true);
final Directory androidDir = tempDir.childDirectory('android');
androidDir
.childFile('build.gradle')
.createSync(recursive: true);
androidDir
.childDirectory('app')
.childFile('build.gradle')
..createSync(recursive: true)
..writeAsStringSync('apply from: irrelevant/flutter.gradle');
androidDir
.childFile('gradle.properties')
.createSync(recursive: true);
androidDir
.childDirectory('gradle')
.childDirectory('wrapper')
.childFile('gradle-wrapper.properties')
.createSync(recursive: true);
tempDir
.childDirectory('build')
.childDirectory('outputs')
.childDirectory('repo')
.createSync(recursive: true);
tempDir
.childDirectory('lib')
.childFile('main.dart')
.createSync(recursive: true);
when(mockProcessManager.run(any,
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment')))
.thenAnswer((_) => Future<ProcessResult>.value(ProcessResult(0, 0, 'any', '')));
await expectLater( await expectLater(
runBuildApkCommand(tempDir.path, arguments: <String>['--no-pub', '--flutter-root=/flutter_root']), runBuildApkCommand(
projectPath,
arguments: <String>['--no-pub'],
),
throwsToolExit(message: 'Gradle task assembleRelease failed with exit code 1'), throwsToolExit(message: 'Gradle task assembleRelease failed with exit code 1'),
); );
...@@ -212,7 +156,26 @@ flutter: ...@@ -212,7 +156,26 @@ flutter:
}, },
overrides: <Type, Generator>{ overrides: <Type, Generator>{
AndroidSdk: () => mockAndroidSdk, AndroidSdk: () => mockAndroidSdk,
FileSystem: () => memoryFileSystem, FlutterProjectFactory: () => FakeFlutterProjectFactory(tempDir),
ProcessManager: () => mockProcessManager,
});
testUsingContext('throws throwsToolExit if AndroidSdk is null', () async {
final String projectPath = await createProject(tempDir,
arguments: <String>['--no-pub', '--template=app']);
await expectLater(() async {
await runBuildApkCommand(
projectPath,
arguments: <String>['--no-pub'],
);
}, throwsToolExit(
message: '[!] No Android SDK found. Try setting the ANDROID_HOME environment variable',
));
},
overrides: <Type, Generator>{
AndroidSdk: () => null,
FlutterProjectFactory: () => FakeFlutterProjectFactory(tempDir),
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
}); });
}); });
...@@ -451,18 +414,6 @@ Future<BuildApkCommand> runBuildApkCommand( ...@@ -451,18 +414,6 @@ Future<BuildApkCommand> runBuildApkCommand(
return command; return command;
} }
class FakeFlutterProjectFactory extends FlutterProjectFactory {
FakeFlutterProjectFactory(this.directoryOverride) :
assert(directoryOverride != null);
final Directory directoryOverride;
@override
FlutterProject fromDirectory(Directory _) {
return super.fromDirectory(directoryOverride.childDirectory('flutter_project'));
}
}
class MockAndroidSdk extends Mock implements AndroidSdk {} class MockAndroidSdk extends Mock implements AndroidSdk {}
class MockProcessManager extends Mock implements ProcessManager {} class MockProcessManager extends Mock implements ProcessManager {}
class MockProcess extends Mock implements Process {} class MockProcess extends Mock implements Process {}
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
import 'dart:io'; import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_builder.dart'; import 'package:flutter_tools/src/android/android_builder.dart';
import 'package:flutter_tools/src/android/android_sdk.dart'; import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/base/context.dart'; import 'package:flutter_tools/src/base/context.dart';
...@@ -125,67 +124,15 @@ void main() { ...@@ -125,67 +124,15 @@ void main() {
}); });
group('AndroidSdk', () { group('AndroidSdk', () {
FileSystem memoryFileSystem;
setUp(() {
memoryFileSystem = MemoryFileSystem();
tempDir = memoryFileSystem.systemTempDirectory.createTempSync('flutter_tools_packages_test.');
memoryFileSystem.currentDirectory = tempDir;
gradlew = memoryFileSystem.path.join(tempDir.path, 'flutter_project', 'android',
platform.isWindows ? 'gradlew.bat' : 'gradlew');
});
testUsingContext('validateSdkWellFormed() not called, sdk reinitialized', () async { testUsingContext('validateSdkWellFormed() not called, sdk reinitialized', () async {
final Directory gradleCacheDir = memoryFileSystem final String projectPath = await createProject(tempDir,
.directory('/flutter_root/bin/cache/artifacts/gradle_wrapper') arguments: <String>['--no-pub', '--template=app']);
..createSync(recursive: true);
gradleCacheDir.childFile(platform.isWindows ? 'gradlew.bat' : 'gradlew').createSync();
tempDir.childFile('pubspec.yaml')
..createSync(recursive: true)
..writeAsStringSync('''name: test
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
''');
tempDir.childFile('.packages').createSync(recursive: true);
final Directory androidDir = tempDir.childDirectory('android');
androidDir.childFile('build.gradle').createSync(recursive: true);
androidDir
.childDirectory('app')
.childFile('build.gradle')
..createSync(recursive: true)
..writeAsStringSync('apply from: irrelevant/flutter.gradle');
androidDir
.childFile('gradle.properties')
.createSync(recursive: true);
androidDir
.childDirectory('gradle')
.childDirectory('wrapper')
.childFile('gradle-wrapper.properties')
.createSync(recursive: true);
tempDir.childDirectory('build')
.childDirectory('outputs')
.childDirectory('repo')
.createSync(recursive: true);
tempDir.childDirectory('lib')
.childFile('main.dart')
.createSync(recursive: true);
when(mockProcessManager.run(any,
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment')))
.thenAnswer((_) => Future<ProcessResult>.value(ProcessResult(0, 0, 'any', '')));
await expectLater( await expectLater(
runBuildAppBundleCommand(tempDir.path, arguments: <String>['--no-pub', '--flutter-root=/flutter_root']), runBuildAppBundleCommand(
projectPath,
arguments: <String>['--no-pub'],
),
throwsToolExit(message: 'Gradle task bundleRelease failed with exit code 1'), throwsToolExit(message: 'Gradle task bundleRelease failed with exit code 1'),
); );
...@@ -194,8 +141,27 @@ flutter: ...@@ -194,8 +141,27 @@ flutter:
}, },
overrides: <Type, Generator>{ overrides: <Type, Generator>{
AndroidSdk: () => mockAndroidSdk, AndroidSdk: () => mockAndroidSdk,
FlutterProjectFactory: () => FakeFlutterProjectFactory(tempDir),
ProcessManager: () => mockProcessManager,
});
testUsingContext('throws throwsToolExit if AndroidSdk is null', () async {
final String projectPath = await createProject(tempDir,
arguments: <String>['--no-pub', '--template=app']);
await expectLater(() async {
await runBuildAppBundleCommand(
projectPath,
arguments: <String>['--no-pub'],
);
}, throwsToolExit(
message: '[!] No Android SDK found. Try setting the ANDROID_HOME environment variable',
));
},
overrides: <Type, Generator>{
AndroidSdk: () => null,
FlutterProjectFactory: () => FakeFlutterProjectFactory(tempDir),
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
FileSystem: () => memoryFileSystem,
}); });
}); });
...@@ -437,18 +403,6 @@ Future<BuildAppBundleCommand> runBuildAppBundleCommand( ...@@ -437,18 +403,6 @@ Future<BuildAppBundleCommand> runBuildAppBundleCommand(
return command; return command;
} }
class FakeFlutterProjectFactory extends FlutterProjectFactory {
FakeFlutterProjectFactory(this._directoryOverride) :
assert(_directoryOverride != null);
final Directory _directoryOverride;
@override
FlutterProject fromDirectory(Directory _) {
return super.fromDirectory(_directoryOverride.childDirectory('flutter_project'));
}
}
class MockAndroidSdk extends Mock implements AndroidSdk {} class MockAndroidSdk extends Mock implements AndroidSdk {}
class MockProcessManager extends Mock implements ProcessManager {} class MockProcessManager extends Mock implements ProcessManager {}
class MockProcess extends Mock implements Process {} class MockProcess extends Mock implements Process {}
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:flutter_tools/src/android/android_builder.dart'; import 'package:flutter_tools/src/android/android_builder.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/project.dart';
...@@ -33,3 +34,18 @@ class FakeAndroidBuilder implements AndroidBuilder { ...@@ -33,3 +34,18 @@ class FakeAndroidBuilder implements AndroidBuilder {
@required String target, @required String target,
}) async {} }) async {}
} }
/// Creates a [FlutterProject] in a directory named [flutter_project]
/// within [directoryOverride].
class FakeFlutterProjectFactory extends FlutterProjectFactory {
FakeFlutterProjectFactory(this.directoryOverride) :
assert(directoryOverride != null);
final Directory directoryOverride;
@override
FlutterProject fromDirectory(Directory _) {
projects.clear();
return super.fromDirectory(directoryOverride.childDirectory('flutter_project'));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment