From 052be9c41aace24561a35659a1c883b4b6e7db11 Mon Sep 17 00:00:00 2001 From: Gray Mackall <34871572+gmackall@users.noreply.github.com> Date: Mon, 3 Feb 2025 18:07:16 -0800 Subject: [PATCH] Update `generate_gradle_lockfiles.dart` to handle batch updating kotlin Gradle files (#162628) Also removes the only entry from the exclusion script, as this fixes the reason for its exclusion. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md --------- Co-authored-by: Gray Mackall --- dev/tools/bin/config/lockfile_exclusion.yaml | 7 +- dev/tools/bin/generate_gradle_lockfiles.dart | 123 ++++++++++++++++-- examples/hello_world/android/build.gradle.kts | 6 +- .../hello_world/android/settings.gradle.kts | 6 +- 4 files changed, 119 insertions(+), 23 deletions(-) diff --git a/dev/tools/bin/config/lockfile_exclusion.yaml b/dev/tools/bin/config/lockfile_exclusion.yaml index 96c586197c..ef81a65925 100644 --- a/dev/tools/bin/config/lockfile_exclusion.yaml +++ b/dev/tools/bin/config/lockfile_exclusion.yaml @@ -2,11 +2,8 @@ # Each exclusion must have an associated reason. Please avoid adding to this list unless necessary, # as each exclusion must be updated by hand. -# hello_world uses a Kotlin Gradle settings file (settings.gradle.kts). We don't have a template -# Kotlin Gradle settings file (only a groovy one), so we currently can't generate it. -- examples/hello_world/android -# Also uses kts files. -- dev/integration_tests/display_cutout_rotation/android +# There are currently no entries :) but if you wanted to add one, the format would be +# - made/up/path/flutter_create_name/android # The following files must also be manually updated at the moment, because they don't use a # lib/main.dart (but they don't need exclusion, as we already skip that case). diff --git a/dev/tools/bin/generate_gradle_lockfiles.dart b/dev/tools/bin/generate_gradle_lockfiles.dart index 90346dcd63..acd607d22a 100644 --- a/dev/tools/bin/generate_gradle_lockfiles.dart +++ b/dev/tools/bin/generate_gradle_lockfiles.dart @@ -83,9 +83,10 @@ void main(List arguments) { final Set exclusionSet; if (useExclusion) { exclusionSet = HashSet.from( - (loadYaml(exclusionFile.readAsStringSync()) as YamlList).toList().cast().map( - (String s) => '${repoRoot.path}/$s', - ), + ((loadYaml(exclusionFile.readAsStringSync()) ?? YamlList()) as YamlList) + .toList() + .cast() + .map((String s) => '${repoRoot.path}/$s'), ); print('Loaded exclusion file from ${exclusionFile.path}.'); } else { @@ -164,11 +165,6 @@ void main(List arguments) { continue; } - if (androidDirectory.path.contains('ios/.symlinks')) { - print('${rootBuildGradle.path} is in the ios subdirectory, skipping'); - continue; - } - print('Processing ${androidDirectory.path}'); try { @@ -178,8 +174,19 @@ void main(List arguments) { } if (gradleGeneration) { - rootBuildGradle.writeAsStringSync(rootGradleFileContent); - settingsGradle.writeAsStringSync(settingGradleFile); + // Write file content corresponding to original file language. + if (rootBuildGradle.basename.endsWith('.kts')) { + rootBuildGradle.writeAsStringSync(rootGradleKtsFileContent); + } else { + rootBuildGradle.writeAsStringSync(rootGradleFileContent); + } + + if (settingsGradle.basename.endsWith('.kts')) { + settingsGradle.writeAsStringSync(settingsGradleKtsFileContent); + } else { + settingsGradle.writeAsStringSync(settingGradleFileContent); + } + wrapperGradle.writeAsStringSync(wrapperGradleFileContent); } @@ -250,7 +257,7 @@ tasks.register("clean", Delete) { } '''; -const String settingGradleFile = r''' +const String settingGradleFileContent = r''' // Copyright 2014 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -294,6 +301,93 @@ plugins { include ":app" '''; +// Consider updating this file to reflect the latest updates to app templates +// when performing batch updates (this file is modeled after +// root_app/android/build.gradle.kts). +const String rootGradleKtsFileContent = r''' +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is auto generated. +// To update all the settings.gradle files in the Flutter repo, +// See dev/tools/bin/generate_gradle_lockfiles.dart. + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.layout.buildDirectory.value(rootProject.layout.buildDirectory.dir("../../build").get()) + +subprojects { + project.layout.buildDirectory.value(rootProject.layout.buildDirectory.dir(project.name).get()) +} +subprojects { + project.evaluationDependsOn(":app") + dependencyLocking { + ignoredDependencies.add("io.flutter:*") + lockFile = file("${rootProject.projectDir}/project-${project.name}.lockfile") + if (!project.hasProperty("local-engine-repo")) { + lockAllConfigurations() + } + } +} + +tasks.register("clean") { + delete(rootProject.layout.buildDirectory) +} +'''; + +// Consider updating this file to reflect the latest updates to app templates +// when performing batch updates (this file is modeled after +// root_app/android/settings.gradle.kts). +const String settingsGradleKtsFileContent = r''' +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is auto generated. +// To update all the settings.gradle files in the Flutter repo, +// See dev/tools/bin/generate_gradle_lockfiles.dart. + +pluginManagement { + val flutterSdkPath = + run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + val flutterSdkPath = properties.getProperty("flutter.sdk") + require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } + flutterSdkPath + } + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +buildscript { + dependencyLocking { + lockFile = file("${rootProject.projectDir}/buildscript-gradle.lockfile") + lockAllConfigurations() + } +} + +plugins { + id("dev.flutter.flutter-plugin-loader") version "1.0.0" + id("com.android.application") version "8.7.0" apply false + id("org.jetbrains.kotlin.android") version "1.8.22" apply false +} + +include(":app") +'''; + const String wrapperGradleFileContent = r''' distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists @@ -309,8 +403,13 @@ Iterable discoverAndroidDirectories(Directory repoRoot) { // Exclude the top-level "engine/" directory, which is not covered by the the tool. .where((Directory directory) => directory.basename != 'engine') // ... and then recurse into every directory (other than the excluded directory). - .expand((Directory d) => d.listSync(recursive: true)) + .expand((Directory directory) => directory.listSync(recursive: true)) .whereType() + // These directories are build artifacts which are not part of source control. + .where( + (Directory directory) => + !directory.path.contains('/build/') && !directory.path.contains('.symlinks'), + ) // ... where the directory ultimately is named "android". .where((FileSystemEntity entity) => entity.basename == 'android'); } diff --git a/examples/hello_world/android/build.gradle.kts b/examples/hello_world/android/build.gradle.kts index 42fe951ea1..1bcb0ad239 100644 --- a/examples/hello_world/android/build.gradle.kts +++ b/examples/hello_world/android/build.gradle.kts @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Contents of this file should be generated automatically by -// dev/tools/bin/generate_gradle_lockfiles.dart, but currently are not. -// See #141540. +// This file is auto generated. +// To update all the settings.gradle files in the Flutter repo, +// See dev/tools/bin/generate_gradle_lockfiles.dart. allprojects { repositories { diff --git a/examples/hello_world/android/settings.gradle.kts b/examples/hello_world/android/settings.gradle.kts index bae8e28a7e..7b83c06e53 100644 --- a/examples/hello_world/android/settings.gradle.kts +++ b/examples/hello_world/android/settings.gradle.kts @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Contents of this file should be generated automatically by -// dev/tools/bin/generate_gradle_lockfiles.dart, but currently are not. -// See #141540. +// This file is auto generated. +// To update all the settings.gradle files in the Flutter repo, +// See dev/tools/bin/generate_gradle_lockfiles.dart. pluginManagement { val flutterSdkPath =