Skip to content

Commit ef15eac

Browse files
Jonah Williamsfluttergithubbot
authored andcommitted
[flutter_tools] Remove context from Xcode and most of Xcodeproj (flutter#48661)
1 parent 7cf2ff1 commit ef15eac

File tree

7 files changed

+576
-511
lines changed

7 files changed

+576
-511
lines changed

packages/flutter_tools/lib/src/context_runner.dart

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,20 @@ Future<T> runInContext<T>(
145145
VisualStudioValidator: () => const VisualStudioValidator(),
146146
WebWorkflow: () => const WebWorkflow(),
147147
WindowsWorkflow: () => const WindowsWorkflow(),
148-
Xcode: () => Xcode(),
149-
XcodeProjectInterpreter: () => XcodeProjectInterpreter(),
148+
Xcode: () => Xcode(
149+
logger: globals.logger,
150+
processManager: globals.processManager,
151+
platform: globals.platform,
152+
fileSystem: globals.fs,
153+
xcodeProjectInterpreter: xcodeProjectInterpreter,
154+
),
155+
XcodeProjectInterpreter: () => XcodeProjectInterpreter(
156+
logger: globals.logger,
157+
processManager: globals.processManager,
158+
platform: globals.platform,
159+
fileSystem: globals.fs,
160+
terminal: globals.terminal,
161+
),
150162
XcodeValidator: () => const XcodeValidator(),
151163
},
152164
);

