Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
dec3d69
Merge remote-tracking branch 'upstream/main' into camx_occ
camsim99 May 1, 2023
0e0333b
Merge remote-tracking branch 'upstream/main'
camsim99 May 2, 2023
bd7ac99
Merge remote-tracking branch 'upstream/main'
camsim99 May 3, 2023
5c3363b
Merge remote-tracking branch 'upstream/main'
camsim99 May 10, 2023
fed9621
Undo changes
camsim99 May 10, 2023
5aabe34
Merge remote-tracking branch 'upstream/main'
camsim99 May 12, 2023
2b9a352
Merge remote-tracking branch 'upstream/main'
camsim99 May 25, 2023
a1173da
Merge remote-tracking branch 'upstream/main'
camsim99 May 30, 2023
cbc3d6b
Merge remote-tracking branch 'upstream/main'
camsim99 May 30, 2023
cae5a4c
Merge remote-tracking branch 'upstream/main'
camsim99 Jun 1, 2023
72283db
Merge remote-tracking branch 'upstream/main'
camsim99 Jun 5, 2023
166a77c
Merge remote-tracking branch 'upstream/main'
camsim99 Jun 5, 2023
399780e
Merge remote-tracking branch 'upstream/main'
camsim99 Jun 14, 2023
8d5d0e7
Merge remote-tracking branch 'upstream/main'
camsim99 Jun 26, 2023
084d960
Merge remote-tracking branch 'upstream/main'
camsim99 Jul 12, 2023
d2a59ac
Merge remote-tracking branch 'upstream/main'
camsim99 Jul 17, 2023
a1422bf
Merge remote-tracking branch 'upstream/main'
camsim99 Jul 17, 2023
bdd87a6
Merge remote-tracking branch 'upstream/main'
camsim99 Jul 18, 2023
137a28b
Merge remote-tracking branch 'upstream/main'
camsim99 Jul 19, 2023
bc0db5a
Merge remote-tracking branch 'upstream/main'
camsim99 Jul 20, 2023
d04b466
Merge remote-tracking branch 'upstream/main'
camsim99 Jul 21, 2023
a9cfe87
Merge remote-tracking branch 'upstream/main'
camsim99 Jul 24, 2023
a32def1
Merge remote-tracking branch 'upstream/main'
camsim99 Aug 2, 2023
4785148
Merge remote-tracking branch 'upstream/main'
camsim99 Aug 14, 2023
7a8fc69
Merge remote-tracking branch 'upstream/main'
camsim99 Aug 15, 2023
b02e15f
Merge remote-tracking branch 'upstream/main'
camsim99 Aug 15, 2023
c6e5868
Merge remote-tracking branch 'upstream/main'
camsim99 Aug 17, 2023
0c0065a
Merge remote-tracking branch 'upstream/main'
camsim99 Aug 28, 2023
9dfe259
Merge remote-tracking branch 'upstream/main'
camsim99 Aug 29, 2023
bfcc0df
Merge remote-tracking branch 'upstream/main'
camsim99 Aug 30, 2023
b80cc86
Merge remote-tracking branch 'upstream/main'
camsim99 Sep 5, 2023
4663838
Merge remote-tracking branch 'upstream/main'
camsim99 Sep 13, 2023
33fe515
Merge remote-tracking branch 'upstream/main'
camsim99 Sep 21, 2023
0c34fb6
Merge remote-tracking branch 'upstream/main'
camsim99 Sep 26, 2023
bb26ca9
Start adding compileSdk option
camsim99 Sep 26, 2023
b36ff96
Add replcement logic
camsim99 Sep 27, 2023
4c839ed
Start adding tests for compileSdk, change dep names
camsim99 Oct 9, 2023
23c82b0
Add temp fix for examples, add all tests
camsim99 Oct 10, 2023
c6fa8aa
self review
camsim99 Oct 23, 2023
f69b14a
Merge remote-tracking branch 'upstream/main' into ud_compilesdk
camsim99 Oct 23, 2023
bef8ff2
Modify command
camsim99 Oct 23, 2023
e7aa7c3
Merge remote-tracking branch 'upstream/main' into ud_compilesdk
camsim99 Oct 24, 2023
16c6024
Add isExample
camsim99 Oct 24, 2023
8e08aee
Remove unused import
camsim99 Oct 24, 2023
de8ad84
Merge branch 'main' into ud_compilesdk
camsim99 Oct 25, 2023
fe8f758
Address review
camsim99 Oct 31, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions script/tool/lib/src/common/repository_package.dart
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,18 @@ class RepositoryPackage {
!isPlatformInterface &&
directory.basename != directory.parent.basename;

/// True if this appears to be an example package, according to package
/// conventions.
bool get isExample {
final RepositoryPackage? enclosingPackage = getEnclosingPackage();
if (enclosingPackage == null) {
// An example package is enclosed in another package.
return false;
}
// Check whether this is one of the enclosing package's examples.
return enclosingPackage.getExamples().any((RepositoryPackage p) => p.path == path);
}

/// Returns the Flutter example packages contained in the package, if any.
Iterable<RepositoryPackage> getExamples() {
final Directory exampleDirectory = directory.childDirectory('example');
Expand Down
176 changes: 127 additions & 49 deletions script/tool/lib/src/update_dependency_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,17 @@ class UpdateDependencyCommand extends PackageLoopingCommand {
argParser.addOption(_androidDependency,
help: 'An Android dependency to update.',
allowed: <String>[
'gradle',
_AndroidDepdencyType.gradle,
_AndroidDepdencyType.compileSdk,
_AndroidDepdencyType.compileSdkForExamples,
],
allowedHelp: <String, String>{
'gradle': 'Updates Gradle version used in plugin example apps.',
_AndroidDepdencyType.gradle:
'Updates Gradle version used in plugin example apps.',
_AndroidDepdencyType.compileSdk:
'Updates compileSdk version used to compile plugins.',
_AndroidDepdencyType.compileSdkForExamples:
'Updates compileSdk version used to compile plugin examples.',
});
argParser.addOption(
_versionFlag,
Expand Down Expand Up @@ -130,7 +137,7 @@ ${response.httpResponse.body}
if (version == null) {
printError('A version must be provided to update this dependency.');
throw ToolExit(_exitNoTargetVersion);
} else if (_targetAndroidDependency == 'gradle') {
} else if (_targetAndroidDependency == _AndroidDepdencyType.gradle) {
final RegExp validGradleVersionPattern = RegExp(r'^\d+(?:\.\d+){1,2}$');
final bool isValidGradleVersion =
validGradleVersionPattern.stringMatch(version) == version;
Expand All @@ -139,14 +146,24 @@ ${response.httpResponse.body}
'A version with a valid format (maximum 2-3 numbers separated by period) must be provided.');
throw ToolExit(_exitInvalidTargetVersion);
}
_targetVersion = version;
return;
} else if (_targetAndroidDependency == _AndroidDepdencyType.compileSdk ||
_targetAndroidDependency ==
_AndroidDepdencyType.compileSdkForExamples) {
final RegExp validSdkVersion = RegExp(r'^\d{1,2}$');
final bool isValidSdkVersion =
validSdkVersion.stringMatch(version) == version;
if (!isValidSdkVersion) {
printError(
'A valid Android SDK version number (1-2 digit numbers) must be provided.');
throw ToolExit(_exitInvalidTargetVersion);
}
} else {
// TODO(camsim99): Add other supported Android dependencies like the Android SDK and AGP.
// TODO(camsim99): Add other supported Android dependencies like the min/target Android SDK and AGP.
printError(
'Target Android dependency $_targetAndroidDependency is unrecognized.');
throw ToolExit(_exitIncorrectTargetDependency);
}
_targetVersion = version;
}
}

