react_native_util 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +39 -31
- data/lib/assets/templates/Podfile.erb +3 -0
- data/lib/react_native_util/converter.rb +47 -160
- data/lib/react_native_util/exceptions.rb +3 -3
- data/lib/react_native_util/metadata.rb +1 -1
- data/lib/react_native_util/project.rb +141 -0
- data/lib/react_native_util/util.rb +55 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f874dfbe6f26ca09e59e9392f1e6591d09148b6a34aba766a41feea3bb2957e
|
4
|
+
data.tar.gz: 6ccfddce4c25414ef398924bb426dc0191851fb40c1ad6477e19f1eb3970b6cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 798ac753cc2ca53970ee8def6a65f24159a69b300e1259864ee59bc9d888aed2323d282bf053e7a78dd9d57f1f4f267d56b471ab0e0bb02ea365aff2ff4e9f13
|
7
|
+
data.tar.gz: bfd1a390de9180aed09a3a7da175a938a25743c99233937b499a21eab4c04961d6d35553f1676c44af4f3db3b89705f762dbb377c434b55ff8d602365a5dfaf4
|
data/README.md
CHANGED
@@ -13,9 +13,13 @@ Community utility CLI for React Native projects.
|
|
13
13
|
|
14
14
|
_macOS required_
|
15
15
|
|
16
|
+
It's not necessary to install yarn or react-native-cli separately when
|
17
|
+
installing from the Homebrew tap with `brew install jdee/tap/react_native_util`.
|
18
|
+
They will be installed as required dependencies. If they are not present when
|
19
|
+
running from RubyGems, the react_pod command will fail.
|
16
20
|
```bash
|
17
|
-
brew install yarn
|
18
|
-
|
21
|
+
brew install yarn
|
22
|
+
brew install react-native-cli
|
19
23
|
```
|
20
24
|
|
21
25
|
## Installation
|
@@ -56,35 +60,35 @@ git status
|
|
56
60
|
|
57
61
|
_Typical command output:_
|
58
62
|
```
|
59
|
-
2019-05-
|
60
|
-
[✔] yarn install success in
|
61
|
-
2019-05-
|
62
|
-
2019-05-
|
63
|
-
2019-05-
|
64
|
-
2019-05-
|
65
|
-
2019-05-
|
66
|
-
2019-05-
|
67
|
-
2019-05-
|
68
|
-
2019-05-
|
69
|
-
2019-05-
|
70
|
-
2019-05-
|
71
|
-
2019-05-
|
72
|
-
2019-05-
|
73
|
-
2019-05-
|
74
|
-
2019-05-
|
75
|
-
2019-05-
|
76
|
-
2019-05-
|
77
|
-
[✔] react-native unlink react-native-webview success in 0.
|
78
|
-
2019-05-
|
79
|
-
2019-05-
|
80
|
-
2019-05-
|
81
|
-
2019-05-
|
82
|
-
2019-05-
|
63
|
+
2019-05-12T15:37:50-07:00 react_native_util react_pod v0.3.0
|
64
|
+
[✔] yarn install success in 7.2 s
|
65
|
+
2019-05-12T15:37:57-07:00 Darwin 18.5.0 x86_64
|
66
|
+
2019-05-12T15:37:57-07:00 Ruby 2.6.3: ~/.rvm/rubies/ruby-2.6.3/bin/ruby
|
67
|
+
2019-05-12T15:37:57-07:00 RubyGems 3.0.3: ~/.rvm/rubies/ruby-2.6.3/bin/gem
|
68
|
+
2019-05-12T15:37:57-07:00 Bundler 1.17.2: ~/.rvm/gems/ruby-2.6.3/bin/bundle
|
69
|
+
2019-05-12T15:37:57-07:00 react-native-cli: /usr/local/bin/react-native
|
70
|
+
2019-05-12T15:37:57-07:00 react-native-cli: 2.0.1
|
71
|
+
2019-05-12T15:37:57-07:00 react-native: 0.59.8
|
72
|
+
2019-05-12T15:37:58-07:00 yarn 1.16.0: /usr/local/bin/yarn
|
73
|
+
2019-05-12T15:37:58-07:00 cocoapods 1.6.1: ~/.rvm/gems/ruby-2.6.3/bin/pod
|
74
|
+
2019-05-12T15:37:58-07:00 cocoapods-core: 1.6.1
|
75
|
+
2019-05-12T15:37:58-07:00 package.json:
|
76
|
+
2019-05-12T15:37:58-07:00 app name: "TestApp"
|
77
|
+
2019-05-12T15:37:58-07:00 Found Xcode project at ~/github/jdee/react_native_util/examples/TestApp/ios/TestApp.xcodeproj
|
78
|
+
2019-05-12T15:37:58-07:00 Dependencies:
|
79
|
+
2019-05-12T15:37:58-07:00 react-native-webview
|
80
|
+
2019-05-12T15:37:58-07:00 Unlinking dependencies
|
81
|
+
[✔] react-native unlink react-native-webview success in 0.6 s
|
82
|
+
2019-05-12T15:37:59-07:00 Removing Libraries from TestApp
|
83
|
+
2019-05-12T15:37:59-07:00 Removing Libraries from TestAppTests
|
84
|
+
2019-05-12T15:37:59-07:00 Removing Libraries group
|
85
|
+
2019-05-12T15:37:59-07:00 Generating ios/Podfile
|
86
|
+
2019-05-12T15:37:59-07:00 Linking dependencies
|
83
87
|
[✔] react-native link react-native-webview success in 0.5 s
|
84
|
-
2019-05-
|
85
|
-
[✔] pod install success in
|
86
|
-
2019-05-
|
87
|
-
2019-05-
|
88
|
+
2019-05-12T15:37:59-07:00 Generating Pods project and ios/TestApp.xcworkspace
|
89
|
+
[✔] pod install success in 12.2 s
|
90
|
+
2019-05-12T15:38:12-07:00 Conversion complete ✅
|
91
|
+
2019-05-12T15:38:12-07:00 $ open ios/TestApp.xcworkspace
|
88
92
|
```
|
89
93
|
|
90
94
|
## Rake task
|
@@ -112,6 +116,10 @@ ReactNativeUtil::Rake::ReactPodTask.new(
|
|
112
116
|
require 'react_native_util/converter'
|
113
117
|
|
114
118
|
Dir.chdir '/path/to/rn/project' do
|
115
|
-
|
119
|
+
begin
|
120
|
+
ReactNativeUtil::Converter.new(repo_update: true).convert_to_react_pod!
|
121
|
+
rescue ReactNativeUtil::BaseException => e
|
122
|
+
puts "Error from #convert_to_react_pod!: #{e.message}"
|
123
|
+
end
|
116
124
|
end
|
117
125
|
```
|
@@ -11,6 +11,9 @@ target '<%= app_name %>' do
|
|
11
11
|
]
|
12
12
|
pod 'yoga', path: '../node_modules/react-native/ReactCommon/yoga'
|
13
13
|
pod 'Folly', podspec: '../node_modules/react-native/third-party-podspecs/Folly.podspec'
|
14
|
+
|
15
|
+
# --- react-native link adds pods below this line. ---
|
16
|
+
|
14
17
|
end
|
15
18
|
|
16
19
|
<% if test_target %>
|
@@ -2,49 +2,29 @@ require 'cocoapods-core'
|
|
2
2
|
require 'erb'
|
3
3
|
require 'json'
|
4
4
|
require 'rubygems'
|
5
|
-
|
6
|
-
require 'tty/platform'
|
7
|
-
require 'xcodeproj'
|
8
|
-
require_relative 'util'
|
5
|
+
require_relative 'project'
|
9
6
|
|
10
7
|
module ReactNativeUtil
|
11
8
|
# Class to perform conversion operations.
|
12
9
|
class Converter
|
13
10
|
include Util
|
14
11
|
|
15
|
-
# [Array<String>] Xcode projects from react-native that may be in the Libraries group
|
16
|
-
DEFAULT_DEPENDENCIES = %w[
|
17
|
-
ART
|
18
|
-
React
|
19
|
-
RCTActionSheet
|
20
|
-
RCTAnimation
|
21
|
-
RCTBlob
|
22
|
-
RCTCameraRoll
|
23
|
-
RCTGeolocation
|
24
|
-
RCTImage
|
25
|
-
RCTLinking
|
26
|
-
RCTNetwork
|
27
|
-
RCTPushNotification
|
28
|
-
RCTSettings
|
29
|
-
RCTTest
|
30
|
-
RCTText
|
31
|
-
RCTVibration
|
32
|
-
RCTWebSocket
|
33
|
-
]
|
34
|
-
|
35
12
|
# [String] Path to the Podfile template
|
36
13
|
PODFILE_TEMPLATE_PATH = File.expand_path '../assets/templates/Podfile.erb', __dir__
|
37
14
|
|
15
|
+
REQUIRED_COMMANDS = [:yarn, 'react-native' => 'react-native-cli']
|
16
|
+
|
38
17
|
# [Hash] Contents of ./package.json
|
39
18
|
attr_reader :package_json
|
40
19
|
|
41
20
|
# [String] Full path to Xcode project
|
42
21
|
attr_reader :xcodeproj_path
|
43
22
|
|
44
|
-
# [
|
45
|
-
attr_reader :
|
23
|
+
# [Project] Contents of the project at xcodeproj_path
|
24
|
+
attr_reader :project
|
46
25
|
|
47
26
|
attr_reader :options
|
27
|
+
attr_reader :react_project
|
48
28
|
attr_reader :react_podspec
|
49
29
|
|
50
30
|
def initialize(repo_update: nil)
|
@@ -56,9 +36,27 @@ module ReactNativeUtil
|
|
56
36
|
end
|
57
37
|
end
|
58
38
|
|
59
|
-
# Convert project to use React pod
|
60
|
-
#
|
39
|
+
# Convert project to use React pod. Expects the app's package.json in the
|
40
|
+
# current directory.
|
41
|
+
#
|
42
|
+
# require 'react_native_util/converter'
|
43
|
+
#
|
44
|
+
# Dir.chdir '/path/to/rn/project' do
|
45
|
+
# begin
|
46
|
+
# ReactNativeUtil::Converter.new(repo_update: true).convert_to_react_pod!
|
47
|
+
# rescue ReactNativeUtil::BaseException => e
|
48
|
+
# # All exceptions generated by this gem inherit from
|
49
|
+
# # ReactNativeUtil::BaseException.
|
50
|
+
# puts "Error from #convert_to_react_pod!: #{e.message}"
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# @raise ConversionError on conversion failure
|
55
|
+
# @raise ExecutionError on generic command failure
|
56
|
+
# @raise Errno::ENOENT if a required command is not present
|
61
57
|
def convert_to_react_pod!
|
58
|
+
validate_commands! REQUIRED_COMMANDS
|
59
|
+
|
62
60
|
# Make sure no uncommitted changes
|
63
61
|
check_repo_status!
|
64
62
|
|
@@ -75,7 +73,7 @@ module ReactNativeUtil
|
|
75
73
|
load_xcodeproj!
|
76
74
|
log "Found Xcode project at #{xcodeproj_path}"
|
77
75
|
|
78
|
-
if libraries_group.nil?
|
76
|
+
if project.libraries_group.nil?
|
79
77
|
log "Libraries group not found in #{xcodeproj_path}. No conversion necessary."
|
80
78
|
exit 0
|
81
79
|
end
|
@@ -87,35 +85,37 @@ module ReactNativeUtil
|
|
87
85
|
exit 1
|
88
86
|
end
|
89
87
|
|
88
|
+
project.validate_app_target!
|
89
|
+
|
90
90
|
load_react_podspec!
|
91
91
|
|
92
92
|
# 2. Detect native dependencies in Libraries group.
|
93
93
|
log 'Dependencies:'
|
94
|
-
dependencies.each { |d| log " #{d}" }
|
94
|
+
project.dependencies.each { |d| log " #{d}" }
|
95
95
|
|
96
96
|
# Save for after Libraries removed.
|
97
|
-
deps_to_add = dependencies
|
97
|
+
deps_to_add = project.dependencies
|
98
98
|
|
99
99
|
# 3. Run react-native unlink for each one.
|
100
100
|
log 'Unlinking dependencies'
|
101
|
-
dependencies.each do |dep|
|
101
|
+
project.dependencies.each do |dep|
|
102
102
|
run_command_with_spinner! 'react-native', 'unlink', dep, log: File.join(Dir.tmpdir, "react-native-unlink-#{dep}.log")
|
103
103
|
end
|
104
104
|
|
105
105
|
# reload after react-native unlink
|
106
106
|
load_xcodeproj!
|
107
|
+
load_react_project!
|
107
108
|
|
108
109
|
# 4a. Add Start Packager script
|
109
|
-
|
110
|
-
add_packager_script
|
110
|
+
project.add_packager_script_from react_project
|
111
111
|
|
112
112
|
# Make a note of pod subspecs to replace Libraries group
|
113
113
|
load_subspecs_from_libraries
|
114
114
|
|
115
115
|
# 4b. Remove Libraries group from Xcode project.
|
116
|
-
|
116
|
+
project.remove_libraries_group
|
117
117
|
|
118
|
-
|
118
|
+
project.save
|
119
119
|
|
120
120
|
# 5. Generate boilerplate Podfile.
|
121
121
|
generate_podfile!
|
@@ -207,8 +207,9 @@ module ReactNativeUtil
|
|
207
207
|
# Load the project at @xcodeproj_path into @xcodeproj
|
208
208
|
# @raise ConversionError on failure
|
209
209
|
def load_xcodeproj!
|
210
|
-
@
|
211
|
-
@
|
210
|
+
@project = nil # in case of exception on reopen
|
211
|
+
@project = Project.open xcodeproj_path
|
212
|
+
@project.app_name = app_name
|
212
213
|
rescue Errno::ENOENT
|
213
214
|
raise ConversionError, "Failed to open #{xcodeproj_path}. File not found."
|
214
215
|
rescue Xcodeproj::PlainInformative => e
|
@@ -226,72 +227,9 @@ module ReactNativeUtil
|
|
226
227
|
# rubocop: enable Security/Eval
|
227
228
|
end
|
228
229
|
|
229
|
-
# A representation of the Libraries group (if any) from the Xcode project.
|
230
|
-
# @return the Libraries group
|
231
|
-
def libraries_group
|
232
|
-
xcodeproj['Libraries']
|
233
|
-
end
|
234
|
-
|
235
|
-
# Remove the Libraries group from the xcodeproj in memory.
|
236
|
-
# Resets @libraries_group to nil as well.
|
237
|
-
def remove_libraries_group_from_project!
|
238
|
-
# Remove links against these static libraries
|
239
|
-
xcodeproj.targets.reject { |t| t.name =~ /-tvOS/ }.each do |t|
|
240
|
-
remove_libraries_from_target t
|
241
|
-
end
|
242
|
-
|
243
|
-
log 'Removing Libraries group'
|
244
|
-
libraries_group.remove_from_project
|
245
|
-
end
|
246
|
-
|
247
|
-
def remove_libraries_from_target(target)
|
248
|
-
log "Removing Libraries from #{target.name}"
|
249
|
-
to_remove = target.frameworks_build_phase.files.select do |file|
|
250
|
-
path = file.file_ref.pretty_print
|
251
|
-
next false unless /^lib(.+)\.a$/.match?(path)
|
252
|
-
|
253
|
-
static_libs.include?(path)
|
254
|
-
end
|
255
|
-
|
256
|
-
to_remove.each { |f| target.frameworks_build_phase.remove_build_file f }
|
257
|
-
end
|
258
|
-
|
259
|
-
# A list of external dependencies from NPM requiring react-native link.
|
260
|
-
# @return [Array<String>] a list of NPM package names
|
261
|
-
def dependencies
|
262
|
-
return [] if libraries_group.nil?
|
263
|
-
|
264
|
-
dependency_paths.map do |path|
|
265
|
-
# Find the root above the ios/*.xcodeproj under node_modules
|
266
|
-
root = File.expand_path '../..', path
|
267
|
-
File.basename root
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
|
-
# Paths to Xcode projects in the Libraries group from external deps.
|
272
|
-
# @return [Array<String>] a list of absolute paths to Xcode projects
|
273
|
-
def dependency_paths
|
274
|
-
return [] if libraries_group.nil?
|
275
|
-
|
276
|
-
paths = libraries_group.children.reject { |c| DEFAULT_DEPENDENCIES.include?(c.name.sub(/\.xcodeproj$/, '')) }.map(&:path)
|
277
|
-
paths.map { |p| File.expand_path p, File.join(Dir.pwd, 'ios') }
|
278
|
-
end
|
279
|
-
|
280
|
-
def library_roots
|
281
|
-
libraries_group.children.map do |library|
|
282
|
-
File.basename(library.path).sub(/\.xcodeproj$/, '')
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
|
-
# All static libraries from the Libraries group
|
287
|
-
# @return [Array<String>] an array of filenames
|
288
|
-
def static_libs
|
289
|
-
library_roots.map { |root| "lib#{root}.a" }
|
290
|
-
end
|
291
|
-
|
292
230
|
def load_subspecs_from_libraries
|
293
|
-
roots = library_roots - %w[React]
|
294
|
-
@subspecs_from_libraries = roots.select { |r| DEFAULT_DEPENDENCIES.include?(r) }.map do |root|
|
231
|
+
roots = project.library_roots - %w[React]
|
232
|
+
@subspecs_from_libraries = roots.select { |r| Project::DEFAULT_DEPENDENCIES.include?(r) }.map do |root|
|
295
233
|
case root
|
296
234
|
when 'RCTLinking'
|
297
235
|
'RCTLinkingIOS'
|
@@ -308,18 +246,11 @@ module ReactNativeUtil
|
|
308
246
|
end
|
309
247
|
|
310
248
|
def app_target
|
311
|
-
|
249
|
+
project.app_target
|
312
250
|
end
|
313
251
|
|
314
252
|
def test_target
|
315
|
-
|
316
|
-
end
|
317
|
-
|
318
|
-
# Validate an assumption about the project. TODO: Provide override option.
|
319
|
-
# @raise ConversionError if an application target is not found with the same name as the project.
|
320
|
-
def validate_app_target!
|
321
|
-
raise ConversionError, "Unable to find target #{app_name} in #{xcodeproj_path}." if app_target.nil?
|
322
|
-
raise ConversionError, "Target #{app_name} is not an application target." unless app_target.product_type == 'com.apple.product-type.application'
|
253
|
+
project.test_target
|
323
254
|
end
|
324
255
|
|
325
256
|
def podfile_path
|
@@ -353,55 +284,11 @@ module ReactNativeUtil
|
|
353
284
|
raise ConversionError, 'Uncommitted changes in repo. Please commit or stash before continuing.'
|
354
285
|
end
|
355
286
|
|
356
|
-
#
|
357
|
-
# to the main application target before deleting React.xcodeproj from the
|
358
|
-
# Libraries group. Adjusts paths in the script to account for the different
|
359
|
-
# project location. If React.xcodeproj cannot be opened, or if the relevant
|
360
|
-
# build phase is not found, a warning is logged, and this step is skipped.
|
361
|
-
#
|
362
|
-
# TODO: The build phase is added after all other build phases. Ideally it
|
363
|
-
# can be moved to the beginning. The packager is independent of the Xcode
|
364
|
-
# build process. It may be started at any time. Starting it early is an
|
365
|
-
# optimization that allows it to load while the build is in progress.
|
366
|
-
# Currently it's possible to simply drag the build phase in Xcode to a
|
367
|
-
# higher position after running the react_pod command.
|
368
|
-
def add_packager_script
|
369
|
-
old_packager_phase = packager_phase_from_react_project
|
370
|
-
unless old_packager_phase
|
371
|
-
log 'Could not find packager build phase in React.xcodeproj. Skipping.'.yellow
|
372
|
-
return
|
373
|
-
end
|
374
|
-
|
375
|
-
# location of project is different relative to packager script
|
376
|
-
script = old_packager_phase.shell_script.gsub(%r{../scripts}, '../node_modules/react-native/scripts')
|
377
|
-
|
378
|
-
phase = app_target.new_shell_script_build_phase old_packager_phase.name
|
379
|
-
phase.shell_script = script
|
380
|
-
end
|
381
|
-
|
382
|
-
# Returns a Project object with the contents of the React.xcodeproj project
|
383
|
-
# from node_modules.
|
384
|
-
# @return [Xcodeproj::Project] a Project object with the contents of React.xcodeproj from node_modules
|
287
|
+
# Load the contents of the React.xcodeproj project from node_modules.
|
385
288
|
# @raise Xcodeproj::PlainInformative in case of most failures
|
386
|
-
def
|
387
|
-
|
388
|
-
|
389
|
-
path = libraries_group.children.find { |c| c.path =~ /React.xcodeproj/ }.real_path
|
390
|
-
@react_project = Xcodeproj::Project.open path
|
391
|
-
end
|
392
|
-
|
393
|
-
# Returns the original Start Packager build phase from the React.xcodeproj
|
394
|
-
# under node_modules. This contains the original script.
|
395
|
-
# @return the packager build phase if found
|
396
|
-
# @return nil if not found or React.xcodeproj cannot be opened
|
397
|
-
def packager_phase_from_react_project
|
398
|
-
react_project!.targets.first.build_phases.find { |p| p.name =~ /packager/i }
|
399
|
-
rescue Errno::ENOENT
|
400
|
-
log 'Could not open React.xcodeproj. File not found.'
|
401
|
-
nil
|
402
|
-
rescue Xcodeproj::PlainInformative => e
|
403
|
-
log "Could not open React.xcodeproj. #{e.message}"
|
404
|
-
nil
|
289
|
+
def load_react_project!
|
290
|
+
path = project.libraries_group.children.find { |c| c.path =~ /React.xcodeproj/ }.real_path
|
291
|
+
@react_project = Project.open path
|
405
292
|
end
|
406
293
|
end
|
407
294
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module ReactNativeUtil
|
2
2
|
# Base class for exceptions from this gem
|
3
|
-
class
|
3
|
+
class BaseException < RuntimeError
|
4
4
|
end
|
5
5
|
|
6
6
|
# Exception raised when command execution fails
|
7
|
-
class ExecutionError <
|
7
|
+
class ExecutionError < BaseException
|
8
8
|
end
|
9
9
|
|
10
10
|
# Generic conversion error
|
11
|
-
class ConversionError <
|
11
|
+
class ConversionError < BaseException
|
12
12
|
end
|
13
13
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Conversion tools for React Native projects
|
2
2
|
module ReactNativeUtil
|
3
3
|
NAME = 'react_native_util'
|
4
|
-
VERSION = '0.
|
4
|
+
VERSION = '0.3.0'
|
5
5
|
SUMMARY = 'Community utility CLI for React Native projects'
|
6
6
|
DESCRIPTION = 'Automatically modifies a project created with react-native ' \
|
7
7
|
'init to use the React pod from node_modules.'
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'xcodeproj'
|
2
|
+
require_relative 'util'
|
3
|
+
|
4
|
+
module ReactNativeUtil
|
5
|
+
class Project < Xcodeproj::Project
|
6
|
+
include Util
|
7
|
+
|
8
|
+
# [Array<String>] Xcode projects from react-native that may be in the Libraries group
|
9
|
+
DEFAULT_DEPENDENCIES = %w[
|
10
|
+
ART
|
11
|
+
React
|
12
|
+
RCTActionSheet
|
13
|
+
RCTAnimation
|
14
|
+
RCTBlob
|
15
|
+
RCTCameraRoll
|
16
|
+
RCTGeolocation
|
17
|
+
RCTImage
|
18
|
+
RCTLinking
|
19
|
+
RCTNetwork
|
20
|
+
RCTPushNotification
|
21
|
+
RCTSettings
|
22
|
+
RCTTest
|
23
|
+
RCTText
|
24
|
+
RCTVibration
|
25
|
+
RCTWebSocket
|
26
|
+
]
|
27
|
+
|
28
|
+
attr_accessor :app_name
|
29
|
+
|
30
|
+
def app_target
|
31
|
+
targets.find { |t| t.name == app_name }
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_target
|
35
|
+
targets.select(&:test_target_type?).reject { |t| t.name =~ /tvOS/ }.first
|
36
|
+
end
|
37
|
+
|
38
|
+
# Validate an assumption about the project. TODO: Provide override option.
|
39
|
+
# @raise ConversionError if an application target is not found with the same name as the project.
|
40
|
+
def validate_app_target!
|
41
|
+
raise ConversionError, "Unable to find target #{app_name} in #{path}." if app_target.nil?
|
42
|
+
raise ConversionError, "Target #{app_name} is not an application target." unless app_target.product_type == 'com.apple.product-type.application'
|
43
|
+
end
|
44
|
+
|
45
|
+
# A representation of the Libraries group (if any) from the Xcode project.
|
46
|
+
# @return the Libraries group
|
47
|
+
def libraries_group
|
48
|
+
self['Libraries']
|
49
|
+
end
|
50
|
+
|
51
|
+
# Remove the Libraries group from the xcodeproj in memory.
|
52
|
+
def remove_libraries_group
|
53
|
+
# Remove links against these static libraries
|
54
|
+
targets.reject { |t| t.name =~ /-tvOS/ }.each do |t|
|
55
|
+
remove_libraries_from_target t
|
56
|
+
end
|
57
|
+
|
58
|
+
log 'Removing Libraries group'
|
59
|
+
libraries_group.remove_from_project
|
60
|
+
end
|
61
|
+
|
62
|
+
def remove_libraries_from_target(target)
|
63
|
+
log "Removing Libraries from #{target.name}"
|
64
|
+
to_remove = target.frameworks_build_phase.files.select do |file|
|
65
|
+
path = file.file_ref.pretty_print
|
66
|
+
next false unless /^lib(.+)\.a$/.match?(path)
|
67
|
+
|
68
|
+
static_libs.include?(path)
|
69
|
+
end
|
70
|
+
|
71
|
+
to_remove.each { |f| target.frameworks_build_phase.remove_build_file f }
|
72
|
+
end
|
73
|
+
|
74
|
+
# A list of external dependencies from NPM requiring react-native link.
|
75
|
+
# @return [Array<String>] a list of NPM package names
|
76
|
+
def dependencies
|
77
|
+
return [] if libraries_group.nil?
|
78
|
+
|
79
|
+
dependency_paths.map do |path|
|
80
|
+
# Find the root above the ios/*.xcodeproj under node_modules
|
81
|
+
root = File.expand_path '../..', path
|
82
|
+
File.basename root
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Paths to Xcode projects in the Libraries group from external deps.
|
87
|
+
# @return [Array<String>] a list of absolute paths to Xcode projects
|
88
|
+
def dependency_paths
|
89
|
+
return [] if libraries_group.nil?
|
90
|
+
|
91
|
+
paths = libraries_group.children.reject { |c| DEFAULT_DEPENDENCIES.include?(c.name.sub(/\.xcodeproj$/, '')) }.map(&:path)
|
92
|
+
paths.map { |p| File.expand_path p, File.join(Dir.pwd, 'ios') }
|
93
|
+
end
|
94
|
+
|
95
|
+
def library_roots
|
96
|
+
libraries_group.children.map do |library|
|
97
|
+
File.basename(library.path).sub(/\.xcodeproj$/, '')
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Adds the Start Packager script from the React.xcodeproj under node_modules
|
102
|
+
# to the main application target before deleting React.xcodeproj from the
|
103
|
+
# Libraries group. Adjusts paths in the script to account for the different
|
104
|
+
# project location. If the relevant build phase is not found, a warning is
|
105
|
+
# logged, and this step is skipped.
|
106
|
+
#
|
107
|
+
# TODO: The build phase is added after all other build phases. Ideally it
|
108
|
+
# can be moved to the beginning. The packager is independent of the Xcode
|
109
|
+
# build process. It may be started at any time. Starting it early is an
|
110
|
+
# optimization that allows it to load while the build is in progress.
|
111
|
+
# Currently it's possible to simply drag the build phase in Xcode to a
|
112
|
+
# higher position after running the react_pod command.
|
113
|
+
def add_packager_script_from(react_project)
|
114
|
+
old_packager_phase = react_project.packager_phase
|
115
|
+
unless old_packager_phase
|
116
|
+
log 'Could not find packager build phase in React.xcodeproj. Skipping.'.yellow
|
117
|
+
return
|
118
|
+
end
|
119
|
+
|
120
|
+
# location of project is different relative to packager script
|
121
|
+
script = old_packager_phase.shell_script.gsub(%r{../scripts}, '../node_modules/react-native/scripts')
|
122
|
+
|
123
|
+
phase = app_target.new_shell_script_build_phase old_packager_phase.name
|
124
|
+
phase.shell_script = script
|
125
|
+
end
|
126
|
+
|
127
|
+
# All static libraries from the Libraries group
|
128
|
+
# @return [Array<String>] an array of filenames
|
129
|
+
def static_libs
|
130
|
+
library_roots.map { |root| "lib#{root}.a" }
|
131
|
+
end
|
132
|
+
|
133
|
+
# Returns the original Start Packager build phase (from the React.xcodeproj
|
134
|
+
# under node_modules). This contains the original script.
|
135
|
+
# @return the packager build phase if found
|
136
|
+
# @return nil if not found
|
137
|
+
def packager_phase
|
138
|
+
targets.first.build_phases.find { |p| p.name =~ /packager/i }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'colored'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'tty/platform'
|
2
4
|
require 'tty/spinner'
|
3
5
|
require_relative 'core_ext/io'
|
4
6
|
require_relative 'core_ext/regexp'
|
@@ -90,5 +92,58 @@ module ReactNativeUtil
|
|
90
92
|
def log(message)
|
91
93
|
STDOUT.log message
|
92
94
|
end
|
95
|
+
|
96
|
+
# Determine if a specific command is available.
|
97
|
+
#
|
98
|
+
# @param command [#to_s] A command to check for
|
99
|
+
# @return true if found, false otherwise
|
100
|
+
def have_command?(command)
|
101
|
+
# May be shell-dependent, OS-dependent
|
102
|
+
# Kernel#system does not raise Errno::ENOENT when running under the Bundler
|
103
|
+
!`which #{command}`.empty?
|
104
|
+
end
|
105
|
+
|
106
|
+
# Validate one or more commands. If the specified command is not
|
107
|
+
# available in the PATH (via which), a ConversionError is raised noting
|
108
|
+
# the package to be installed (from Homebrew, e.g.).
|
109
|
+
#
|
110
|
+
# When package names to be installed differ from command names, a Hash
|
111
|
+
# may be used. For example:
|
112
|
+
# validate_commands! [:yarn, 'react-native' => 'react-native-cli']
|
113
|
+
#
|
114
|
+
# @param commands [Array, Hash, #to_s] one or more commands to be validated.
|
115
|
+
# @raise ConversionError if any command not found
|
116
|
+
def validate_commands!(commands)
|
117
|
+
errors = []
|
118
|
+
|
119
|
+
case commands
|
120
|
+
when Array
|
121
|
+
# Validate each command in the array, accumulating error messages
|
122
|
+
# if necessary.
|
123
|
+
commands.each do |c|
|
124
|
+
begin
|
125
|
+
validate_commands! c
|
126
|
+
rescue ConversionError => e
|
127
|
+
errors += e.message.split("\n")
|
128
|
+
end
|
129
|
+
end
|
130
|
+
when Hash
|
131
|
+
# Each key represents a command to check. The value is the package to
|
132
|
+
# install if missing.
|
133
|
+
commands.each do |key, value|
|
134
|
+
next if have_command?(key)
|
135
|
+
|
136
|
+
errors << "#{key} command not found. Please install #{value} to continue."
|
137
|
+
end
|
138
|
+
else
|
139
|
+
# commands is a single command to be validated. The package name is the
|
140
|
+
# same. Usually a symbol or a string, but only has to respond to #to_s.
|
141
|
+
errors << "#{commands} command not found. Please install #{commands} to continue." unless have_command? commands
|
142
|
+
end
|
143
|
+
|
144
|
+
return if errors.empty?
|
145
|
+
|
146
|
+
raise ConversionError, errors.join("\n")
|
147
|
+
end
|
93
148
|
end
|
94
149
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: react_native_util
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jimmy Dee
|
@@ -229,6 +229,7 @@ files:
|
|
229
229
|
- lib/react_native_util/core_ext/string.rb
|
230
230
|
- lib/react_native_util/exceptions.rb
|
231
231
|
- lib/react_native_util/metadata.rb
|
232
|
+
- lib/react_native_util/project.rb
|
232
233
|
- lib/react_native_util/rake/react_pod_task.rb
|
233
234
|
- lib/react_native_util/util.rb
|
234
235
|
homepage: https://github.com/jdee/react_native_util
|