[various] Conditionalize the namespace in all Android plugins (#3836)

The recent change to add `namespace` to all plugins broke builds for apps using AGP 4.1 or earlier. This conditionalizes setting the namespace based on whether the property exists at all, making it compatible with both AGP 8.0 and AGP <4.2.

Updates tooling to enforce this for plugin (but not example app) build.gradle files.

Fixes https://github.com/flutter/flutter/issues/125621
This commit is contained in:
stuartmorgan
2023-04-27 17:34:33 -07:00
committed by GitHub
parent 204764579f
commit a86beafa89
47 changed files with 206 additions and 38 deletions

View File

@ -153,13 +153,32 @@ class GradleCheckCommand extends PackageLoopingCommand {
RegExp('^\\s*namespace\\s+[\'"](.*?)[\'"]', multiLine: true);
final RegExpMatch? namespaceMatch =
namespaceRegex.firstMatch(gradleContents);
// For plugins, make sure the namespace is conditionalized so that it
// doesn't break client apps using AGP 4.1 and earlier (which don't have
// a namespace property, and will fail to build if it's set).
const String namespaceConditional =
'if (project.android.hasProperty("namespace"))';
String exampleSetNamespace = "namespace 'dev.flutter.foo'";
if (!isExample) {
exampleSetNamespace = '''
$namespaceConditional {
$exampleSetNamespace
}''';
}
// Wrap the namespace command in an `android` block, adding the indentation
// to make it line up correctly.
final String exampleAndroidNamespaceBlock = '''
android {
${exampleSetNamespace.split('\n').join('\n ')}
}
''';
if (namespaceMatch == null) {
const String errorMessage = '''
final String errorMessage = '''
build.gradle must set a "namespace":
android {
namespace 'dev.flutter.foo'
}
$exampleAndroidNamespaceBlock
The value must match the "package" attribute in AndroidManifest.xml, if one is
present. For more information, see:
@ -170,6 +189,18 @@ https://developer.android.com/build/publish-library/prep-lib-release#choose-name
'$indentation${errorMessage.split('\n').join('\n$indentation')}');
return false;
} else {
if (!isExample && !gradleContents.contains(namespaceConditional)) {
final String errorMessage = '''
build.gradle for a plugin must conditionalize "namespace":
$exampleAndroidNamespaceBlock
''';
printError(
'$indentation${errorMessage.split('\n').join('\n$indentation')}');
return false;
}
return _validateNamespaceMatchesManifest(package,
isExample: isExample, namespace: namespaceMatch.group(1)!);
}