Commit 4ccd185b authored by hacker1024's avatar hacker1024
Browse files

flutter{329,332}: Pass --project-cache-dir to Gradle

parent 910796ca
Loading
Loading
Loading
Loading
+158 −6
Original line number Diff line number Diff line
@@ -15,11 +15,9 @@ The intermediate project makes a `settings.gradle` file in `$HOME/.cache/flutter
This Gradle project will build the actual `packages/flutter_tools/gradle` project by setting
`rootProject.projectDir = new File("$settingsDir")` and `apply from: new File("$settingsDir/settings.gradle.kts")`.

Now the `.gradle` will be built in `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/`, but `build` doesn't.
To move `build` to `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/` as well, we need to set `buildDirectory`.
diff --git a/packages/flutter_tools/gradle/settings.gradle b/packages/flutter_tools/gradle/settings.gradle
new file mode 100644
index 0000000000..b2485c94b4
To move `build` to `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/`, we need to set `buildDirectory`.
To move `.gradle` as well, the `--project-cache-dir` argument must be passed to the Gradle wrapper.
Changing the `GradleUtils.getExecutable` function signature is a delibarate choice, to ensure that no new unpatched usages slip in.
--- /dev/null
+++ b/packages/flutter_tools/gradle/settings.gradle
@@ -0,0 +1,19 @@
@@ -44,12 +42,166 @@ index 0000000000..b2485c94b4
+includeBuild(dir)
--- a/packages/flutter_tools/gradle/build.gradle.kts
+++ b/packages/flutter_tools/gradle/build.gradle.kts
@@ -4,6 +4,8 @@
@@ -4,6 +4,11 @@
 
 import org.jetbrains.kotlin.gradle.dsl.JvmTarget
 
+// While flutter_tools runs Gradle with a --project-cache-dir, this startParameter
+// is not passed correctly to the Kotlin Gradle plugin for some reason, and so
+// must be set here as well.
+gradle.startParameter.projectCacheDir = layout.buildDirectory.dir("cache").get().asFile
+
 plugins {
     `java-gradle-plugin`
     groovy
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -456,9 +456,9 @@ class AndroidGradleBuilder implements AndroidBuilder {
     // from the local.properties file.
     updateLocalProperties(project: project, buildInfo: androidBuildInfo.buildInfo);
 
-    final List<String> options = <String>[];
-
-    final String gradleExecutablePath = _gradleUtils.getExecutable(project);
+    final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
+      project,
+    );
 
     // All automatically created files should exist.
     if (configOnly) {
@@ -781,7 +781,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
       'aar_init_script.gradle',
     );
     final List<String> command = <String>[
-      _gradleUtils.getExecutable(project),
+      ..._gradleUtils.getExecutable(project),
       '-I=$initScript',
       '-Pflutter-root=$flutterRoot',
       '-Poutput-dir=${outputDirectory.path}',
@@ -896,6 +896,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
     final List<String> results = <String>[];
 
     try {
+      final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
+        project,
+      );
+
       exitCode = await _runGradleTask(
         _kBuildVariantTaskName,
         preRunTask: () {
@@ -911,10 +915,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
             ),
           );
         },
-        options: const <String>['-q'],
+        options: <String>[...options, '-q'],
         project: project,
         localGradleErrors: gradleErrors,
-        gradleExecutablePath: _gradleUtils.getExecutable(project),
+        gradleExecutablePath: gradleExecutablePath,
         outputParser: (String line) {
           if (_kBuildVariantRegex.firstMatch(line) case final RegExpMatch match) {
             results.add(match.namedGroup(_kBuildVariantRegexGroupName)!);
@@ -948,6 +952,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
     late Stopwatch sw;
     int exitCode = 1;
     try {
+      final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
+        project,
+      );
+
       exitCode = await _runGradleTask(
         taskName,
         preRunTask: () {
@@ -963,10 +971,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
             ),
           );
         },
-        options: <String>['-q', '-PoutputPath=$outputPath'],
+        options: <String>[...options, '-q', '-PoutputPath=$outputPath'],
         project: project,
         localGradleErrors: gradleErrors,
-        gradleExecutablePath: _gradleUtils.getExecutable(project),
+        gradleExecutablePath: gradleExecutablePath,
       );
     } on Error catch (error) {
       _logger.printError(error.toString());
--- a/packages/flutter_tools/lib/src/android/gradle_errors.dart
+++ b/packages/flutter_tools/lib/src/android/gradle_errors.dart
@@ -240,7 +240,12 @@ final GradleHandledError flavorUndefinedHandler = GradleHandledError(
     required bool usesAndroidX,
   }) async {
     final RunResult tasksRunResult = await globals.processUtils.run(
-      <String>[globals.gradleUtils!.getExecutable(project), 'app:tasks', '--all', '--console=auto'],
+      <String>[
+        ...globals.gradleUtils!.getExecutable(project),
+        'app:tasks',
+        '--all',
+        '--console=auto',
+      ],
       throwOnError: true,
       workingDirectory: project.android.hostAppGradleRoot.path,
       environment: globals.java?.environment,
--- a/packages/flutter_tools/lib/src/android/gradle_utils.dart
+++ b/packages/flutter_tools/lib/src/android/gradle_utils.dart
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 import 'package:meta/meta.dart';
+import 'package:path/path.dart';
 import 'package:process/process.dart';
 import 'package:unified_analytics/unified_analytics.dart';
 
@@ -154,9 +155,16 @@ class GradleUtils {
   final Logger _logger;
   final OperatingSystemUtils _operatingSystemUtils;
 
+  List<String> get _requiredArguments => <String>[
+    '--project-cache-dir=${join(switch (globals.platform.environment['XDG_CACHE_HOME']) {
+      final String cacheHome => cacheHome,
+      _ => join(globals.fsUtils.homeDirPath ?? throwToolExit('No cache directory has been specified.'), '.cache'),
+    }, 'flutter', 'nix-flutter-tools-gradle', globals.flutterVersion.engineRevision.substring(0, 10), 'cache')}',
+  ];
+
   /// Gets the Gradle executable path and prepares the Gradle project.
   /// This is the `gradlew` or `gradlew.bat` script in the `android/` directory.
-  String getExecutable(FlutterProject project) {
+  List<String> getExecutable(FlutterProject project) {
     final Directory androidDir = project.android.hostAppGradleRoot;
     injectGradleWrapperIfNeeded(androidDir);
 
@@ -167,7 +175,7 @@ class GradleUtils {
       // If the Gradle executable doesn't have execute permission,
       // then attempt to set it.
       _operatingSystemUtils.makeExecutable(gradle);
-      return gradle.absolute.path;
+      return <String>[gradle.absolute.path, ..._requiredArguments];
     }
     throwToolExit(
       'Unable to locate gradlew script. Please check that ${gradle.path} '
--- a/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart
+++ b/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart
@@ -2740,8 +2740,8 @@ Gradle Crashed
 
 class FakeGradleUtils extends Fake implements GradleUtils {
   @override
-  String getExecutable(FlutterProject project) {
-    return 'gradlew';
+  List<String> getExecutable(FlutterProject project) {
+    return const <String>['gradlew'];
   }
 }
 
--- a/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart
+++ b/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart
@@ -1580,8 +1580,8 @@ Platform fakePlatform(String name) {
 
 class FakeGradleUtils extends Fake implements GradleUtils {
   @override
-  String getExecutable(FlutterProject project) {
-    return 'gradlew';
+  List<String> getExecutable(FlutterProject project) {
+    return const <String>['gradlew'];
   }
 }
 
+158 −6
Original line number Diff line number Diff line
@@ -15,11 +15,9 @@ The intermediate project makes a `settings.gradle` file in `$HOME/.cache/flutter
This Gradle project will build the actual `packages/flutter_tools/gradle` project by setting
`rootProject.projectDir = new File("$settingsDir")` and `apply from: new File("$settingsDir/settings.gradle.kts")`.

