• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'dart:async';
6import 'dart:io' as dart_io;
7
8import 'package:file/file.dart';
9import 'package:file/local.dart' as io;
10import 'package:path/path.dart' as path;
11
12import 'utils.dart';
13
14const String _kProvisioningConfigFileEnvironmentVariable = 'FLUTTER_DEVICELAB_XCODE_PROVISIONING_CONFIG';
15const String _kTestXcconfigFileName = 'TestConfig.xcconfig';
16const FileSystem _fs = io.LocalFileSystem();
17
18/// Patches the given Xcode project adding provisioning certificates and team
19/// information required to build and run the project, if
20/// FLUTTER_DEVICELAB_XCODE_PROVISIONING_CONFIG is set. If it is not set,
21/// we rely on automatic signing by Xcode.
22Future<void> prepareProvisioningCertificates(String flutterProjectPath) async {
23  final String certificateConfig = await _readProvisioningConfigFile();
24  if (certificateConfig == null) {
25    // No cert config available, rely on automatic signing by Xcode.
26    return;
27  }
28
29  await _patchXcconfigFilesIfNotPatched(flutterProjectPath);
30  final File testXcconfig = _fs.file(path.join(flutterProjectPath, 'ios/Flutter/$_kTestXcconfigFileName'));
31  await testXcconfig.writeAsString(certificateConfig);
32}
33
34Future<void> runPodInstallForCustomPodfile(String flutterProjectPath) async {
35  final String iosPath = path.join(flutterProjectPath, 'ios');
36  exec('pod', <String>['install', '--project-directory=$iosPath']);
37}
38
39Future<void> _patchXcconfigFilesIfNotPatched(String flutterProjectPath) async {
40  final List<File> xcconfigFiles = <File>[
41    _fs.file(path.join(flutterProjectPath, 'ios/Flutter/Flutter.xcconfig')),
42    _fs.file(path.join(flutterProjectPath, 'ios/Flutter/Debug.xcconfig')),
43    _fs.file(path.join(flutterProjectPath, 'ios/Flutter/Release.xcconfig')),
44  ];
45
46  bool xcconfigFileExists = false;
47
48  for (final File file in xcconfigFiles) {
49    if (await file.exists()) {
50      xcconfigFileExists = true;
51      const String include = '#include "$_kTestXcconfigFileName"';
52      final String contents = await file.readAsString();
53      final bool alreadyPatched = contents.contains(include);
54      if (!alreadyPatched) {
55        final IOSink patchOut = file.openWrite(mode: FileMode.append);
56        patchOut.writeln(); // in case EOF is not preceded by line break
57        patchOut.writeln(include);
58        await patchOut.close();
59      }
60    }
61  }
62
63  if (!xcconfigFileExists) {
64    final String candidatesFormatted = xcconfigFiles.map<String>((File f) => f.path).join(', ');
65    throw 'Failed to locate a xcconfig file to patch with provisioning profile '
66        'info. Tried: $candidatesFormatted';
67  }
68}
69
70Future<String> _readProvisioningConfigFile() async {
71  void throwUsageError(String specificMessage) {
72    throw '''
73================================================================================
74You are attempting to build an XCode project, which requires a provisioning
75certificate and team information. The test framework attempted to locate an
76.xcconfig file whose path is defined by the environment variable
77$_kProvisioningConfigFileEnvironmentVariable.
78
79$specificMessage
80================================================================================
81'''.trim();
82  }
83
84  if (!dart_io.Platform.environment.containsKey(_kProvisioningConfigFileEnvironmentVariable)) {
85    print('''
86$_kProvisioningConfigFileEnvironmentVariable variable is not defined in your
87environment. Relying on automatic signing by Xcode...
88'''.trim());
89    return null;
90  }
91
92  final String filePath = dart_io.Platform.environment[_kProvisioningConfigFileEnvironmentVariable];
93  final File file = _fs.file(filePath);
94  if (!(await file.exists())) {
95    throwUsageError('''
96File not found: $filePath
97
98It is defined by environment variable $_kProvisioningConfigFileEnvironmentVariable
99'''.trim());
100  }
101
102  return file.readAsString();
103}
104