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;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String? get defaultFlavor => _flutterDescriptor['default-flavor'] as String?;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Font {
|
class Font {
|
||||||
@ -557,6 +559,10 @@ void _validateFlutter(YamlMap? yaml, List<String> errors) {
|
|||||||
if (yamlValue is! bool) {
|
if (yamlValue is! bool) {
|
||||||
errors.add('Expected "$yamlKey" to be a bool, but got $yamlValue (${yamlValue.runtimeType}).');
|
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:
|
default:
|
||||||
errors.add('Unexpected child "$yamlKey" found under "flutter".');
|
errors.add('Unexpected child "$yamlKey" found under "flutter".');
|
||||||
break;
|
break;
|
||||||
|
@ -1094,7 +1094,8 @@ abstract class FlutterCommand extends Command<void> {
|
|||||||
'flavor',
|
'flavor',
|
||||||
help: 'Build a custom app flavor as defined by platform-specific build setup.\n'
|
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 '
|
'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 (flavor != null) {
|
||||||
if (globals.platform.environment['FLUTTER_APP_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.');
|
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.fonts, isEmpty);
|
||||||
expect(flutterManifest.assets, isEmpty);
|
expect(flutterManifest.assets, isEmpty);
|
||||||
expect(flutterManifest.additionalLicenses, isEmpty);
|
expect(flutterManifest.additionalLicenses, isEmpty);
|
||||||
|
expect(flutterManifest.defaultFlavor, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('FlutterManifest is null when the pubspec.yaml file is not a map', () async {
|
testWithoutContext('FlutterManifest is null when the pubspec.yaml file is not a map', () async {
|
||||||
@ -1448,6 +1449,37 @@ flutter:
|
|||||||
|
|
||||||
expect(flutterManifest.disabledSwiftPackageManager, false);
|
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({
|
Matcher matchesManifest({
|
||||||
|
@ -1217,6 +1217,45 @@ void main() {
|
|||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
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