Unverified Commit 216da410 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] add --config-only option to flutter build ios (#64848)

parent 183a653e
......@@ -40,6 +40,11 @@ class BuildIOSCommand extends BuildSubCommand {
addNullSafetyModeOptions(hide: !verboseHelp);
usesAnalyzeSizeFlag();
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.'
)
..addFlag('simulator',
help: 'Build for the iOS simulator instead of the device. This changes '
'the default build mode to debug if otherwise unspecified.',
......@@ -64,13 +69,27 @@ class BuildIOSCommand extends BuildSubCommand {
@override
Future<FlutterCommandResult> runCommand() async {
final bool forSimulator = boolArg('simulator');
final bool configOnly = boolArg('config-only');
final bool shouldCodesign = boolArg('codesign');
defaultBuildMode = forSimulator ? BuildMode.debug : BuildMode.release;
final BuildInfo buildInfo = getBuildInfo();
if (!globals.platform.isMacOS) {
throwToolExit('Building for iOS is only supported on the Mac.');
throwToolExit('Building for iOS is only supported on macOS.');
}
if (forSimulator && !buildInfo.supportsSimulator) {
throwToolExit('${toTitleCase(buildInfo.friendlyModeName)} mode is not supported for simulators.');
}
if (configOnly && buildInfo.codeSizeDirectory != null) {
throwToolExit('Cannot analyze code size without performing a full build.');
}
if (!forSimulator && !shouldCodesign) {
globals.printStatus(
'Warning: Building for device with codesigning disabled. You will '
'have to manually codesign before deploying to device.',
);
}
final BuildInfo buildInfo = getBuildInfo();
final BuildableIOSApp app = await applicationPackages.getPackageForPlatform(
TargetPlatform.ios,
buildInfo,
......@@ -80,18 +99,7 @@ class BuildIOSCommand extends BuildSubCommand {
throwToolExit('Application not configured for iOS');
}
final bool shouldCodesign = boolArg('codesign');
if (!forSimulator && !shouldCodesign) {
globals.printStatus('Warning: Building for device with codesigning disabled. You will '
'have to manually codesign before deploying to device.');
}
if (forSimulator && !buildInfo.supportsSimulator) {
throwToolExit('${toTitleCase(buildInfo.friendlyModeName)} mode is not supported for simulators.');
}
final String logTarget = forSimulator ? 'simulator' : 'device';
final String typeName = globals.artifacts.getEngineType(TargetPlatform.ios, buildInfo.mode);
globals.printStatus('Building $app for $logTarget ($typeName)...');
final XcodeBuildResult result = await buildXcodeProject(
......@@ -100,6 +108,7 @@ class BuildIOSCommand extends BuildSubCommand {
targetOverride: targetFile,
buildForDevice: !forSimulator,
codesign: shouldCodesign,
configOnly: configOnly,
);
if (!result.success) {
......
......@@ -97,6 +97,7 @@ Future<XcodeBuildResult> buildXcodeProject({
DarwinArch activeArch,
bool codesign = true,
String deviceID,
bool configOnly = false,
}) async {
if (!upgradePbxProjWithFlutterAssets(app.project, globals.logger)) {
return XcodeBuildResult(success: false);
......@@ -187,6 +188,9 @@ Future<XcodeBuildResult> buildXcodeProject({
buildInfo: buildInfo,
);
await processPodsIfNeeded(project.ios, getIosBuildDirectory(), buildInfo.mode);
if (configOnly) {
return XcodeBuildResult(success: true);
}
final List<String> buildCommands = <String>[
'/usr/bin/env',
......
// 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 'package:flutter_tools/src/base/platform.dart';
import 'package:process/process.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import '../src/common.dart';
void main() {
test('flutter build ios --config only updates generated xcconfig file without performing build', () async {
final String woringDirectory = globals.fs.path.join(getFlutterRoot(), 'examples', 'hello_world');
final String flutterBin = globals.fs.path.join(getFlutterRoot(), 'bin', 'flutter');
await const LocalProcessManager().run(<String>[
flutterBin,
'clean',
], workingDirectory: woringDirectory);
final ProcessResult result = await const LocalProcessManager().run(<String>[
flutterBin,
'build',
'ios',
'--config-only',
'--release',
'--obfuscate',
'--split-debug-info=info',
'--no-codesign',
], workingDirectory: woringDirectory);
print(result.stdout);
print(result.stderr);
expect(result.exitCode, 0);
final File generatedConfig = globals.fs.file(
globals.fs.path.join(woringDirectory, 'ios', 'Flutter', 'Generated.xcconfig'));
// Config is updated if command succeeded.
expect(generatedConfig, exists);
expect(generatedConfig.readAsStringSync(), allOf(
contains('DART_OBFUSCATION=true'),
contains('FLUTTER_FRAMEWORK_DIR=${globals.fs.path.absolute(getFlutterRoot(), 'bin', 'cache', 'artifacts', 'engine')}'),
));
// file that only exists if app was fully built.
final File frameworkPlist = globals.fs.file(
globals.fs.path.join(woringDirectory, 'build', 'ios', 'iphoneos', 'Runner.app', 'AppFrameworkInfo.plist'));
expect(frameworkPlist, isNot(exists));
},skip: !const LocalPlatform().isMacOS);
}
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