add default-flavor
field to flutter pubspec, which will be used as the flavor in flutter build/run
if --flavor
is not provided (#147968)
This PR adds a new flag `default-flavor` in the `flutter` section of `pubspec.yaml`. It allows developers of multi-flavor android apps to specify a default flavor to be used for `flutter run`, `flutter build` etc. Using `flutter run` on flavored apps already works without specifying `--flavor` already works on iOS (it defaults to the `runner` schema), so I (and others in #22856) figured this would be nice to have. fixes #22856
This commit is contained in:
parent
ca198c8585
commit
43548359c9
@ -388,6 +388,8 @@ class FlutterManifest {
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
String? get defaultFlavor => _flutterDescriptor['default-flavor'] as String?;
|
||||
}
|
||||
|
||||
class Font {
|
||||
@ -557,6 +559,10 @@ void _validateFlutter(YamlMap? yaml, List<String> errors) {
|
||||
if (yamlValue is! bool) {
|
||||
errors.add('Expected "$yamlKey" to be a bool, but got $yamlValue (${yamlValue.runtimeType}).');
|
||||
}
|
||||
case 'default-flavor':
|
||||
if (yamlValue is! String) {
|
||||
errors.add('Expected "$yamlKey" to be a string, but got $yamlValue (${yamlValue.runtimeType}).');
|
||||
}
|
||||
default:
|
||||
errors.add('Unexpected child "$yamlKey" found under "flutter".');
|
||||
break;
|
||||
|
@ -1094,7 +1094,8 @@ abstract class FlutterCommand extends Command<void> {
|
||||
'flavor',
|
||||
help: 'Build a custom app flavor as defined by platform-specific build setup.\n'
|
||||
'Supports the use of product flavors in Android Gradle scripts, and '
|
||||
'the use of custom Xcode schemes.',
|
||||
'the use of custom Xcode schemes.\n'
|
||||
'Overrides the value of the "default-flavor" entry in the flutter pubspec.',
|
||||
);
|
||||
}
|
||||
|
||||
@ -1283,7 +1284,9 @@ abstract class FlutterCommand extends Command<void> {
|
||||
}
|
||||
}
|
||||
|
||||
final String? flavor = argParser.options.containsKey('flavor') ? stringArg('flavor') : null;
|
||||
final String? defaultFlavor = FlutterProject.current().manifest.defaultFlavor;
|
||||
final String? cliFlavor = argParser.options.containsKey('flavor') ? stringArg('flavor') : null;
|
||||
final String? flavor = cliFlavor ?? defaultFlavor;
|
||||
if (flavor != null) {
|
||||
if (globals.platform.environment['FLUTTER_APP_FLAVOR'] != null) {
|
||||
throwToolExit('FLUTTER_APP_FLAVOR is used by the framework and cannot be set in the environment.');
|
||||
|
@ -36,6 +36,7 @@ void main() {
|
||||
expect(flutterManifest.fonts, isEmpty);
|
||||
expect(flutterManifest.assets, isEmpty);
|
||||
expect(flutterManifest.additionalLicenses, isEmpty);
|
||||
expect(flutterManifest.defaultFlavor, null);
|
||||
});
|
||||
|
||||
testWithoutContext('FlutterManifest is null when the pubspec.yaml file is not a map', () async {
|
||||
@ -1448,6 +1449,37 @@ flutter:
|
||||
|
||||
expect(flutterManifest.disabledSwiftPackageManager, false);
|
||||
});
|
||||
|
||||
testWithoutContext('FlutterManifest can parse default flavor', () async {
|
||||
const String manifest = '''
|
||||
name: test
|
||||
flutter:
|
||||
default-flavor: prod
|
||||
''';
|
||||
final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
|
||||
manifest,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
|
||||
expect(flutterManifest, isNotNull);
|
||||
expect(flutterManifest!.defaultFlavor, 'prod');
|
||||
});
|
||||
|
||||
testWithoutContext('FlutterManifest fails on invalid default flavor', () async {
|
||||
const String manifest = '''
|
||||
name: test
|
||||
flutter:
|
||||
default-flavor: 3
|
||||
''';
|
||||
|
||||
final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
|
||||
manifest,
|
||||
logger: logger,
|
||||
);
|
||||
|
||||
expect(flutterManifest, null);
|
||||
expect(logger.errorText, 'Expected "default-flavor" to be a string, but got 3 (int).\n');
|
||||
});
|
||||
}
|
||||
|
||||
Matcher matchesManifest({
|
||||
|
@ -1217,6 +1217,45 @@ void main() {
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testUsingContext('CLI option overrides default flavor from manifest', () async {
|
||||
final File pubspec = fileSystem.file('pubspec.yaml');
|
||||
await pubspec.create();
|
||||
await pubspec.writeAsString('''
|
||||
name: test
|
||||
flutter:
|
||||
default-flavor: foo
|
||||
''');
|
||||
|
||||
final DummyFlutterCommand flutterCommand = DummyFlutterCommand();
|
||||
final BuildInfo buildInfo = await flutterCommand.getBuildInfo(forcedBuildMode: BuildMode.debug);
|
||||
expect(buildInfo.flavor, 'foo');
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => FakeProcessManager.empty(),
|
||||
});
|
||||
|
||||
testUsingContext('tool loads default flavor from manifest, but cli overrides', () async {
|
||||
final File pubspec = fileSystem.file('pubspec.yaml');
|
||||
await pubspec.create();
|
||||
await pubspec.writeAsString('''
|
||||
name: test
|
||||
flutter:
|
||||
default-flavor: foo
|
||||
''');
|
||||
|
||||
final DummyFlutterCommand flutterCommand = DummyFlutterCommand(commandFunction: () async {
|
||||
return FlutterCommandResult.success();
|
||||
},);
|
||||
flutterCommand.usesFlavorOption();
|
||||
final CommandRunner<void> runner = createTestCommandRunner(flutterCommand);
|
||||
await runner.run(<String>['dummy', '--flavor', 'bar']);
|
||||
final BuildInfo buildInfo = await flutterCommand.getBuildInfo(forcedBuildMode: BuildMode.debug);
|
||||
expect(buildInfo.flavor, 'bar');
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => FakeProcessManager.empty(),
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user