Skip to content

Commit ce44ebb

Browse files
authored
Kgp bulk update (#10412)
Add kgp to plugins bulk update dependency tooling. ## Pre-Review Checklist **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent 4385dea commit ce44ebb

File tree

2 files changed

+188
-14
lines changed

2 files changed

+188
-14
lines changed

script/tool/lib/src/update_dependency_command.dart

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class UpdateDependencyCommand extends PackageLoopingCommand {
4545
allowed: <String>[
4646
_AndroidDependencyType.gradle,
4747
_AndroidDependencyType.androidGradlePlugin,
48+
_AndroidDependencyType.kotlinGradlePlugin,
4849
_AndroidDependencyType.compileSdk,
4950
_AndroidDependencyType.compileSdkForExamples,
5051
],
@@ -53,6 +54,8 @@ class UpdateDependencyCommand extends PackageLoopingCommand {
5354
'Updates Gradle version used in plugin example apps.',
5455
_AndroidDependencyType.androidGradlePlugin:
5556
'Updates AGP version used in plugin example apps.',
57+
_AndroidDependencyType.kotlinGradlePlugin:
58+
'Updates KGP version used in plugin example apps.',
5659
_AndroidDependencyType.compileSdk:
5760
'Updates compileSdk version used to compile plugins.',
5861
_AndroidDependencyType.compileSdkForExamples:
@@ -155,6 +158,19 @@ A version with a valid format (maximum 2-3 numbers separated by 1-2 periods) mus
155158
3. If present, the third number must have a single digit''');
156159
throw ToolExit(_exitInvalidTargetVersion);
157160
}
161+
} else if (_targetAndroidDependency ==
162+
_AndroidDependencyType.kotlinGradlePlugin) {
163+
final RegExp validKgpVersionPattern = RegExp(r'^\d\.\d\.\d{1,2}$');
164+
final bool isValidKgpVersion =
165+
validKgpVersionPattern.stringMatch(version) == version;
166+
if (!isValidKgpVersion) {
167+
printError('''
168+
A version with a valid format (3 numbers separated by 2 periods) must be provided.
169+
1. The first number must have one digit
170+
2. The second number must have one digit
171+
3. The third number must have one or two digits''');
172+
throw ToolExit(_exitInvalidTargetVersion);
173+
}
158174
} else if (_targetAndroidDependency ==
159175
_AndroidDependencyType.compileSdk ||
160176
_targetAndroidDependency ==
@@ -266,7 +282,8 @@ A version with a valid format (maximum 2-3 numbers separated by 1-2 periods) mus
266282
_targetAndroidDependency ==
267283
_AndroidDependencyType.compileSdkForExamples ||
268284
_targetAndroidDependency ==
269-
_AndroidDependencyType.androidGradlePlugin) {
285+
_AndroidDependencyType.androidGradlePlugin ||
286+
_targetAndroidDependency == _AndroidDependencyType.kotlinGradlePlugin) {
270287
return _runForAndroidDependencyOnExamples(package);
271288
}
272289

@@ -334,7 +351,17 @@ A version with a valid format (maximum 2-3 numbers separated by 1-2 periods) mus
334351
r'^\s*id\s+"com\.android\.application"\s+version\s+"(\d{1,2}\.\d{1,2}(?:\.\d)?)"\s+apply\s+false\s*$',
335352
multiLine: true);
336353
newDependencyVersionEntry =
337-
' id "com.android.application" version "$_targetVersion" apply false';
354+
'id "com.android.application" version "$_targetVersion" apply false';
355+
} else if (_targetAndroidDependency ==
356+
_AndroidDependencyType.kotlinGradlePlugin) {
357+
if (androidDirectory.childFile('settings.gradle').existsSync()) {
358+
filesToUpdate.add(androidDirectory.childFile('settings.gradle'));
359+
}
360+
dependencyVersionPattern = RegExp(
361+
r'^\s*id\s+"org\.jetbrains\.kotlin\.android"\s+version\s+"(\d\.\d\.\d{1,2})"\s+apply\s+false\s*$',
362+
multiLine: true);
363+
newDependencyVersionEntry =
364+
' id "org.jetbrains.kotlin.android" version "$_targetVersion" apply false';
338365
} else {
339366
printError(
340367
'Target Android dependency $_targetAndroidDependency is unrecognized.');
@@ -525,6 +552,7 @@ enum _PubDependencyType { normal, dev }
525552
class _AndroidDependencyType {
526553
static const String gradle = 'gradle';
527554
static const String androidGradlePlugin = 'androidGradlePlugin';
555+
static const String kotlinGradlePlugin = 'kotlinGradlePlugin';
528556
static const String compileSdk = 'compileSdk';
529557
static const String compileSdkForExamples = 'compileSdkForExamples';
530558
}

script/tool/test/update_dependency_command_test.dart

Lines changed: 158 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,18 @@ dev_dependencies:
614614
'8.12.12'
615615
];
616616

617+
const String invalidGradleAgpVersionError = '''
618+
A version with a valid format (maximum 2-3 numbers separated by 1-2 periods) must be provided.
619+
1. The first number must have one or two digits
620+
2. The second number must have one or two digits
621+
3. If present, the third number must have a single digit''';
622+
623+
const String invalidKgpVersionError = '''
624+
A version with a valid format (3 numbers separated by 2 periods) must be provided.
625+
1. The first number must have one digit
626+
2. The second number must have one digit
627+
3. The third number must have one or two digits''';
628+
617629
group('gradle', () {
618630
for (final String gradleVersion in invalidGradleAgpVersionsFormat) {
619631
test('throws because gradleVersion: $gradleVersion is invalid',
@@ -633,11 +645,7 @@ dev_dependencies:
633645
expect(
634646
output,
635647
containsAllInOrder(<Matcher>[
636-
contains('''
637-
A version with a valid format (maximum 2-3 numbers separated by 1-2 periods) must be provided.
638-
1. The first number must have one or two digits
639-
2. The second number must have one or two digits
640-
3. If present, the third number must have a single digit'''),
648+
contains(invalidGradleAgpVersionError),
641649
]),
642650
);
643651
});
@@ -925,11 +933,7 @@ distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
925933
expect(
926934
output,
927935
containsAllInOrder(<Matcher>[
928-
contains('''
929-
A version with a valid format (maximum 2-3 numbers separated by 1-2 periods) must be provided.
930-
1. The first number must have one or two digits
931-
2. The second number must have one or two digits
932-
3. If present, the third number must have a single digit'''),
936+
contains(invalidGradleAgpVersionError),
933937
]),
934938
);
935939
});
@@ -994,7 +998,7 @@ plugins {
994998

995999
expect(
9961000
updatedGradleSettingsContents,
997-
contains(r' id "com.android.application" version '
1001+
contains(r'id "com.android.application" version '
9981002
'"$newAgpVersion" apply false'));
9991003
});
10001004

@@ -1037,10 +1041,152 @@ plugins {
10371041

10381042
expect(
10391043
updatedGradleSettingsContents,
1040-
contains(r' id "com.android.application" version '
1044+
contains(r'id "com.android.application" version '
10411045
'"$newAgpVersion" apply false'));
10421046
});
10431047
});
1048+
group('kgp', () {
1049+
final List<String> invalidKgpVersionsFormat = <String>[
1050+
'81',
1051+
'81.1',
1052+
'8.123',
1053+
'8.12.12',
1054+
'8.12.1',
1055+
];
1056+
1057+
for (final String kgpVersion in invalidKgpVersionsFormat) {
1058+
test('throws because kgpVersion: $kgpVersion is invalid', () async {
1059+
Error? commandError;
1060+
final List<String> output = await runCapturingPrint(runner, <String>[
1061+
'update-dependency',
1062+
'--android-dependency',
1063+
'kotlinGradlePlugin',
1064+
'--version',
1065+
kgpVersion,
1066+
], errorHandler: (Error e) {
1067+
commandError = e;
1068+
});
1069+
1070+
expect(commandError, isA<ToolExit>());
1071+
expect(
1072+
output,
1073+
containsAllInOrder(<Matcher>[
1074+
contains(invalidKgpVersionError),
1075+
]),
1076+
);
1077+
});
1078+
}
1079+
1080+
test('skips if example app does not run on Android', () async {
1081+
final RepositoryPackage package =
1082+
createFakePlugin('fake_plugin', packagesDir);
1083+
1084+
final List<String> output = await runCapturingPrint(runner, <String>[
1085+
'update-dependency',
1086+
'--packages',
1087+
package.displayName,
1088+
'--android-dependency',
1089+
'kotlinGradlePlugin',
1090+
'--version',
1091+
'2.2.20',
1092+
], errorHandler: (Error e) {
1093+
print((e as ToolExit).stackTrace);
1094+
});
1095+
1096+
expect(
1097+
output,
1098+
containsAllInOrder(<Matcher>[
1099+
contains('SKIPPING: No example apps run on Android.'),
1100+
]),
1101+
);
1102+
});
1103+
1104+
test('succeeds if example app has android/settings.gradle structure',
1105+
() async {
1106+
final RepositoryPackage package = createFakePlugin(
1107+
'fake_plugin', packagesDir,
1108+
extraFiles: <String>['example/android/settings.gradle']);
1109+
const String newKgpVersion = '2.2.20';
1110+
1111+
final File gradleSettingsFile = package.directory
1112+
.childDirectory('example')
1113+
.childDirectory('android')
1114+
.childFile('settings.gradle');
1115+
1116+
gradleSettingsFile.writeAsStringSync(r'''
1117+
...
1118+
plugins {
1119+
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
1120+
...
1121+
id "org.jetbrains.kotlin.android" version "2.2.20" apply false
1122+
...
1123+
}
1124+
...
1125+
''');
1126+
1127+
await runCapturingPrint(runner, <String>[
1128+
'update-dependency',
1129+
'--packages',
1130+
package.displayName,
1131+
'--android-dependency',
1132+
'kotlinGradlePlugin',
1133+
'--version',
1134+
newKgpVersion,
1135+
]);
1136+
1137+
final String updatedGradleSettingsContents =
1138+
gradleSettingsFile.readAsStringSync();
1139+
1140+
expect(
1141+
updatedGradleSettingsContents,
1142+
contains(r' id "org.jetbrains.kotlin.android" version '
1143+
'"$newKgpVersion" apply false'));
1144+
});
1145+
1146+
test('succeeds if one example app runs on Android and another does not',
1147+
() async {
1148+
final RepositoryPackage package = createFakePlugin(
1149+
'fake_plugin', packagesDir,
1150+
examples: <String>['example_1', 'example_2'],
1151+
extraFiles: <String>['example/example_2/android/settings.gradle']);
1152+
const String newKgpVersion = '2.2.20';
1153+
1154+
final File gradleSettingsFile = package.directory
1155+
.childDirectory('example')
1156+
.childDirectory('example_2')
1157+
.childDirectory('android')
1158+
.childFile('settings.gradle');
1159+
1160+
gradleSettingsFile.writeAsStringSync(r'''
1161+
...
1162+
plugins {
1163+
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
1164+
...
1165+
id "org.jetbrains.kotlin.android" version "2.2.20" apply false
1166+
...
1167+
}
1168+
...
1169+
''');
1170+
1171+
await runCapturingPrint(runner, <String>[
1172+
'update-dependency',
1173+
'--packages',
1174+
package.displayName,
1175+
'--android-dependency',
1176+
'kotlinGradlePlugin',
1177+
'--version',
1178+
newKgpVersion,
1179+
]);
1180+
1181+
final String updatedGradleSettingsContents =
1182+
gradleSettingsFile.readAsStringSync();
1183+
1184+
expect(
1185+
updatedGradleSettingsContents,
1186+
contains(r' id "org.jetbrains.kotlin.android" version '
1187+
'"$newKgpVersion" apply false'));
1188+
});
1189+
});
10441190

10451191
group('compileSdk/compileSdkForExamples', () {
10461192
// Tests if the compileSdk version is updated for the provided

0 commit comments

Comments
 (0)