Now the `.gradle` will be built in `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/`, but `build` doesn't.
To move `build` to `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/` as well, we need to set `buildDirectory`.
diff --git a/packages/flutter_tools/gradle/settings.gradle b/packages/flutter_tools/gradle/settings.gradle
new file mode 100644
index 0000000000..b2485c94b4
To move `build` to `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/`, we need to set `buildDirectory`.
To move `.gradle` as well, the `--project-cache-dir` argument must be passed to the Gradle wrapper.
Changing the `GradleUtils.getExecutable` function signature is a delibarate choice, to ensure that no new unpatched usages slip in.
--- /dev/null
+++ b/packages/flutter_tools/gradle/settings.gradle
@@ -0,0 +1,19 @@
@@ -44,12 +42,166 @@ index 0000000000..b2485c94b4
+includeBuild(dir)
--- a/packages/flutter_tools/gradle/build.gradle.kts
+++ b/packages/flutter_tools/gradle/build.gradle.kts
@@ -4,6 +4,8 @@
@@ -4,6 +4,11 @@
 
 import org.jetbrains.kotlin.gradle.dsl.JvmTarget
 
+// While flutter_tools runs Gradle with a --project-cache-dir, this startParameter
+// is not passed correctly to the Kotlin Gradle plugin for some reason, and so
+// must be set here as well.
+gradle.startParameter.projectCacheDir = layout.buildDirectory.dir("cache").get().asFile
+
 plugins {
     `java-gradle-plugin`
     groovy
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -456,9 +456,9 @@ class AndroidGradleBuilder implements AndroidBuilder {
     // from the local.properties file.
     updateLocalProperties(project: project, buildInfo: androidBuildInfo.buildInfo);
 
-    final List<String> options = <String>[];
-
-    final String gradleExecutablePath = _gradleUtils.getExecutable(project);
+    final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
+      project,
+    );
 
     // All automatically created files should exist.
     if (configOnly) {
@@ -781,7 +781,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
       'aar_init_script.gradle',
     );
     final List<String> command = <String>[
-      _gradleUtils.getExecutable(project),
+      ..._gradleUtils.getExecutable(project),
       '-I=$initScript',
       '-Pflutter-root=$flutterRoot',
       '-Poutput-dir=${outputDirectory.path}',
@@ -896,6 +896,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
     final List<String> results = <String>[];
 
     try {
+      final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
+        project,
+      );
+
       exitCode = await _runGradleTask(
         _kBuildVariantTaskName,
         preRunTask: () {
@@ -911,10 +915,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
             ),
           );
         },
-        options: const <String>['-q'],
+        options: <String>[...options, '-q'],
         project: project,
         localGradleErrors: gradleErrors,
-        gradleExecutablePath: _gradleUtils.getExecutable(project),
+        gradleExecutablePath: gradleExecutablePath,
         outputParser: (String line) {
           if (_kBuildVariantRegex.firstMatch(line) case final RegExpMatch match) {
             results.add(match.namedGroup(_kBuildVariantRegexGroupName)!);
@@ -948,6 +952,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
     late Stopwatch sw;
     int exitCode = 1;
     try {
+      final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
+        project,
+      );
+
       exitCode = await _runGradleTask(
         taskName,
         preRunTask: () {
@@ -963,10 +971,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
             ),
           );
         },
-        options: <String>['-q', '-PoutputPath=$outputPath'],
+        options: <String>[...options, '-q', '-PoutputPath=$outputPath'],
         project: project,
         localGradleErrors: gradleErrors,
-        gradleExecutablePath: _gradleUtils.getExecutable(project),
+        gradleExecutablePath: gradleExecutablePath,
       );
     } on Error catch (error) {
       _logger.printError(error.toString());
--- a/packages/flutter_tools/lib/src/android/gradle_errors.dart
+++ b/packages/flutter_tools/lib/src/android/gradle_errors.dart
@@ -240,7 +240,12 @@ final GradleHandledError flavorUndefinedHandler = GradleHandledError(
     required bool usesAndroidX,
   }) async {
     final RunResult tasksRunResult = await globals.processUtils.run(
-      <String>[globals.gradleUtils!.getExecutable(project), 'app:tasks', '--all', '--console=auto'],
+      <String>[
+        ...globals.gradleUtils!.getExecutable(project),
+        'app:tasks',
+        '--all',
+        '--console=auto',
+      ],
       throwOnError: true,
       workingDirectory: project.android.hostAppGradleRoot.path,
       environment: globals.java?.environment,
--- a/packages/flutter_tools/lib/src/android/gradle_utils.dart
+++ b/packages/flutter_tools/lib/src/android/gradle_utils.dart
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 import 'package:meta/meta.dart';
+import 'package:path/path.dart';
 import 'package:process/process.dart';
 import 'package:unified_analytics/unified_analytics.dart';
 
@@ -154,9 +155,16 @@ class GradleUtils {
   final Logger _logger;
   final OperatingSystemUtils _operatingSystemUtils;
 
+  List<String> get _requiredArguments => <String>[
+    '--project-cache-dir=${join(switch (globals.platform.environment['XDG_CACHE_HOME']) {
+      final String cacheHome => cacheHome,
+      _ => join(globals.fsUtils.homeDirPath ?? throwToolExit('No cache directory has been specified.'), '.cache'),
+    }, 'flutter', 'nix-flutter-tools-gradle', globals.flutterVersion.engineRevision.substring(0, 10), 'cache')}',
+  ];
+
   /// Gets the Gradle executable path and prepares the Gradle project.
   /// This is the `gradlew` or `gradlew.bat` script in the `android/` directory.
