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 =