[flutter_tools] reland: --no-android-gradle-daemon in devicelab (#68491)
Remove devicelab specific code for shutting down gradle daemon, add --android-gradle-daemon option to build/run/drive`. Avoids need for un-tested devicelab specific handler. There are also some feature requests for this, so 2 birds one stone. Example: flutter build apk --no-android-gradle-daemon will pass --no-daemon on to gradle
This commit is contained in:
parent
8df0c5e158
commit
e422d5c724
@ -21,6 +21,7 @@ void main() {
|
||||
|
||||
await inDirectory(complexLayoutPath, () async {
|
||||
await flutter('drive', options: <String>[
|
||||
'--no-android-gradle-daemon',
|
||||
'-v',
|
||||
'--profile',
|
||||
'--trace-startup', // Enables "endless" timeline event buffering.
|
||||
|
@ -6,7 +6,6 @@ import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:vm_service_client/vm_service_client.dart';
|
||||
|
||||
import 'package:flutter_devicelab/framework/utils.dart';
|
||||
@ -88,7 +87,6 @@ Future<TaskResult> runTask(
|
||||
} finally {
|
||||
if (!runnerFinished)
|
||||
runner.kill(ProcessSignal.sigkill);
|
||||
await cleanupSystem();
|
||||
await stdoutSub.cancel();
|
||||
await stderrSub.cancel();
|
||||
}
|
||||
@ -124,42 +122,3 @@ Future<VMIsolateRef> _connectToRunnerIsolate(Uri vmServiceUri) async {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> cleanupSystem() async {
|
||||
if (deviceOperatingSystem == null || deviceOperatingSystem == DeviceOperatingSystem.android) {
|
||||
print('\n\nCleaning up system after task...');
|
||||
final String javaHome = await findJavaHome();
|
||||
if (javaHome != null) {
|
||||
// To shut gradle down, we have to call "gradlew --stop".
|
||||
// To call gradlew, we need to have a gradle-wrapper.properties file along
|
||||
// with a shell script, a .jar file, etc. We get these from various places
|
||||
// as you see in the code below, and we save them all into a temporary dir
|
||||
// which we can then delete after.
|
||||
// All the steps below are somewhat tolerant of errors, because it doesn't
|
||||
// really matter if this succeeds every time or not.
|
||||
print('\nTelling Gradle to shut down (JAVA_HOME=$javaHome)');
|
||||
final String gradlewBinaryName = Platform.isWindows ? 'gradlew.bat' : 'gradlew';
|
||||
final Directory tempDir = Directory.systemTemp.createTempSync('flutter_devicelab_shutdown_gradle.');
|
||||
recursiveCopy(Directory(path.join(flutterDirectory.path, 'bin', 'cache', 'artifacts', 'gradle_wrapper')), tempDir);
|
||||
copy(File(path.join(path.join(flutterDirectory.path, 'packages', 'flutter_tools'), 'templates', 'app', 'android.tmpl', 'gradle', 'wrapper', 'gradle-wrapper.properties')), Directory(path.join(tempDir.path, 'gradle', 'wrapper')));
|
||||
if (!Platform.isWindows) {
|
||||
await exec(
|
||||
'chmod',
|
||||
<String>['a+x', path.join(tempDir.path, gradlewBinaryName)],
|
||||
canFail: true,
|
||||
);
|
||||
}
|
||||
await exec(
|
||||
path.join(tempDir.path, gradlewBinaryName),
|
||||
<String>['--stop'],
|
||||
environment: <String, String>{ 'JAVA_HOME': javaHome},
|
||||
workingDirectory: tempDir.path,
|
||||
canFail: true,
|
||||
);
|
||||
rmTree(tempDir);
|
||||
print('\n');
|
||||
} else {
|
||||
print('Could not determine JAVA_HOME; not shutting down Gradle.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ Future<TaskResult> runDartDefinesTask() async {
|
||||
await flutter('packages', options: <String>['get']);
|
||||
|
||||
await flutter('drive', options: <String>[
|
||||
'--no-android-gradle-daemon',
|
||||
'--verbose',
|
||||
'-d',
|
||||
deviceId,
|
||||
|
@ -71,6 +71,7 @@ class GalleryTransitionTest {
|
||||
'build',
|
||||
options: <String>[
|
||||
'apk',
|
||||
'--no-android-gradle-daemon',
|
||||
'--profile',
|
||||
'-t',
|
||||
'test_driver/$testFile.dart',
|
||||
|
@ -26,7 +26,7 @@ TaskFunction createHotModeTest({String deviceIdOverride, Map<String, String> env
|
||||
final File benchmarkFile = file(path.join(_editedFlutterGalleryDir.path, 'hot_benchmark.json'));
|
||||
rm(benchmarkFile);
|
||||
final List<String> options = <String>[
|
||||
'--hot', '-d', deviceIdOverride, '--benchmark', '--verbose', '--resident',
|
||||
'--hot', '-d', deviceIdOverride, '--benchmark', '--verbose', '--resident', '--no-android-gradle-daemon',
|
||||
];
|
||||
int hotReloadCount = 0;
|
||||
Map<String, dynamic> twoReloadsData;
|
||||
|
@ -130,6 +130,7 @@ class DriverTest {
|
||||
await flutter('packages', options: <String>['get']);
|
||||
|
||||
final List<String> options = <String>[
|
||||
'--no-android-gradle-daemon',
|
||||
'-v',
|
||||
'-t',
|
||||
testTarget,
|
||||
|
@ -347,6 +347,7 @@ TaskFunction createsScrollSmoothnessPerfTest() {
|
||||
await flutter('packages', options: <String>['get']);
|
||||
|
||||
await flutter('drive', options: <String>[
|
||||
'--no-android-gradle-daemon',
|
||||
'-v',
|
||||
'--verbose-system-logs',
|
||||
'--profile',
|
||||
@ -395,6 +396,7 @@ TaskFunction createFramePolicyIntegrationTest() {
|
||||
await flutter('packages', options: <String>['get']);
|
||||
|
||||
await flutter('drive', options: <String>[
|
||||
'--no-android-gradle-daemon',
|
||||
'-v',
|
||||
'--verbose-system-logs',
|
||||
'--profile',
|
||||
@ -459,6 +461,7 @@ class StartupTest {
|
||||
final List<Map<String, dynamic>> results = <Map<String, dynamic>>[];
|
||||
for (int i = 0; i < iterations; ++i) {
|
||||
await flutter('run', options: <String>[
|
||||
'--no-android-gradle-daemon',
|
||||
'--verbose',
|
||||
'--profile',
|
||||
'--trace-startup',
|
||||
@ -575,6 +578,7 @@ class PerfTest {
|
||||
await flutter('packages', options: <String>['get']);
|
||||
|
||||
await flutter('drive', options: <String>[
|
||||
'--no-android-gradle-daemon',
|
||||
'-v',
|
||||
'--verbose-system-logs',
|
||||
'--profile',
|
||||
|
@ -43,6 +43,7 @@ class TrackWidgetCreationEnabledTask {
|
||||
final Process runProcess = await startProcess(
|
||||
path.join(flutterDirectory.path, 'bin', 'flutter'),
|
||||
flutterCommandArgs('run', <String>[
|
||||
'--no-android-gradle-daemon',
|
||||
...?additionalArgs,
|
||||
'--vmservice-out-file=info',
|
||||
'--track-widget-creation',
|
||||
@ -78,6 +79,7 @@ class TrackWidgetCreationEnabledTask {
|
||||
final Process runProcess = await startProcess(
|
||||
path.join(flutterDirectory.path, 'bin', 'flutter'),
|
||||
flutterCommandArgs('run', <String>[
|
||||
'--no-android-gradle-daemon',
|
||||
...?additionalArgs,
|
||||
'--vmservice-out-file=info',
|
||||
'--no-track-widget-creation',
|
||||
|
@ -279,6 +279,9 @@ Future<void> buildGradleApp({
|
||||
} else {
|
||||
command.add('-q');
|
||||
}
|
||||
if (!buildInfo.androidGradleDaemon) {
|
||||
command.add('--no-daemon');
|
||||
}
|
||||
if (globals.artifacts is LocalEngineArtifacts) {
|
||||
final LocalEngineArtifacts localEngineArtifacts = globals.artifacts as LocalEngineArtifacts;
|
||||
final Directory localEngineRepo = _getLocalEngineRepo(
|
||||
@ -592,6 +595,9 @@ Future<void> buildGradleAar({
|
||||
} else {
|
||||
command.add('-q');
|
||||
}
|
||||
if (!buildInfo.androidGradleDaemon) {
|
||||
command.add('--no-daemon');
|
||||
}
|
||||
|
||||
if (target != null && target.isNotEmpty) {
|
||||
command.add('-Ptarget=$target');
|
||||
|
@ -34,6 +34,7 @@ class BuildInfo {
|
||||
this.packagesPath = '.packages',
|
||||
this.nullSafetyMode = NullSafetyMode.autodetect,
|
||||
this.codeSizeDirectory,
|
||||
this.androidGradleDaemon = true,
|
||||
});
|
||||
|
||||
final BuildMode mode;
|
||||
@ -118,6 +119,20 @@ class BuildInfo {
|
||||
/// will be written for code size profiling.
|
||||
final String codeSizeDirectory;
|
||||
|
||||
/// Whether to enable the Gradle daemon when performing an Android build.
|
||||
///
|
||||
/// Starting the daemon is the default behavior of the gradle wrapper script created
|
||||
/// in a Flutter project. Setting this value to false will cause the tool to pass
|
||||
/// `--no-daemon` to the gradle wrapper script, preventing it from spawning a daemon
|
||||
/// process.
|
||||
///
|
||||
/// For one-off builds or CI systems, preventing the daemon from spawning will
|
||||
/// reduce system resource usage, at the cost of any subsequent builds starting
|
||||
/// up slightly slower.
|
||||
///
|
||||
/// The Gradle daemon may also be disabled in the Android application's properties file.
|
||||
final bool androidGradleDaemon;
|
||||
|
||||
static const BuildInfo debug = BuildInfo(BuildMode.debug, null, treeShakeIcons: false);
|
||||
static const BuildInfo profile = BuildInfo(BuildMode.profile, null, treeShakeIcons: kIconTreeShakerEnabledDefault);
|
||||
static const BuildInfo jitRelease = BuildInfo(BuildMode.jitRelease, null, treeShakeIcons: kIconTreeShakerEnabledDefault);
|
||||
|
@ -43,6 +43,7 @@ class BuildAarCommand extends BuildSubCommand {
|
||||
usesTrackWidgetCreation(verboseHelp: false);
|
||||
addNullSafetyModeOptions(hide: !verboseHelp);
|
||||
addEnableExperimentation(hide: !verboseHelp);
|
||||
addAndroidSpecificBuildOptions(hide: !verboseHelp);
|
||||
argParser
|
||||
..addMultiOption(
|
||||
'target-platform',
|
||||
|
@ -33,6 +33,7 @@ class BuildApkCommand extends BuildSubCommand {
|
||||
addBuildPerformanceFile(hide: !verboseHelp);
|
||||
addNullSafetyModeOptions(hide: !verboseHelp);
|
||||
usesAnalyzeSizeFlag();
|
||||
addAndroidSpecificBuildOptions(hide: !verboseHelp);
|
||||
argParser
|
||||
..addFlag('split-per-abi',
|
||||
negatable: false,
|
||||
|
@ -33,6 +33,7 @@ class BuildAppBundleCommand extends BuildSubCommand {
|
||||
addNullSafetyModeOptions(hide: !verboseHelp);
|
||||
addEnableExperimentation(hide: !verboseHelp);
|
||||
usesAnalyzeSizeFlag();
|
||||
addAndroidSpecificBuildOptions(hide: !verboseHelp);
|
||||
argParser.addMultiOption('target-platform',
|
||||
splitCommas: true,
|
||||
defaultsTo: <String>['android-arm', 'android-arm64', 'android-x64'],
|
||||
|
@ -88,6 +88,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
|
||||
usesDeviceUserOption();
|
||||
usesDeviceTimeoutOption();
|
||||
addDdsOptions(verboseHelp: verboseHelp);
|
||||
addAndroidSpecificBuildOptions(hide: !verboseHelp);
|
||||
}
|
||||
|
||||
bool get traceStartup => boolArg('trace-startup');
|
||||
|
@ -114,6 +114,7 @@ class FlutterOptions {
|
||||
static const String kDeviceTimeout = 'device-timeout';
|
||||
static const String kAnalyzeSize = 'analyze-size';
|
||||
static const String kNullAssertions = 'null-assertions';
|
||||
static const String kAndroidGradleDaemon = 'android-gradle-daemon';
|
||||
}
|
||||
|
||||
abstract class FlutterCommand extends Command<void> {
|
||||
@ -611,6 +612,18 @@ abstract class FlutterCommand extends Command<void> {
|
||||
);
|
||||
}
|
||||
|
||||
void addAndroidSpecificBuildOptions({ bool hide = false }) {
|
||||
argParser.addFlag(
|
||||
FlutterOptions.kAndroidGradleDaemon,
|
||||
help: 'Whether to enable the Gradle daemon when performing an Android build. '
|
||||
'Starting the daemon is the default behavior of the gradle wrapper script created '
|
||||
' in a Flutter project. Setting this flag to false corresponds to passing '
|
||||
"'--no-daemon' to the gradle wrapper script. This flag will cause the daemon "
|
||||
'process to terminate after the build is completed',
|
||||
defaultsTo: true,
|
||||
);
|
||||
}
|
||||
|
||||
/// Adds build options common to all of the desktop build commands.
|
||||
void addCommonDesktopBuildOptions({ bool verboseHelp = false }) {
|
||||
addBuildModeFlags(verboseHelp: verboseHelp);
|
||||
@ -764,6 +777,9 @@ abstract class FlutterCommand extends Command<void> {
|
||||
? stringArg(FlutterOptions.kSplitDebugInfoOption)
|
||||
: null;
|
||||
|
||||
final bool androidGradleDaemon = !argParser.options.containsKey(FlutterOptions.kAndroidGradleDaemon)
|
||||
|| boolArg(FlutterOptions.kAndroidGradleDaemon);
|
||||
|
||||
if (dartObfuscation && (splitDebugInfoPath == null || splitDebugInfoPath.isEmpty)) {
|
||||
throwToolExit(
|
||||
'"--${FlutterOptions.kDartObfuscationOption}" can only be used in '
|
||||
@ -827,6 +843,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
packagesPath: globalResults['packages'] as String ?? '.packages',
|
||||
nullSafetyMode: nullSafetyMode,
|
||||
codeSizeDirectory: codeSizeDirectory,
|
||||
androidGradleDaemon: androidGradleDaemon,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1328,7 +1328,7 @@ plugin1=${plugin1.path}
|
||||
ProcessManager: () => mockProcessManager,
|
||||
});
|
||||
|
||||
testUsingContext('logs success event after a sucessful retry', () async {
|
||||
testUsingContext('logs success event after a successful retry', () async {
|
||||
int testFnCalled = 0;
|
||||
when(mockProcessManager.start(any,
|
||||
workingDirectory: anyNamed('workingDirectory'),
|
||||
@ -1415,7 +1415,7 @@ plugin1=${plugin1.path}
|
||||
Usage: () => mockUsage,
|
||||
});
|
||||
|
||||
testUsingContext('performs code size analyis and sends analytics', () async {
|
||||
testUsingContext('performs code size analysis and sends analytics', () async {
|
||||
when(mockProcessManager.start(any,
|
||||
workingDirectory: anyNamed('workingDirectory'),
|
||||
environment: anyNamed('environment')))
|
||||
@ -2059,6 +2059,59 @@ plugin1=${plugin1.path}
|
||||
ProcessManager: () => mockProcessManager,
|
||||
});
|
||||
|
||||
testUsingContext('honors --no-android-gradle-daemon setting', () async {
|
||||
(globals.processManager as FakeProcessManager).addCommand(
|
||||
const FakeCommand(command: <String>[
|
||||
'/android/gradlew',
|
||||
'-q',
|
||||
'--no-daemon',
|
||||
'-Ptarget-platform=android-arm,android-arm64,android-x64',
|
||||
'-Ptarget=lib/main.dart',
|
||||
'-Ptrack-widget-creation=false',
|
||||
'assembleRelease'
|
||||
],
|
||||
));
|
||||
fileSystem.file('android/gradlew').createSync(recursive: true);
|
||||
|
||||
fileSystem.directory('android')
|
||||
.childFile('gradle.properties')
|
||||
.createSync(recursive: true);
|
||||
|
||||
fileSystem.file('android/build.gradle')
|
||||
.createSync(recursive: true);
|
||||
|
||||
fileSystem.directory('android')
|
||||
.childDirectory('app')
|
||||
.childFile('build.gradle')
|
||||
..createSync(recursive: true)
|
||||
..writeAsStringSync('apply from: irrelevant/flutter.gradle');
|
||||
|
||||
await expectLater(() async {
|
||||
await buildGradleApp(
|
||||
project: FlutterProject.current(),
|
||||
androidBuildInfo: const AndroidBuildInfo(
|
||||
BuildInfo(
|
||||
BuildMode.release,
|
||||
null,
|
||||
treeShakeIcons: false,
|
||||
androidGradleDaemon: false,
|
||||
),
|
||||
),
|
||||
target: 'lib/main.dart',
|
||||
isBuildingBundle: false,
|
||||
localGradleErrors: const <GradleHandledError>[],
|
||||
);
|
||||
}, throwsToolExit());
|
||||
}, overrides: <Type, Generator>{
|
||||
AndroidSdk: () => mockAndroidSdk,
|
||||
AndroidStudio: () => mockAndroidStudio,
|
||||
Artifacts: () => Artifacts.test(),
|
||||
Cache: () => cache,
|
||||
Platform: () => android,
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[]),
|
||||
});
|
||||
|
||||
testUsingContext('build aar uses selected local engine,the engine abi is arm', () async {
|
||||
when(mockArtifacts.getArtifactPath(Artifact.flutterFramework,
|
||||
platform: TargetPlatform.android_arm, mode: anyNamed('mode'))).thenReturn('engine');
|
||||
|
Loading…
x
Reference in New Issue
Block a user