-  String getExecutable(FlutterProject project) {
+  List<String> getExecutable(FlutterProject project) {
     final Directory androidDir = project.android.hostAppGradleRoot;
     injectGradleWrapperIfNeeded(androidDir);
 
@@ -167,7 +175,7 @@ class GradleUtils {
       // If the Gradle executable doesn't have execute permission,
       // then attempt to set it.
       _operatingSystemUtils.makeExecutable(gradle);
-      return gradle.absolute.path;
+      return <String>[gradle.absolute.path, ..._requiredArguments];
     }
     throwToolExit(
       'Unable to locate gradlew script. Please check that ${gradle.path} '
--- a/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart
+++ b/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart
@@ -2740,8 +2740,8 @@ Gradle Crashed
 
 class FakeGradleUtils extends Fake implements GradleUtils {
   @override
-  String getExecutable(FlutterProject project) {
-    return 'gradlew';
+  List<String> getExecutable(FlutterProject project) {
+    return const <String>['gradlew'];
   }
 }
 
--- a/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart
+++ b/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart
@@ -1580,8 +1580,8 @@ Platform fakePlatform(String name) {
 
 class FakeGradleUtils extends Fake implements GradleUtils {
   @override
-  String getExecutable(FlutterProject project) {
-    return 'gradlew';
+  List<String> getExecutable(FlutterProject project) {
+    return const <String>['gradlew'];
   }
 }