|
| 1 | +# |
| 2 | +# Copyright (c) Microsoft Corporation. All rights reserved. |
| 3 | +# |
| 4 | +# This source code is licensed under the MIT license found in the |
| 5 | +# LICENSE file in the root directory of this source tree. |
| 6 | +# |
| 7 | + |
| 8 | +require('json') |
| 9 | +require('pathname') |
| 10 | + |
| 11 | +def assert(condition, message) |
| 12 | + raise message unless condition |
| 13 | +end |
| 14 | + |
| 15 | +def autolink_script_path |
| 16 | + package_path = resolve_module('@react-native-community/cli-platform-ios') |
| 17 | + File.join(package_path, 'native_modules') |
| 18 | +end |
| 19 | + |
| 20 | +def find_file(file_name, current_dir) |
| 21 | + return if current_dir.expand_path.to_s == '/' |
| 22 | + |
| 23 | + path = current_dir + file_name |
| 24 | + return path if File.exist?(path) |
| 25 | + |
| 26 | + find_file(file_name, current_dir.parent) |
| 27 | +end |
| 28 | + |
| 29 | +def find_project_root |
| 30 | + podfile_path = Thread.current.backtrace_locations.find do |location| |
| 31 | + File.basename(location.absolute_path) == 'Podfile' |
| 32 | + end |
| 33 | + assert(!podfile_path.nil?, "Could not find 'Podfile'") |
| 34 | + |
| 35 | + Pathname.new(File.dirname(podfile_path.absolute_path)) |
| 36 | +end |
| 37 | + |
| 38 | +def nearest_node_modules(project_root) |
| 39 | + path = find_file('node_modules', project_root) |
| 40 | + assert(!path.nil?, "Could not find 'node_modules'") |
| 41 | + |
| 42 | + path |
| 43 | +end |
| 44 | + |
| 45 | +def resolve_module(request) |
| 46 | + script = "console.log(path.dirname(require.resolve('#{request}/package.json')));" |
| 47 | + Pod::Executable.execute_command('node', ['-e', script], true).strip |
| 48 | +end |
| 49 | + |
| 50 | +def resolve_resources(manifest, target_platform) |
| 51 | + resources = manifest['resources'] |
| 52 | + return if !resources || resources.empty? |
| 53 | + |
| 54 | + resources.instance_of?(Array) ? resources : resources[target_platform.to_s] |
| 55 | +end |
| 56 | + |
| 57 | +def resources_pod(project_root, target_platform) |
| 58 | + app_manifest = find_file('app.json', project_root) |
| 59 | + return if app_manifest.nil? |
| 60 | + |
| 61 | + resources = resolve_resources(JSON.parse(File.read(app_manifest)), target_platform) |
| 62 | + return if !resources.instance_of?(Array) || resources.empty? |
| 63 | + |
| 64 | + spec = { |
| 65 | + 'name' => 'ReactTestApp-Resources', |
| 66 | + 'version' => '1.0.0-dev', |
| 67 | + 'summary' => 'Resources for ReactTestApp', |
| 68 | + 'homepage' => 'https://github.com/microsoft/react-native-test-app', |
| 69 | + 'license' => 'Unlicense', |
| 70 | + 'authors' => '@microsoft/react-native-test-app', |
| 71 | + 'source' => { 'git' => 'https://github.com/microsoft/react-native-test-app.git' }, |
| 72 | + 'platforms' => { |
| 73 | + 'ios' => '12.0', |
| 74 | + 'osx' => '10.14' |
| 75 | + }, |
| 76 | + 'resources' => resources |
| 77 | + } |
| 78 | + |
| 79 | + app_dir = File.dirname(app_manifest) |
| 80 | + podspec_path = File.join(app_dir, 'ReactTestApp-Resources.podspec.json') |
| 81 | + File.write(podspec_path, spec.to_json) |
| 82 | + at_exit { File.delete(podspec_path) if File.exist?(podspec_path) } |
| 83 | + Pathname.new(app_dir).relative_path_from(project_root).to_s |
| 84 | +end |
| 85 | + |
| 86 | +def use_react_native!(project_root, target_platform) |
| 87 | + react_native = Pathname.new(resolve_module('react-native')) |
| 88 | + |
| 89 | + package_json = JSON.parse(File.read(File.join(react_native.to_s, 'package.json'))) |
| 90 | + version = package_json['version'].match(/(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/) |
| 91 | + |
| 92 | + if version[:major] == '0' && version[:minor] == '60' |
| 93 | + require_relative('use_react_native-0.60') |
| 94 | + elsif version[:major] == '0' && version[:minor] == '61' |
| 95 | + require_relative('use_react_native-0.61') |
| 96 | + else |
| 97 | + raise "Unsupported React Native version: #{version[0]}" |
| 98 | + end |
| 99 | + |
| 100 | + include_react_native!(react_native.relative_path_from(project_root).to_s, target_platform) |
| 101 | +end |
| 102 | + |
| 103 | +def use_test_app_internal!(target_platform) |
| 104 | + assert(%i[ios macos].include?(target_platform), "Unsupported platform: #{target_platform}") |
| 105 | + |
| 106 | + xcodeproj = 'ReactTestApp.xcodeproj' |
| 107 | + src_xcodeproj = File.join(__dir__, '..', target_platform.to_s, xcodeproj) |
| 108 | + project_root = find_project_root |
| 109 | + destination = File.join(nearest_node_modules(project_root), '.generated') |
| 110 | + dst_xcodeproj = File.join(destination, xcodeproj) |
| 111 | + |
| 112 | + # Copy/link Xcode project files |
| 113 | + FileUtils.mkdir_p(dst_xcodeproj) |
| 114 | + FileUtils.cp(File.join(src_xcodeproj, 'project.pbxproj'), dst_xcodeproj) |
| 115 | + FileUtils.ln_sf(File.join(src_xcodeproj, 'xcshareddata'), dst_xcodeproj) |
| 116 | + |
| 117 | + # Link source files |
| 118 | + %w[ReactTestApp ReactTestAppTests ReactTestAppUITests].each do |file| |
| 119 | + FileUtils.ln_sf(File.join(__dir__, '..', 'ios', file), destination) |
| 120 | + end |
| 121 | + |
| 122 | + require_relative(autolink_script_path) |
| 123 | + |
| 124 | + platform :ios, '12.0' if target_platform == :ios |
| 125 | + platform :osx, '10.14' if target_platform == :macos |
| 126 | + |
| 127 | + project dst_xcodeproj |
| 128 | + |
| 129 | + target 'ReactTestApp' do |
| 130 | + pod 'QRCodeReader.swift' if target_platform == :ios |
| 131 | + pod 'SwiftLint' |
| 132 | + |
| 133 | + use_react_native!(project_root, target_platform) |
| 134 | + |
| 135 | + if (resources_pod_path = resources_pod(project_root, target_platform)) |
| 136 | + pod 'ReactTestApp-Resources', :path => resources_pod_path |
| 137 | + end |
| 138 | + |
| 139 | + yield ReactTestAppTargets.new(self) |
| 140 | + |
| 141 | + use_native_modules! '.' |
| 142 | + end |
| 143 | + |
| 144 | + post_install do |
| 145 | + puts '' |
| 146 | + puts 'NOTE' |
| 147 | + puts " `#{xcodeproj}` was sourced from `react-native-test-app`" |
| 148 | + puts ' All modifications will be overwritten next time you run `pod install`' |
| 149 | + puts '' |
| 150 | + end |
| 151 | +end |
| 152 | + |
| 153 | +class ReactTestAppTargets |
| 154 | + def initialize(podfile) |
| 155 | + @podfile = podfile |
| 156 | + end |
| 157 | + |
| 158 | + def app |
| 159 | + yield if block_given? |
| 160 | + end |
| 161 | + |
| 162 | + def tests |
| 163 | + @podfile.target 'ReactTestAppTests' do |
| 164 | + @podfile.inherit! :search_paths |
| 165 | + yield if block_given? |
| 166 | + end |
| 167 | + end |
| 168 | + |
| 169 | + def ui_tests |
| 170 | + @podfile.target 'ReactTestAppUITests' do |
| 171 | + @podfile.inherit! :search_paths |
| 172 | + yield if block_given? |
| 173 | + end |
| 174 | + end |
| 175 | +end |
0 commit comments