Skip to content

Commit 1a39ae2

Browse files
authored
refactor(Pods): Allow specifying target platform (#91)
1 parent 255d2e8 commit 1a39ae2

File tree

18 files changed

+282
-212
lines changed

18 files changed

+282
-212
lines changed

example/ios/Podfile.lock

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PODS:
22
- boost-for-react-native (1.63.0)
33
- DoubleConversion (1.1.6)
4-
- Example-Tests (0.0.13):
4+
- Example-Tests (0.0.14):
55
- React
66
- Folly (2018.10.22.00):
77
- boost-for-react-native
@@ -82,7 +82,7 @@ PODS:
8282
- React-Core (= 0.60.6)
8383
- React-RCTWebSocket (0.60.6):
8484
- React-Core (= 0.60.6)
85-
- ReactTestApp-DevSupport (0.0.13)
85+
- ReactTestApp-DevSupport (0.0.14)
8686
- ReactTestApp-Resources (1.0.0-dev)
8787
- SwiftLint (0.39.1)
8888
- yoga (0.60.6.React)
@@ -174,7 +174,7 @@ EXTERNAL SOURCES:
174174
SPEC CHECKSUMS:
175175
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
176176
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
177-
Example-Tests: abfe5bd8e60d7a710889bb681b9b4cbb6ced86e5
177+
Example-Tests: 89126626c7905017d8c49e0817b87623d9b09266
178178
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
179179
glog: 1f3da668190260b06b429bb211bfbee5cd790c28
180180
QRCodeReader.swift: 373a389fe9a22d513c879a32a6f647c58f4ef572
@@ -195,8 +195,8 @@ SPEC CHECKSUMS:
195195
React-RCTText: d91537e29e38dc69cf09cbca0875cf5dc7402da6
196196
React-RCTVibration: 7655d72dfb919dd6d8e135ca108a5a2bd9fcd7b4
197197
React-RCTWebSocket: 7cd2c8d0f8ddd680dc76404defba7ab1f56b83af
198-
ReactTestApp-DevSupport: fc28c1c32fce792379542f36b38fc44c335a50da
199-
ReactTestApp-Resources: d25032e61dffcd03da09f537f9a7bab33613e2f0
198+
ReactTestApp-DevSupport: 7b8bf85ce84176899550a1556b4f9f2fc39f6a9f
199+
ReactTestApp-Resources: c070f72dfcb2806d922eec6656259cbf7a4d2bcf
200200
SwiftLint: 55e96a4a4d537d4a3156859fc1c54bd24851a046
201201
yoga: 5079887aa3e4c62142d6bcee493022643ee4d730
202202

ios/test_app.rb

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
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

ios/use_react_native-0.60.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
#
77
# rubocop:disable Layout/LineLength
88

9-
def include_react_native!(react_native)
9+
def include_react_native!(react_native, target_platform)
10+
react_native = "#{react_native}-macos" if target_platform == :macos
11+
1012
pod 'React', :path => react_native
1113
pod 'React-Core', :path => "#{react_native}/React", :inhibit_warnings => true
1214
pod 'React-DevSupport', :path => "#{react_native}/React"

ios/use_react_native-0.61.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
#
77
# rubocop:disable Layout/LineLength
88

9-
def include_react_native!(react_native)
9+
def include_react_native!(react_native, target_platform)
10+
react_native = "#{react_native}-macos" if target_platform == :macos
11+
1012
pod 'FBLazyVector', :path => "#{react_native}/Libraries/FBLazyVector"
1113
pod 'FBReactNativeSpec', :path => "#{react_native}/Libraries/FBReactNativeSpec"
1214
pod 'RCTRequired', :path => "#{react_native}/Libraries/RCTRequired"

macos/test_app.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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_relative('../ios/test_app.rb')
9+
10+
def use_test_app!
11+
use_test_app_internal!(:macos) do |target|
12+
yield target if block_given?
13+
end
14+
end

test/fixtures/with_ios_resources/app.json

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "TestFixture",
3+
"displayName": "TestFixture",
4+
"components": [
5+
{
6+
"appKey": "TestFixture",
7+
"displayName": "Test"
8+
}
9+
],
10+
"resources": {
11+
"ios": [
12+
"dist-ios/assets",
13+
"dist-ios/main.jsbundle"
14+
],
15+
"macos": [
16+
"dist-macos/assets",
17+
"dist-macos/main.jsbundle"
18+
]
19+
}
20+
}

test/fixtures/with_resources/app.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
{
22
"name": "TestFixture",
33
"displayName": "TestFixture",
4-
"components": {
5-
"TestFixture": {
4+
"components": [
5+
{
6+
"appKey": "TestFixture",
67
"displayName": "Test"
78
}
8-
},
9+
],
910
"resources": [
1011
"dist/assets",
1112
"dist/main.jsbundle"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*
2+
!.gitignore
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
{
22
"name": "TestFixture",
33
"displayName": "TestFixture",
4-
"components": {
5-
"TestFixture": {
4+
"components": [
5+
{
6+
"appKey": "TestFixture",
67
"displayName": "Test"
78
}
8-
},
9+
],
910
"resources": {
1011
}
1112
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*
2+
!.gitignore
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*
2+
!.gitignore
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
{
22
"name": "TestFixture",
33
"displayName": "TestFixture",
4-
"components": {
5-
"TestFixture": {
4+
"components": [
5+
{
6+
"appKey": "TestFixture",
67
"displayName": "Test"
78
}
8-
}
9+
]
910
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*
2+
!.gitignore

0 commit comments

Comments
 (0)