blob: 4cb57c705f89b977375f1ba64fff9cd7118d2bc6 [file] [log] [blame]
// Copyright 2016 The Chromium 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 'dart:async';
import '../base/context.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/process.dart';
import '../base/process_manager.dart';
import '../ios/xcodeproj.dart';
const int kXcodeRequiredVersionMajor = 9;
const int kXcodeRequiredVersionMinor = 0;
Xcode get xcode => context.get<Xcode>();
class Xcode {
bool get isInstalledAndMeetsVersionCheck => isInstalled && isVersionSatisfactory;
String _xcodeSelectPath;
String get xcodeSelectPath {
if (_xcodeSelectPath == null) {
try {
_xcodeSelectPath = processManager.runSync(<String>['/usr/bin/xcode-select', '--print-path']).stdout.trim();
} on ProcessException {
// Ignored, return null below.
}
}
return _xcodeSelectPath;
}
bool get isInstalled {
if (xcodeSelectPath == null || xcodeSelectPath.isEmpty)
return false;
return xcodeProjectInterpreter.isInstalled;
}
int get majorVersion => xcodeProjectInterpreter.majorVersion;
int get minorVersion => xcodeProjectInterpreter.minorVersion;
String get versionText => xcodeProjectInterpreter.versionText;
bool _eulaSigned;
/// Has the EULA been signed?
bool get eulaSigned {
if (_eulaSigned == null) {
try {
final ProcessResult result = processManager.runSync(<String>['/usr/bin/xcrun', 'clang']);
if (result.stdout != null && result.stdout.contains('license'))
_eulaSigned = false;
else if (result.stderr != null && result.stderr.contains('license'))
_eulaSigned = false;
else
_eulaSigned = true;
} on ProcessException {
_eulaSigned = false;
}
}
return _eulaSigned;
}
bool _isSimctlInstalled;
/// Verifies that simctl is installed by trying to run it.
bool get isSimctlInstalled {
if (_isSimctlInstalled == null) {
try {
// This command will error if additional components need to be installed in
// xcode 9.2 and above.
final ProcessResult result = processManager.runSync(<String>['/usr/bin/xcrun', 'simctl', 'list']);
_isSimctlInstalled = result.stderr == null || result.stderr == '';
} on ProcessException {
_isSimctlInstalled = false;
}
}
return _isSimctlInstalled;
}
bool get isVersionSatisfactory {
if (!xcodeProjectInterpreter.isInstalled)
return false;
if (majorVersion > kXcodeRequiredVersionMajor)
return true;
if (majorVersion == kXcodeRequiredVersionMajor)
return minorVersion >= kXcodeRequiredVersionMinor;
return false;
}
Future<RunResult> cc(List<String> args) {
return runCheckedAsync(<String>['xcrun', 'cc']..addAll(args));
}
Future<RunResult> clang(List<String> args) {
return runCheckedAsync(<String>['xcrun', 'clang']..addAll(args));
}
String getSimulatorPath() {
if (xcodeSelectPath == null)
return null;
final List<String> searchPaths = <String>[
fs.path.join(xcodeSelectPath, 'Applications', 'Simulator.app'),
];
return searchPaths.where((String p) => p != null).firstWhere(
(String p) => fs.directory(p).existsSync(),
orElse: () => null,
);
}
}