packages/flutter_tools/lib/src/ios/mac.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ Future<XcodeBuildResult> buildXcodeProject({
458458
// e.g. `flutter build bundle`.
459459
buildCommands.add('FLUTTER_SUPPRESS_ANALYTICS=true');
460460
buildCommands.add('COMPILER_INDEX_STORE_ENABLE=NO');
461-
buildCommands.addAll(environmentVariablesAsXcodeBuildSettings());
461+
buildCommands.addAll(environmentVariablesAsXcodeBuildSettings(globals.platform));
462462

463463
final Stopwatch sw = Stopwatch()..start();
464464
initialBuildStatus = globals.logger.startProgress('Running Xcode build...', timeout: timeoutConfiguration.fastOperation);

packages/flutter_tools/lib/src/ios/xcodeproj.dart

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import 'dart:async';
66

77
import 'package:meta/meta.dart';
8+
import 'package:platform/platform.dart';
9+
import 'package:process/process.dart';
810

911
import '../artifacts.dart';
1012
import '../base/common.dart';
@@ -14,6 +16,7 @@ import '../base/io.dart';
1416
import '../base/logger.dart';
1517
import '../base/os.dart';
1618
import '../base/process.dart';
19+
import '../base/terminal.dart';
1720
import '../base/utils.dart';
1821
import '../build_info.dart';
1922
import '../cache.dart';
@@ -221,15 +224,33 @@ XcodeProjectInterpreter get xcodeProjectInterpreter => context.get<XcodeProjectI
221224

222225
/// Interpreter of Xcode projects.
223226
class XcodeProjectInterpreter {
227+
XcodeProjectInterpreter({
228+
@required Platform platform,
229+
@required ProcessManager processManager,
230+
@required Logger logger,
231+
@required FileSystem fileSystem,
232+
@required AnsiTerminal terminal,
233+
}) : _platform = platform,
234+
_fileSystem = fileSystem,
235+
_terminal = terminal,
236+
_logger = logger,
237+
_processUtils = ProcessUtils(logger: logger, processManager: processManager);
238+
239+
final Platform _platform;
240+
final FileSystem _fileSystem;
241+
final ProcessUtils _processUtils;
242+
final AnsiTerminal _terminal;
243+
final Logger _logger;
244+
224245
static const String _executable = '/usr/bin/xcodebuild';
225246
static final RegExp _versionRegex = RegExp(r'Xcode ([0-9.]+)');
226247

227248
void _updateVersion() {
228-
if (!globals.platform.isMacOS || !globals.fs.file(_executable).existsSync()) {
249+
if (!_platform.isMacOS || !_fileSystem.file(_executable).existsSync()) {
229250
return;
230251
}
231252
try {
232-
final RunResult result = processUtils.runSync(
253+
final RunResult result = _processUtils.runSync(
233254
<String>[_executable, '-version'],
234255
);
235256
if (result.exitCode != 0) {
@@ -283,26 +304,26 @@ class XcodeProjectInterpreter {
283304
Duration timeout = const Duration(minutes: 1),
284305
}) async {
285306
final Status status = Status.withSpinner(
286-
timeout: timeoutConfiguration.fastOperation,
287-
timeoutConfiguration: timeoutConfiguration,
288-
platform: globals.platform,
307+
timeout: const TimeoutConfiguration().fastOperation,
308+
timeoutConfiguration: const TimeoutConfiguration(),
309+
platform: _platform,
289310
stopwatch: Stopwatch(),
290-
supportsColor: globals.terminal.supportsColor,
311+
supportsColor: _terminal.supportsColor,
291312
);
292313
final List<String> showBuildSettingsCommand = <String>[
293314
_executable,
294315
'-project',
295-
globals.fs.path.absolute(projectPath),
316+
_fileSystem.path.absolute(projectPath),
296317
'-target',
297318
target,
298319
'-showBuildSettings',
299-
...environmentVariablesAsXcodeBuildSettings()
320+
...environmentVariablesAsXcodeBuildSettings(_platform)
300321
];
301322
try {
302323
// showBuildSettings is reported to occasionally timeout. Here, we give it
303324
// a lot of wiggle room (locally on Flutter Gallery, this takes ~1s).
304325
// When there is a timeout, we retry once.
305-
final RunResult result = await processUtils.run(
326+
final RunResult result = await _processUtils.run(
306327
showBuildSettingsCommand,
307328
throwOnError: true,
308329
workingDirectory: projectPath,
@@ -317,32 +338,32 @@ class XcodeProjectInterpreter {
317338
command: showBuildSettingsCommand.join(' '),
318339
).send();
319340
}
320-
globals.printTrace('Unexpected failure to get the build settings: $error.');
341+
_logger.printTrace('Unexpected failure to get the build settings: $error.');
321342
return const <String, String>{};
322343
} finally {
323344
status.stop();
324345
}
325346
}
326347

327348
void cleanWorkspace(String workspacePath, String scheme) {
328-
processUtils.runSync(<String>[
349+
_processUtils.runSync(<String>[
329350
_executable,
330351
'-workspace',
331352
workspacePath,
332353
'-scheme',
333354
scheme,
334355
'-quiet',
335356
'clean',
336-
...environmentVariablesAsXcodeBuildSettings()
337-
], workingDirectory: globals.fs.currentDirectory.path);
357+
...environmentVariablesAsXcodeBuildSettings(_platform)
358+
], workingDirectory: _fileSystem.currentDirectory.path);
338359
}
339360

340361
Future<XcodeProjectInfo> getInfo(String projectPath, {String projectFilename}) async {
341362
// The exit code returned by 'xcodebuild -list' when either:
342363
// * -project is passed and the given project isn't there, or
343364
// * no -project is passed and there isn't a project.
344365
const int missingProjectExitCode = 66;
345-
final RunResult result = await processUtils.run(
366+
final RunResult result = await _processUtils.run(
346367
<String>[
347368
_executable,
348369
'-list',
@@ -363,9 +384,9 @@ class XcodeProjectInterpreter {
363384
/// This allows developers to pass arbitrary build settings in without the tool needing to make a flag
364385
/// for or be aware of each one. This could be used to set code signing build settings in a CI
365386
/// environment without requiring settings changes in the Xcode project.
366-
List<String> environmentVariablesAsXcodeBuildSettings() {
387+
List<String> environmentVariablesAsXcodeBuildSettings(Platform platform) {
367388
const String xcodeBuildSettingPrefix = 'FLUTTER_XCODE_';
368-
return globals.platform.environment.entries.where((MapEntry<String, String> mapEntry) {
389+
return platform.environment.entries.where((MapEntry<String, String> mapEntry) {
369390
return mapEntry.key.startsWith(xcodeBuildSettingPrefix);
370391
}).expand<String>((MapEntry<String, String> mapEntry) {
371392
// Remove FLUTTER_XCODE_ prefix from the environment variable to get the build setting.

packages/flutter_tools/lib/src/macos/build_macos.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ Future<void> buildMacOS({
8585
'OBJROOT=${globals.fs.path.join(flutterBuildDir.absolute.path, 'Build', 'Intermediates.noindex')}',
8686
'SYMROOT=${globals.fs.path.join(flutterBuildDir.absolute.path, 'Build', 'Products')}',
8787
'COMPILER_INDEX_STORE_ENABLE=NO',
88-
...environmentVariablesAsXcodeBuildSettings()
88+
...environmentVariablesAsXcodeBuildSettings(globals.platform)
8989
], trace: true);
9090
} finally {
9191
status.cancel();

packages/flutter_tools/lib/src/macos/xcode.dart

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,16 @@
44

55
import 'dart:async';
66

7+
import 'package:meta/meta.dart';
8+
import 'package:platform/platform.dart';
9+
import 'package:process/process.dart';
10+
711
import '../base/common.dart';
812
import '../base/context.dart';
13+
import '../base/file_system.dart';
914
import '../base/io.dart';
15+
import '../base/logger.dart';
1016
import '../base/process.dart';
11-
import '../globals.dart' as globals;
1217
import '../ios/xcodeproj.dart';
1318

1419
const int kXcodeRequiredVersionMajor = 10;
@@ -41,14 +46,31 @@ String getNameForSdk(SdkType sdk) {
4146
return null;
4247
}
4348

49+
/// A utility class for interacting with Xcode command line tools.
4450
class Xcode {
45-
bool get isInstalledAndMeetsVersionCheck => globals.platform.isMacOS && isInstalled && isVersionSatisfactory;
51+
Xcode({
52+
@required Platform platform,
53+
@required ProcessManager processManager,
54+
@required Logger logger,
55+
@required FileSystem fileSystem,
56+
@required XcodeProjectInterpreter xcodeProjectInterpreter,
57+
}) : _platform = platform,
58+
_fileSystem = fileSystem,
59+
_xcodeProjectInterpreter = xcodeProjectInterpreter,
60+
_processUtils = ProcessUtils(logger: logger, processManager: processManager);
61+
62+
final Platform _platform;
63+
final ProcessUtils _processUtils;
64+
final FileSystem _fileSystem;
65+
final XcodeProjectInterpreter _xcodeProjectInterpreter;
66+
67+
bool get isInstalledAndMeetsVersionCheck => _platform.isMacOS && isInstalled && isVersionSatisfactory;
4668

4769
String _xcodeSelectPath;
4870
String get xcodeSelectPath {
4971
if (_xcodeSelectPath == null) {
5072
try {
51-
_xcodeSelectPath = processUtils.runSync(
73+
_xcodeSelectPath = _processUtils.runSync(
5274
<String>['/usr/bin/xcode-select', '--print-path'],
5375
).stdout.trim();
5476
} on ProcessException {
@@ -64,21 +86,21 @@ class Xcode {
6486
if (xcodeSelectPath == null || xcodeSelectPath.isEmpty) {
6587
return false;
6688
}
67-
return xcodeProjectInterpreter.isInstalled;
89+
return _xcodeProjectInterpreter.isInstalled;
6890
}
6991

70-
int get majorVersion => xcodeProjectInterpreter.majorVersion;
92+
int get majorVersion => _xcodeProjectInterpreter.majorVersion;
7193

72-
int get minorVersion => xcodeProjectInterpreter.minorVersion;
94+
int get minorVersion => _xcodeProjectInterpreter.minorVersion;
7395

74-
String get versionText => xcodeProjectInterpreter.versionText;
96+
String get versionText => _xcodeProjectInterpreter.versionText;
7597

7698
bool _eulaSigned;
7799
/// Has the EULA been signed?
78100
bool get eulaSigned {
79101
if (_eulaSigned == null) {
80102
try {
81-
final RunResult result = processUtils.runSync(
103+
final RunResult result = _processUtils.runSync(
82104
<String>['/usr/bin/xcrun', 'clang'],
83105
);
84106
if (result.stdout != null && result.stdout.contains('license')) {
@@ -103,7 +125,7 @@ class Xcode {
103125
try {
104126
// This command will error if additional components need to be installed in
105127
// xcode 9.2 and above.
106-
final RunResult result = processUtils.runSync(
128+
final RunResult result = _processUtils.runSync(
107129
<String>['/usr/bin/xcrun', 'simctl', 'list'],
108130
);
109131
_isSimctlInstalled = result.stderr == null || result.stderr == '';
@@ -115,7 +137,7 @@ class Xcode {
115137
}
116138

117139
bool get isVersionSatisfactory {
118-
if (!xcodeProjectInterpreter.isInstalled) {
140+
if (!_xcodeProjectInterpreter.isInstalled) {
119141
return false;
120142
}
121143
if (majorVersion > kXcodeRequiredVersionMajor) {
@@ -128,22 +150,22 @@ class Xcode {
128150
}
129151

130152
Future<RunResult> cc(List<String> args) {
131-
return processUtils.run(
153+
return _processUtils.run(
132154
<String>['xcrun', 'cc', ...args],
133155
throwOnError: true,
134156
);
135157
}
136158

137159
Future<RunResult> clang(List<String> args) {
138-
return processUtils.run(
160+
return _processUtils.run(
139161
<String>['xcrun', 'clang', ...args],
140162
throwOnError: true,
141163
);
142164
}
143165

144166
Future<String> sdkLocation(SdkType sdk) async {
145167
assert(sdk != null);
146-
final RunResult runResult = await processUtils.run(
168+
final RunResult runResult = await _processUtils.run(
147169
<String>['xcrun', '--sdk', getNameForSdk(sdk), '--show-sdk-path'],
148170
throwOnError: true,
149171
);
@@ -158,10 +180,10 @@ class Xcode {
158180
return null;
159181
}
160182
final List<String> searchPaths = <String>[
161-
globals.fs.path.join(xcodeSelectPath, 'Applications', 'Simulator.app'),
183+
_fileSystem.path.join(xcodeSelectPath, 'Applications', 'Simulator.app'),
162184
];
163185
return searchPaths.where((String p) => p != null).firstWhere(
164-
(String p) => globals.fs.directory(p).existsSync(),
186+
(String p) => _fileSystem.directory(p).existsSync(),
165187
orElse: () => null,
166188
);
167189
}

0 commit comments

Comments
 (0)