Unverified Commit 6eef5f2c authored by stuartmorgan's avatar stuartmorgan Committed by GitHub

Share build command flag configuration on desktop (#64983)

Almost all of the flag setup on Linux, macOS, and Windows should be
identical; this pulls that common setup to a shared method.

This adds support for several flags on macOS that have all the necessary
plumbing already in place due to shared backend code, but were never
enabled.

Fixes https://github.com/flutter/flutter/issues/64944
parent e82571a9
...@@ -18,20 +18,7 @@ import 'build.dart'; ...@@ -18,20 +18,7 @@ import 'build.dart';
/// A command to build a linux desktop target through a build shell script. /// A command to build a linux desktop target through a build shell script.
class BuildLinuxCommand extends BuildSubCommand { class BuildLinuxCommand extends BuildSubCommand {
BuildLinuxCommand({ bool verboseHelp = false }) { BuildLinuxCommand({ bool verboseHelp = false }) {
addTreeShakeIconsFlag(); addCommonDesktopBuildOptions(verboseHelp: verboseHelp);
usesTargetOption();
addBuildModeFlags(verboseHelp: verboseHelp);
usesPubOption();
addSplitDebugInfoOption();
addDartObfuscationOption();
usesDartDefineOption();
usesExtraFrontendOptions();
addEnableExperimentation(hide: !verboseHelp);
usesTrackWidgetCreation(verboseHelp: verboseHelp);
addBuildPerformanceFile(hide: !verboseHelp);
addBundleSkSLPathOption(hide: !verboseHelp);
addNullSafetyModeOptions(hide: !verboseHelp);
usesAnalyzeSizeFlag();
} }
@override @override
......
...@@ -20,19 +20,9 @@ import 'build.dart'; ...@@ -20,19 +20,9 @@ import 'build.dart';
/// A command to build a macOS desktop target through a build shell script. /// A command to build a macOS desktop target through a build shell script.
class BuildMacosCommand extends BuildSubCommand { class BuildMacosCommand extends BuildSubCommand {
BuildMacosCommand({ @required bool verboseHelp }) { BuildMacosCommand({ @required bool verboseHelp }) {
addTreeShakeIconsFlag(); addCommonDesktopBuildOptions(verboseHelp: verboseHelp);
addSplitDebugInfoOption();
usesTargetOption();
addBuildModeFlags();
addDartObfuscationOption();
usesExtraFrontendOptions();
usesBuildNumberOption(); usesBuildNumberOption();
usesBuildNameOption(); usesBuildNameOption();
addEnableExperimentation(hide: !verboseHelp);
addBuildPerformanceFile(hide: !verboseHelp);
addBundleSkSLPathOption(hide: !verboseHelp);
addNullSafetyModeOptions(hide: !verboseHelp);
usesAnalyzeSizeFlag();
} }
@override @override
......
...@@ -21,20 +21,7 @@ import 'build.dart'; ...@@ -21,20 +21,7 @@ import 'build.dart';
/// A command to build a windows desktop target through a build shell script. /// A command to build a windows desktop target through a build shell script.
class BuildWindowsCommand extends BuildSubCommand { class BuildWindowsCommand extends BuildSubCommand {
BuildWindowsCommand({ bool verboseHelp = false }) { BuildWindowsCommand({ bool verboseHelp = false }) {
addTreeShakeIconsFlag(); addCommonDesktopBuildOptions(verboseHelp: verboseHelp);
usesTargetOption();
addBuildModeFlags(verboseHelp: verboseHelp);
usesPubOption();
addSplitDebugInfoOption();
addDartObfuscationOption();
usesDartDefineOption();
usesExtraFrontendOptions();
addEnableExperimentation(hide: !verboseHelp);
usesTrackWidgetCreation(verboseHelp: verboseHelp);
addBuildPerformanceFile(hide: !verboseHelp);
addBundleSkSLPathOption(hide: !verboseHelp);
addNullSafetyModeOptions(hide: !verboseHelp);
usesAnalyzeSizeFlag();
} }
@override @override
......
...@@ -554,6 +554,24 @@ abstract class FlutterCommand extends Command<void> { ...@@ -554,6 +554,24 @@ abstract class FlutterCommand extends Command<void> {
); );
} }
/// Adds build options common to all of the desktop build commands.
void addCommonDesktopBuildOptions({ bool verboseHelp = false }) {
addBuildModeFlags(verboseHelp: verboseHelp);
addBuildPerformanceFile(hide: !verboseHelp);
addBundleSkSLPathOption(hide: !verboseHelp);
addDartObfuscationOption();
addEnableExperimentation(hide: !verboseHelp);
addNullSafetyModeOptions(hide: !verboseHelp);
addSplitDebugInfoOption();
addTreeShakeIconsFlag();
usesAnalyzeSizeFlag();
usesDartDefineOption();
usesExtraFrontendOptions();
usesPubOption();
usesTargetOption();
usesTrackWidgetCreation(verboseHelp: verboseHelp);
}
set defaultBuildMode(BuildMode value) { set defaultBuildMode(BuildMode value) {
_defaultBuildMode = value; _defaultBuildMode = value;
} }
......
...@@ -112,7 +112,7 @@ void main() { ...@@ -112,7 +112,7 @@ void main() {
createCoreMockProjectFiles(); createCoreMockProjectFiles();
expect(createTestCommandRunner(command).run( expect(createTestCommandRunner(command).run(
const <String>['build', 'macos'] const <String>['build', 'macos', '--no-pub']
), throwsToolExit(message: 'No macOS desktop project configured')); ), throwsToolExit(message: 'No macOS desktop project configured'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => macosPlatform, Platform: () => macosPlatform,
...@@ -129,7 +129,7 @@ void main() { ...@@ -129,7 +129,7 @@ void main() {
.createSync(recursive: true); .createSync(recursive: true);
expect(createTestCommandRunner(command).run( expect(createTestCommandRunner(command).run(
const <String>['build', 'macos'] const <String>['build', 'macos', '--no-pub']
), throwsToolExit()); ), throwsToolExit());
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => notMacosPlatform, Platform: () => notMacosPlatform,
...@@ -143,7 +143,7 @@ void main() { ...@@ -143,7 +143,7 @@ void main() {
createMinimalMockProjectFiles(); createMinimalMockProjectFiles();
await createTestCommandRunner(command).run( await createTestCommandRunner(command).run(
const <String>['build', 'macos', '--debug'] const <String>['build', 'macos', '--debug', '--no-pub']
); );
expect(testLogger.statusText, isNot(contains('STDOUT STUFF'))); expect(testLogger.statusText, isNot(contains('STDOUT STUFF')));
expect(testLogger.traceText, isNot(contains('STDOUT STUFF'))); expect(testLogger.traceText, isNot(contains('STDOUT STUFF')));
...@@ -162,7 +162,7 @@ void main() { ...@@ -162,7 +162,7 @@ void main() {
createMinimalMockProjectFiles(); createMinimalMockProjectFiles();
await createTestCommandRunner(command).run( await createTestCommandRunner(command).run(
const <String>['build', 'macos', '--debug'] const <String>['build', 'macos', '--debug', '--no-pub']
); );
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
...@@ -178,7 +178,7 @@ void main() { ...@@ -178,7 +178,7 @@ void main() {
createMinimalMockProjectFiles(); createMinimalMockProjectFiles();
await createTestCommandRunner(command).run( await createTestCommandRunner(command).run(
const <String>['build', 'macos', '--debug', '-v'] const <String>['build', 'macos', '--debug', '--no-pub', '-v']
); );
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
...@@ -195,7 +195,7 @@ void main() { ...@@ -195,7 +195,7 @@ void main() {
createMinimalMockProjectFiles(); createMinimalMockProjectFiles();
await createTestCommandRunner(command).run( await createTestCommandRunner(command).run(
const <String>['build', 'macos', '--profile'] const <String>['build', 'macos', '--profile', '--no-pub']
); );
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
...@@ -212,7 +212,7 @@ void main() { ...@@ -212,7 +212,7 @@ void main() {
createMinimalMockProjectFiles(); createMinimalMockProjectFiles();
await createTestCommandRunner(command).run( await createTestCommandRunner(command).run(
const <String>['build', 'macos', '--release'] const <String>['build', 'macos', '--release', '--no-pub']
); );
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
...@@ -223,6 +223,52 @@ void main() { ...@@ -223,6 +223,52 @@ void main() {
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true), FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
}); });
testUsingContext('macOS build supports standard desktop build options', () async {
final BuildCommand command = BuildCommand();
createMinimalMockProjectFiles();
fileSystem.file('lib/other.dart')
.createSync(recursive: true);
await createTestCommandRunner(command).run(
const <String>[
'build',
'macos',
'--target=lib/other.dart',
'--no-pub',
'--track-widget-creation',
'--split-debug-info=foo/',
'--enable-experiment=non-nullable',
'--obfuscate',
'--dart-define=foo.bar=2',
'--dart-define=fizz.far=3',
'--tree-shake-icons',
'--bundle-sksl-path=foo/bar.sksl.json',
]
);
final List<String> contents = fileSystem
.file('./macos/Flutter/ephemeral/Flutter-Generated.xcconfig')
.readAsLinesSync();
expect(contents, containsAll(<String>[
'DART_DEFINES=foo.bar%3D2,fizz.far%3D3',
'DART_OBFUSCATION=true',
'EXTRA_FRONT_END_OPTIONS=--enable-experiment%3Dnon-nullable',
'EXTRA_GEN_SNAPSHOT_OPTIONS=--enable-experiment%3Dnon-nullable',
'SPLIT_DEBUG_INFO=foo/',
'TRACK_WIDGET_CREATION=true',
'TREE_SHAKE_ICONS=true',
'FLUTTER_TARGET=lib/other.dart',
'BUNDLE_SKSL_PATH=foo/bar.sksl.json',
]));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
setUpMockXcodeBuildHandler('Release')
]),
Platform: () => macosPlatform,
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
});
testUsingContext('macOS build supports build-name and build-number', () async { testUsingContext('macOS build supports build-name and build-number', () async {
final BuildCommand command = BuildCommand(); final BuildCommand command = BuildCommand();
createMinimalMockProjectFiles(); createMinimalMockProjectFiles();
...@@ -232,6 +278,7 @@ void main() { ...@@ -232,6 +278,7 @@ void main() {
'build', 'build',
'macos', 'macos',
'--debug', '--debug',
'--no-pub',
'--build-name=1.2.3', '--build-name=1.2.3',
'--build-number=42', '--build-number=42',
], ],
...@@ -254,7 +301,7 @@ void main() { ...@@ -254,7 +301,7 @@ void main() {
testUsingContext('Refuses to build for macOS when feature is disabled', () { testUsingContext('Refuses to build for macOS when feature is disabled', () {
final CommandRunner<void> runner = createTestCommandRunner(BuildCommand()); final CommandRunner<void> runner = createTestCommandRunner(BuildCommand());
expect(() => runner.run(<String>['build', 'macos']), expect(() => runner.run(<String>['build', 'macos', '--no-pub']),
throwsToolExit()); throwsToolExit());
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: false), FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: false),
...@@ -283,7 +330,7 @@ void main() { ...@@ -283,7 +330,7 @@ void main() {
..writeAsBytesSync(List<int>.generate(10000, (int index) => 0)); ..writeAsBytesSync(List<int>.generate(10000, (int index) => 0));
await createTestCommandRunner(command).run( await createTestCommandRunner(command).run(
const <String>['build', 'macos', '--analyze-size'] const <String>['build', 'macos', '--no-pub', '--analyze-size']
); );
expect(testLogger.statusText, contains('A summary of your macOS bundle analysis can be found at')); expect(testLogger.statusText, contains('A summary of your macOS bundle analysis can be found at'));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment