From 1dd7f45bfb368faeb674703d8c103f25d5aa42e6 Mon Sep 17 00:00:00 2001 From: Alex Wallen Date: Thu, 19 Jan 2023 13:29:17 -0800 Subject: [PATCH] Add `build macos --config-only` option. (#118649) Co-authored-by: a-wallen --- .../lib/src/commands/build_macos.dart | 10 +++ .../lib/src/macos/build_macos.dart | 5 +- .../build_macos_config_only_test.dart | 82 +++++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 packages/flutter_tools/test/integration.shard/build_macos_config_only_test.dart diff --git a/packages/flutter_tools/lib/src/commands/build_macos.dart b/packages/flutter_tools/lib/src/commands/build_macos.dart index ec004840ca..a6efb70fec 100644 --- a/packages/flutter_tools/lib/src/commands/build_macos.dart +++ b/packages/flutter_tools/lib/src/commands/build_macos.dart @@ -20,6 +20,13 @@ class BuildMacosCommand extends BuildSubCommand { required bool verboseHelp, }) : super(verboseHelp: verboseHelp) { addCommonDesktopBuildOptions(verboseHelp: verboseHelp); + usesFlavorOption(); + argParser + .addFlag('config-only', + help: 'Update the project configuration without performing a build. ' + 'This can be used in CI/CD process that create an archive to avoid ' + 'performing duplicate work.' + ); } @override @@ -39,6 +46,8 @@ class BuildMacosCommand extends BuildSubCommand { @override bool get supported => globals.platform.isMacOS; + bool get configOnly => boolArgDeprecated('config-only'); + @override Future runCommand() async { final BuildInfo buildInfo = await getBuildInfo(); @@ -55,6 +64,7 @@ class BuildMacosCommand extends BuildSubCommand { buildInfo: buildInfo, targetOverride: targetFile, verboseLogging: globals.logger.isVerbose, + configOnly: configOnly, sizeAnalyzer: SizeAnalyzer( fileSystem: globals.fs, logger: globals.logger, diff --git a/packages/flutter_tools/lib/src/macos/build_macos.dart b/packages/flutter_tools/lib/src/macos/build_macos.dart index 182dbc8a92..57a7309744 100644 --- a/packages/flutter_tools/lib/src/macos/build_macos.dart +++ b/packages/flutter_tools/lib/src/macos/build_macos.dart @@ -35,6 +35,7 @@ Future buildMacOS({ required BuildInfo buildInfo, String? targetOverride, required bool verboseLogging, + bool configOnly = false, SizeAnalyzer? sizeAnalyzer, }) async { final Directory? xcodeWorkspace = flutterProject.macos.xcodeWorkspace; @@ -78,6 +79,9 @@ Future buildMacOS({ if (!flutterProject.macos.outputFileList.existsSync()) { flutterProject.macos.outputFileList.createSync(recursive: true); } + if (configOnly) { + return; + } final Directory xcodeProject = flutterProject.macos.xcodeProject; @@ -97,7 +101,6 @@ Future buildMacOS({ if (configuration == null) { throwToolExit('Unable to find expected configuration in Xcode project.'); } - // Run the Xcode build. final Stopwatch sw = Stopwatch()..start(); final Status status = globals.logger.startProgress( diff --git a/packages/flutter_tools/test/integration.shard/build_macos_config_only_test.dart b/packages/flutter_tools/test/integration.shard/build_macos_config_only_test.dart new file mode 100644 index 0000000000..cb27c40256 --- /dev/null +++ b/packages/flutter_tools/test/integration.shard/build_macos_config_only_test.dart @@ -0,0 +1,82 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:file_testing/file_testing.dart'; +import 'package:flutter_tools/src/base/file_system.dart'; +import 'package:flutter_tools/src/base/io.dart'; + +import '../src/common.dart'; +import 'test_utils.dart'; + +void main() { + test('flutter build macOS --config only updates generated xcconfig file without performing build', () async { + final String workingDirectory = fileSystem.path.join( + getFlutterRoot(), + 'dev', + 'integration_tests', + 'flutter_gallery', + ); + final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter'); + + await processManager.run([ + flutterBin, + ...getLocalEngineArguments(), + 'clean', + ], workingDirectory: workingDirectory); + final List buildCommand = [ + flutterBin, + ...getLocalEngineArguments(), + 'build', + 'macos', + '--config-only', + '--release', + '--obfuscate', + '--split-debug-info=info', + ]; + final ProcessResult firstRunResult = await processManager.run(buildCommand, workingDirectory: workingDirectory); + + printOnFailure('Output of flutter build macOS:'); + final String firstRunStdout = firstRunResult.stdout.toString(); + printOnFailure('First run stdout: $firstRunStdout'); + printOnFailure('First run stderr: ${firstRunResult.stderr}'); + + expect(firstRunResult.exitCode, 0); + expect(firstRunStdout, contains('Running pod install')); + + final File generatedConfig = fileSystem.file(fileSystem.path.join( + workingDirectory, + 'macos', + 'Flutter', + 'ephemeral', + 'Flutter-Generated.xcconfig', + )); + + // Config is updated if command succeeded. + expect(generatedConfig, exists); + expect(generatedConfig.readAsStringSync(), contains('DART_OBFUSCATION=true')); + + // file that only exists if app was fully built. + final File frameworkPlist = fileSystem.file(fileSystem.path.join( + workingDirectory, + 'build', + 'macos', + 'Build', + 'Products', + 'Release', + 'App.framework', + 'Resources', + 'Info.plist' + )); + + expect(frameworkPlist, isNot(exists)); + + // Run again with no changes. + final ProcessResult secondRunResult = await processManager.run(buildCommand, workingDirectory: workingDirectory); + final String secondRunStdout = secondRunResult.stdout.toString(); + printOnFailure('Second run stdout: $secondRunStdout'); + printOnFailure('Second run stderr: ${secondRunResult.stderr}'); + + expect(secondRunResult.exitCode, 0); + }, skip: !platform.isMacOS); // [intended] macOS builds only work on macos. +}