ios.dart 3.86 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
// Copyright (c) 2017 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 'dart:io' as dart_io;

import 'package:file/file.dart';
import 'package:file/local.dart' as io;
import 'package:path/path.dart' as path;

12 13
import 'utils.dart';

14 15
const String _kProvisioningConfigFileEnvironmentVariable = 'FLUTTER_DEVICELAB_XCODE_PROVISIONING_CONFIG';
const String _kTestXcconfigFileName = 'TestConfig.xcconfig';
16
const FileSystem _fs = io.LocalFileSystem();
17 18

/// Patches the given Xcode project adding provisioning certificates and team
19 20 21
/// information required to build and run the project, if
/// FLUTTER_DEVICELAB_XCODE_PROVISIONING_CONFIG is set. If it is not set,
/// we rely on automatic signing by Xcode.
22
Future<void> prepareProvisioningCertificates(String flutterProjectPath) async {
23
  final String certificateConfig = await _readProvisioningConfigFile();
24 25 26 27
  if (certificateConfig == null) {
    // No cert config available, rely on automatic signing by Xcode.
    return;
  }
28

29
  await _patchXcconfigFilesIfNotPatched(flutterProjectPath);
30 31 32 33
  final File testXcconfig = _fs.file(path.join(flutterProjectPath, 'ios/Flutter/$_kTestXcconfigFileName'));
  await testXcconfig.writeAsString(certificateConfig);
}

34
Future<void> runPodInstallForCustomPodfile(String flutterProjectPath) async {
35 36 37 38
  final String iosPath = path.join(flutterProjectPath, 'ios');
  exec('pod', <String>['install', '--project-directory=$iosPath']);
}

39
Future<void> _patchXcconfigFilesIfNotPatched(String flutterProjectPath) async {
40 41 42
  final List<File> xcconfigFiles = <File>[
    _fs.file(path.join(flutterProjectPath, 'ios/Flutter/Flutter.xcconfig')),
    _fs.file(path.join(flutterProjectPath, 'ios/Flutter/Debug.xcconfig')),
43
    _fs.file(path.join(flutterProjectPath, 'ios/Flutter/Release.xcconfig')),
44 45 46 47 48
  ];

  bool xcconfigFileExists = false;

  for (final File file in xcconfigFiles) {
49
    if (await file.exists()) {
50 51 52
      xcconfigFileExists = true;
      const String include = '#include "$_kTestXcconfigFileName"';
      final String contents = await file.readAsString();
53 54
      final bool alreadyPatched = contents.contains(include);
      if (!alreadyPatched) {
55
        final IOSink patchOut = file.openWrite(mode: FileMode.append);
56
        patchOut.writeln(); // in case EOF is not preceded by line break
57 58 59 60
        patchOut.writeln(include);
        await patchOut.close();
      }
    }
61 62
  }

63 64 65 66 67
  if (!xcconfigFileExists) {
    final String candidatesFormatted = xcconfigFiles.map<String>((File f) => f.path).join(', ');
    throw 'Failed to locate a xcconfig file to patch with provisioning profile '
        'info. Tried: $candidatesFormatted';
  }
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
}

Future<String> _readProvisioningConfigFile() async {
  void throwUsageError(String specificMessage) {
    throw '''
================================================================================
You are attempting to build an XCode project, which requires a provisioning
certificate and team information. The test framework attempted to locate an
.xcconfig file whose path is defined by the environment variable
$_kProvisioningConfigFileEnvironmentVariable.

$specificMessage
================================================================================
'''.trim();
  }

  if (!dart_io.Platform.environment.containsKey(_kProvisioningConfigFileEnvironmentVariable)) {
85
    print('''
86
$_kProvisioningConfigFileEnvironmentVariable variable is not defined in your
87
environment. Relying on automatic signing by Xcode...
88
'''.trim());
89
    return null;
90 91 92 93 94 95 96 97 98 99 100 101 102 103
  }

  final String filePath = dart_io.Platform.environment[_kProvisioningConfigFileEnvironmentVariable];
  final File file = _fs.file(filePath);
  if (!(await file.exists())) {
    throwUsageError('''
File not found: $filePath

It is defined by environment variable $_kProvisioningConfigFileEnvironmentVariable
'''.trim());
  }

  return file.readAsString();
}