Unverified Commit 4566b340 authored by Dan Field's avatar Dan Field Committed by GitHub

Do not validate the Android SDK when building an appbundle (#41946)

parent 3af16678
...@@ -9,7 +9,6 @@ import 'package:meta/meta.dart'; ...@@ -9,7 +9,6 @@ import 'package:meta/meta.dart';
import '../base/common.dart'; import '../base/common.dart';
import '../base/context.dart'; import '../base/context.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../globals.dart';
import '../project.dart'; import '../project.dart';
import 'android_sdk.dart'; import 'android_sdk.dart';
...@@ -70,14 +69,17 @@ class _AndroidBuilderImpl extends AndroidBuilder { ...@@ -70,14 +69,17 @@ class _AndroidBuilderImpl extends AndroidBuilder {
if (androidSdk == null) { if (androidSdk == null) {
throwToolExit('No Android SDK found. Try setting the `ANDROID_SDK_ROOT` environment variable.'); throwToolExit('No Android SDK found. Try setting the `ANDROID_SDK_ROOT` environment variable.');
} }
try {
await buildGradleAar( await buildGradleAar(
project: project, project: project,
androidBuildInfo: androidBuildInfo, androidBuildInfo: androidBuildInfo,
target: target, target: target,
outputDir: outputDir, outputDir: outputDir,
); );
} finally {
androidSdk.reinitialize(); androidSdk.reinitialize();
} }
}
/// Builds the APK. /// Builds the APK.
@override @override
...@@ -98,14 +100,17 @@ class _AndroidBuilderImpl extends AndroidBuilder { ...@@ -98,14 +100,17 @@ class _AndroidBuilderImpl extends AndroidBuilder {
if (androidSdk == null) { if (androidSdk == null) {
throwToolExit('No Android SDK found. Try setting the ANDROID_SDK_ROOT environment variable.'); throwToolExit('No Android SDK found. Try setting the ANDROID_SDK_ROOT environment variable.');
} }
try {
await buildGradleProject( await buildGradleProject(
project: project, project: project,
androidBuildInfo: androidBuildInfo, androidBuildInfo: androidBuildInfo,
target: target, target: target,
isBuildingBundle: false, isBuildingBundle: false,
); );
} finally {
androidSdk.reinitialize(); androidSdk.reinitialize();
} }
}
/// Builds the App Bundle. /// Builds the App Bundle.
@override @override
...@@ -126,19 +131,17 @@ class _AndroidBuilderImpl extends AndroidBuilder { ...@@ -126,19 +131,17 @@ class _AndroidBuilderImpl extends AndroidBuilder {
if (androidSdk == null) { if (androidSdk == null) {
throwToolExit('No Android SDK found. Try setting the ANDROID_HOME environment variable.'); throwToolExit('No Android SDK found. Try setting the ANDROID_HOME environment variable.');
} }
final List<String> validationResult = androidSdk.validateSdkWellFormed();
if (validationResult.isNotEmpty) { try {
for (String message in validationResult) { await buildGradleProject(
printError(message, wrap: false);
}
throwToolExit('Try re-installing or updating your Android SDK.');
}
return buildGradleProject(
project: project, project: project,
androidBuildInfo: androidBuildInfo, androidBuildInfo: androidBuildInfo,
target: target, target: target,
isBuildingBundle: true, isBuildingBundle: true,
); );
} finally {
androidSdk.reinitialize();
}
} }
} }
......
...@@ -820,9 +820,8 @@ Future<void> _buildGradleProjectV2( ...@@ -820,9 +820,8 @@ Future<void> _buildGradleProjectV2(
workingDirectory: flutterProject.android.hostAppGradleRoot.path, workingDirectory: flutterProject.android.hostAppGradleRoot.path,
allowReentrantFlutter: true, allowReentrantFlutter: true,
environment: gradleEnv, environment: gradleEnv,
// TODO(mklim): if AndroidX warnings are no longer required, this // TODO(mklim): if AndroidX warnings are no longer required, we can remove
// mapFunction and all its associated variabled can be replaced with just // them from this map function.
// `filter: ndkMessagefilter`.
mapFunction: (String line) { mapFunction: (String line) {
final bool isAndroidXPluginWarning = androidXPluginWarningRegex.hasMatch(line); final bool isAndroidXPluginWarning = androidXPluginWarningRegex.hasMatch(line);
if (!isAndroidXPluginWarning && androidXFailureRegex.hasMatch(line)) { if (!isAndroidXPluginWarning && androidXFailureRegex.hasMatch(line)) {
......
...@@ -2,15 +2,24 @@ ...@@ -2,15 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
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/gradle.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/reporting/reporting.dart'; import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:mockito/mockito.dart';
import 'package:process/process.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/context.dart'; import '../../src/context.dart';
import '../../src/mocks.dart';
void main() { void main() {
Cache.disableLocking(); Cache.disableLocking();
...@@ -74,4 +83,100 @@ void main() { ...@@ -74,4 +83,100 @@ void main() {
AndroidBuilder: () => FakeAndroidBuilder(), AndroidBuilder: () => FakeAndroidBuilder(),
}, timeout: allowForCreateFlutterProject); }, timeout: allowForCreateFlutterProject);
}); });
group('Gradle', () {
ProcessManager mockProcessManager;
Directory tempDir;
AndroidSdk mockAndroidSdk;
Usage mockUsage;
FileSystem memoryFileSystem;
setUp(() {
mockUsage = MockUsage();
when(mockUsage.isFirstRun).thenReturn(true);
memoryFileSystem = MemoryFileSystem();
tempDir = memoryFileSystem.systemTempDirectory.createTempSync('flutter_tools_packages_test.');
memoryFileSystem.currentDirectory = tempDir;
mockProcessManager = MockProcessManager();
when(mockProcessManager.run(any,
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment')))
.thenAnswer((_) => Future<ProcessResult>.value(ProcessResult(0, 0, 'assembleRelease', '')));
// Fallback with error.
final Process process = createMockProcess(exitCode: 1);
when(mockProcessManager.start(any,
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment')))
.thenAnswer((_) => Future<Process>.value(process));
when(mockProcessManager.canRun(any)).thenReturn(false);
mockAndroidSdk = MockAndroidSdk();
when(mockAndroidSdk.directory).thenReturn('irrelevant');
});
group('AndroidSdk', () {
testUsingContext('validateSdkWellFormed() not called, sdk reinitialized', () async {
final Directory gradleCacheDir = memoryFileSystem.directory('/flutter_root/bin/cache/artifacts/gradle_wrapper')..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:
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.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());
verify(mockAndroidSdk.reinitialize()).called(1);
},
overrides: <Type, Generator>{
AndroidSdk: () => mockAndroidSdk,
GradleUtils: () => GradleUtils(),
ProcessManager: () => mockProcessManager,
FileSystem: () => memoryFileSystem,
});
});
});
} }
Future<BuildAarCommand> runBuildAarCommand(
String target, {
List<String> arguments,
}) async {
final BuildAarCommand command = BuildAarCommand();
final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>[
'aar',
'--no-pub',
'--flutter-root=/flutter_root',
...?arguments,
fs.path.join(target, 'lib', 'main.dart'),
]);
return command;
}
class MockAndroidSdk extends Mock implements AndroidSdk {}
class MockProcessManager extends Mock implements ProcessManager {}
class MockProcess extends Mock implements Process {}
class MockUsage extends Mock implements Usage {}
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
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/android/gradle.dart'; import 'package:flutter_tools/src/android/gradle.dart';
...@@ -137,6 +138,62 @@ void main() { ...@@ -137,6 +138,62 @@ void main() {
tryToDelete(tempDir); tryToDelete(tempDir);
}); });
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 {
final Directory gradleCacheDir = memoryFileSystem.directory('/flutter_root/bin/cache/artifacts/gradle_wrapper')..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.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(
runBuildApkCommand(tempDir.path, arguments: <String>['--no-pub', '--flutter-root=/flutter_root']),
throwsToolExit(message: 'Gradle build failed: 1'),
);
verifyNever(mockAndroidSdk.validateSdkWellFormed());
verify(mockAndroidSdk.reinitialize()).called(1);
},
overrides: <Type, Generator>{
AndroidSdk: () => mockAndroidSdk,
GradleUtils: () => GradleUtils(),
ProcessManager: () => mockProcessManager,
FileSystem: () => memoryFileSystem,
});
});
testUsingContext('shrinking is enabled by default on release mode', () async { testUsingContext('shrinking is enabled by default on release mode', () async {
final String projectPath = await createProject(tempDir, final String projectPath = await createProject(tempDir,
arguments: <String>['--no-pub', '--template=app']); arguments: <String>['--no-pub', '--template=app']);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
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/android/gradle.dart'; import 'package:flutter_tools/src/android/gradle.dart';
...@@ -122,6 +123,64 @@ void main() { ...@@ -122,6 +123,64 @@ void main() {
tryToDelete(tempDir); tryToDelete(tempDir);
}); });
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 {
final Directory gradleCacheDir = memoryFileSystem.directory('/flutter_root/bin/cache/artifacts/gradle_wrapper')..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.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(
runBuildAppBundleCommand(tempDir.path, arguments: <String>['--no-pub', '--flutter-root=/flutter_root']),
throwsToolExit(message: 'Gradle build failed: 1'),
);
verifyNever(mockAndroidSdk.validateSdkWellFormed());
verify(mockAndroidSdk.reinitialize()).called(1);
},
overrides: <Type, Generator>{
AndroidSdk: () => mockAndroidSdk,
GradleUtils: () => GradleUtils(),
ProcessManager: () => mockProcessManager,
FileSystem: () => memoryFileSystem,
});
});
testUsingContext('shrinking is enabled by default on release mode', () async { testUsingContext('shrinking is enabled by default on release mode', () async {
final String projectPath = await createProject( final String projectPath = await createProject(
tempDir, tempDir,
......
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