Expand Down Expand Up @@ -233,59 +250,114 @@ ${response.httpResponse.body}
/// an Android dependency.
Future<PackageResult> _runForAndroidDependency(
RepositoryPackage package) async {
if (_targetAndroidDependency == 'gradle') {
final Iterable<RepositoryPackage> packageExamples = package.getExamples();
bool updateRanForExamples = false;
for (final RepositoryPackage example in packageExamples) {
if (!example.platformDirectory(FlutterPlatform.android).existsSync()) {
continue;
}
if (_targetAndroidDependency == _AndroidDepdencyType.compileSdk) {
return _runForCompileSdkVersion(package);
} else if (_targetAndroidDependency == _AndroidDepdencyType.gradle ||
_targetAndroidDependency ==
_AndroidDepdencyType.compileSdkForExamples) {
return _runForAndroidDependencyOnExamples(package);
}

updateRanForExamples = true;
Directory gradleWrapperPropertiesDirectory =
example.platformDirectory(FlutterPlatform.android);
if (gradleWrapperPropertiesDirectory
return PackageResult.fail(<String>[
'Target Android dependency $_androidDependency is unrecognized.'
]);
}

Future<PackageResult> _runForAndroidDependencyOnExamples(
RepositoryPackage package) async {
final Iterable<RepositoryPackage> packageExamples = package.getExamples();
bool updateRanForExamples = false;
for (final RepositoryPackage example in packageExamples) {
if (!example.platformDirectory(FlutterPlatform.android).existsSync()) {
continue;
}

updateRanForExamples = true;
Directory androidDirectory =
example.platformDirectory(FlutterPlatform.android);
final File fileToUpdate;
final RegExp dependencyVersionPattern;
final String newDependencyVersionEntry;

if (_targetAndroidDependency == _AndroidDepdencyType.gradle) {
if (androidDirectory
.childDirectory('app')
.childDirectory('gradle')
.existsSync()) {
gradleWrapperPropertiesDirectory =
gradleWrapperPropertiesDirectory.childDirectory('app');
androidDirectory = androidDirectory.childDirectory('app');
}
final File gradleWrapperPropertiesFile =
gradleWrapperPropertiesDirectory
.childDirectory('gradle')
.childDirectory('wrapper')
.childFile('gradle-wrapper.properties');

final String gradleWrapperPropertiesContents =
gradleWrapperPropertiesFile.readAsStringSync();
final RegExp validGradleDistributionUrl =
fileToUpdate = androidDirectory
.childDirectory('gradle')
.childDirectory('wrapper')
.childFile('gradle-wrapper.properties');
dependencyVersionPattern =
RegExp(r'^\s*distributionUrl\s*=\s*.*\.zip', multiLine: true);
if (!validGradleDistributionUrl
.hasMatch(gradleWrapperPropertiesContents)) {
return PackageResult.fail(<String>[
'Unable to find a "distributionUrl" entry to update for ${package.displayName}.'
]);
}

print(
'${indentation}Updating ${getRelativePosixPath(example.directory, from: package.directory)} to "$_targetVersion"');
final String newGradleWrapperPropertiesContents =
gradleWrapperPropertiesContents.replaceFirst(
validGradleDistributionUrl,
'distributionUrl=https\\://services.gradle.org/distributions/gradle-$_targetVersion-all.zip');
// TODO(camsim99): Validate current AGP version against target Gradle
// version: https://github.com/flutter/flutter/issues/133887.
gradleWrapperPropertiesFile
.writeAsStringSync(newGradleWrapperPropertiesContents);
newDependencyVersionEntry =
'distributionUrl=https\\://services.gradle.org/distributions/gradle-$_targetVersion-all.zip';
} else if (_targetAndroidDependency ==
_AndroidDepdencyType.compileSdkForExamples) {
fileToUpdate =
androidDirectory.childDirectory('app').childFile('build.gradle');
dependencyVersionPattern = RegExp(
r'(compileSdk|compileSdkVersion) (\d{1,2}|flutter.compileSdkVersion)');
newDependencyVersionEntry = 'compileSdk $_targetVersion';
} else {
printError(
'Target Android dependency $_targetAndroidDependency is unrecognized.');
throw ToolExit(_exitIncorrectTargetDependency);
}

final String oldFileToUpdateContents = fileToUpdate.readAsStringSync();

if (!dependencyVersionPattern.hasMatch(oldFileToUpdateContents)) {
return PackageResult.fail(<String>[
'Unable to find a $_targetAndroidDependency version entry to update for ${example.displayName}.'
]);
}
return updateRanForExamples
? PackageResult.success()
: PackageResult.skip('No example apps run on Android.');

print(
'${indentation}Updating ${getRelativePosixPath(example.directory, from: package.directory)} to "$_targetVersion"');
final String newGradleWrapperPropertiesContents = oldFileToUpdateContents
.replaceFirst(dependencyVersionPattern, newDependencyVersionEntry);

fileToUpdate.writeAsStringSync(newGradleWrapperPropertiesContents);
}
return PackageResult.fail(<String>[
'Target Android dependency $_androidDependency is unrecognized.'
]);
return updateRanForExamples
? PackageResult.success()
: PackageResult.skip('No example apps run on Android.');
}

Future<PackageResult> _runForCompileSdkVersion(
RepositoryPackage package) async {
if (!package.platformDirectory(FlutterPlatform.android).existsSync()) {
return PackageResult.skip(
'Package ${package.displayName} does not run on Android.');
} else if (package.isExample) {
// We skip examples for this command.
return PackageResult.skip(
'Package ${package.displayName} is not a top-level package; run with "compileSdkForExamples" to update.');
}
final File buildConfigurationFile = package
.platformDirectory(FlutterPlatform.android)
.childFile('build.gradle');
final String buildConfigurationContents =
buildConfigurationFile.readAsStringSync();
final RegExp validCompileSdkVersion =
RegExp(r'(compileSdk|compileSdkVersion) \d{1,2}');

if (!validCompileSdkVersion.hasMatch(buildConfigurationContents)) {
return PackageResult.fail(<String>[
'Unable to find a compileSdk version entry to update for ${package.displayName}.'
]);
}
print('${indentation}Updating ${package.directory} to "$_targetVersion"');
final String newBuildConfigurationContents = buildConfigurationContents
.replaceFirst(validCompileSdkVersion, 'compileSdk $_targetVersion');
buildConfigurationFile.writeAsStringSync(newBuildConfigurationContents);

return PackageResult.success();
}

/// Returns information about the current dependency of [package] on
Expand Down Expand Up @@ -414,3 +486,9 @@ class _PubDependencyInfo {
}

enum _PubDependencyType { normal, dev }

class _AndroidDepdencyType {
static const String gradle = 'gradle';
static const String compileSdk = 'compileSdk';
static const String compileSdkForExamples = 'compileSdkForExamples';
}
10 changes: 10 additions & 0 deletions script/tool/test/common/repository_package_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ void main() {
final List<RepositoryPackage> examples = plugin.getExamples().toList();

expect(examples.length, 1);
expect(examples[0].isExample, isTrue);
expect(examples[0].path, getExampleDir(plugin).path);
});

Expand All @@ -112,6 +113,8 @@ void main() {
final List<RepositoryPackage> examples = plugin.getExamples().toList();

expect(examples.length, 2);
expect(examples[0].isExample, isTrue);
expect(examples[1].isExample, isTrue);
expect(examples[0].path,
getExampleDir(plugin).childDirectory('example1').path);
expect(examples[1].path,
Expand All @@ -125,6 +128,7 @@ void main() {
final List<RepositoryPackage> examples = package.getExamples().toList();

expect(examples.length, 1);
expect(examples[0].isExample, isTrue);
expect(examples[0].path, getExampleDir(package).path);
});

Expand All @@ -136,6 +140,8 @@ void main() {
final List<RepositoryPackage> examples = package.getExamples().toList();

expect(examples.length, 2);
expect(examples[0].isExample, isTrue);
expect(examples[1].isExample, isTrue);
expect(examples[0].path,
getExampleDir(package).childDirectory('example1').path);
expect(examples[1].path,
Expand All @@ -151,6 +157,7 @@ void main() {
expect(plugin.isAppFacing, false);
expect(plugin.isPlatformInterface, false);
expect(plugin.isFederated, false);
expect(plugin.isExample, isFalse);
});

test('handle app-facing packages', () {
Expand All @@ -160,6 +167,7 @@ void main() {
expect(plugin.isAppFacing, true);
expect(plugin.isPlatformInterface, false);
expect(plugin.isPlatformImplementation, false);
expect(plugin.isExample, isFalse);
});

test('handle platform interface packages', () {
Expand All @@ -170,6 +178,7 @@ void main() {
expect(plugin.isAppFacing, false);
expect(plugin.isPlatformInterface, true);
expect(plugin.isPlatformImplementation, false);
expect(plugin.isExample, isFalse);
});

test('handle platform implementation packages', () {
Expand All @@ -181,6 +190,7 @@ void main() {
expect(plugin.isAppFacing, false);
expect(plugin.isPlatformInterface, false);
expect(plugin.isPlatformImplementation, true);
expect(plugin.isExample, isFalse);
});
});

Expand Down
Loading