react_native_util 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +43 -0
- data/bin/react_native_util +5 -0
- data/bin/rn +5 -0
- data/lib/assets/templates/Podfile.erb +32 -0
- data/lib/react_native_util.rb +2 -0
- data/lib/react_native_util/cli.rb +36 -0
- data/lib/react_native_util/converter.rb +266 -0
- data/lib/react_native_util/core_ext/io.rb +31 -0
- data/lib/react_native_util/core_ext/string.rb +42 -0
- data/lib/react_native_util/exceptions.rb +13 -0
- data/lib/react_native_util/metadata.rb +8 -0
- data/lib/react_native_util/util.rb +69 -0
- metadata +241 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ef52763097785909d46e154fa9d4d03e7e86c2ec767dd588080d7af6835aeb50
|
4
|
+
data.tar.gz: 258fd214fe3297cc53ff6c6a63702e54c1e985c9d2ff8f04cd34ba2bccc0af34
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cb4075f0ab323b3cbceda2291c3493fc6a0d8b22d0ba52601ad9ef4965a07dbb0579b3befba6f0dad9ffb3984baec1bf2095874d20d0185a5b1797c73cfd6e88
|
7
|
+
data.tar.gz: c2a7cce8791f0a9521c3239aa9b3279dc485b8622909bf4e6acbd0be566fd323cfb7eb7397359d1c1c6bb3b4bd3fa43e8ff7df2ddd0e521cde0c47d77652f483
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 Jimmy Dee
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# react_native_util gem
|
2
|
+
|
3
|
+
[![Gem](https://img.shields.io/gem/v/react_native_util.svg?style=flat)](https://rubygems.org/gems/react_native_util)
|
4
|
+
[![Downloads](https://img.shields.io/gem/dt/react_native_util.svg?style=flat)](https://rubygems.org/gems/react_native_util)
|
5
|
+
[![License](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://github.com/jdee/react_native_util/blob/master/LICENSE)
|
6
|
+
[![CircleCI](https://img.shields.io/circleci/project/github/jdee/react_native_util.svg)](https://circleci.com/gh/jdee/react_native_util)
|
7
|
+
|
8
|
+
**Work in progress**
|
9
|
+
|
10
|
+
Community utility CLI for React Native projects.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
```bash
|
15
|
+
[sudo] gem install react_native_util
|
16
|
+
react_native_util -h
|
17
|
+
rn -h
|
18
|
+
```
|
19
|
+
|
20
|
+
## Gemfile
|
21
|
+
|
22
|
+
```Ruby
|
23
|
+
gem 'react_native_util'
|
24
|
+
```
|
25
|
+
|
26
|
+
## Try it out
|
27
|
+
|
28
|
+
First set up a test app:
|
29
|
+
```bash
|
30
|
+
react-native init TestApp
|
31
|
+
cd TestApp
|
32
|
+
yarn add react-native-webview
|
33
|
+
react-native link react-native-webview
|
34
|
+
git init .
|
35
|
+
git add .
|
36
|
+
git commit -m'Before conversion'
|
37
|
+
```
|
38
|
+
|
39
|
+
Now do the conversion:
|
40
|
+
```bash
|
41
|
+
rn react_pod
|
42
|
+
git status
|
43
|
+
```
|
data/bin/rn
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
platform :ios, '9.0'
|
2
|
+
|
3
|
+
target '<%= app_name %>' do
|
4
|
+
pod 'React',
|
5
|
+
path: '../node_modules/react-native',
|
6
|
+
subspecs: %w[
|
7
|
+
Core
|
8
|
+
CxxBridge
|
9
|
+
DevSupport
|
10
|
+
RCTActionSheet
|
11
|
+
RCTAnimation
|
12
|
+
RCTBlob
|
13
|
+
RCTGeolocation
|
14
|
+
RCTImage
|
15
|
+
RCTLinkingIOS
|
16
|
+
RCTNetwork
|
17
|
+
RCTSettings
|
18
|
+
RCTText
|
19
|
+
RCTVibration
|
20
|
+
RCTWebSocket
|
21
|
+
]
|
22
|
+
pod 'yoga', path: '../node_modules/react-native/ReactCommon/yoga'
|
23
|
+
pod 'Folly', podspec: '../node_modules/react-native/third-party-podspecs/Folly.podspec'
|
24
|
+
end
|
25
|
+
|
26
|
+
<% if test_target %>
|
27
|
+
target '<%= test_target.name %>' do
|
28
|
+
pod 'React', path: '../node_modules/react-native', subspecs: %w[Core CxxBridge]
|
29
|
+
pod 'yoga', path: '../node_modules/react-native/ReactCommon/yoga'
|
30
|
+
pod 'Folly', podspec: '../node_modules/react-native/third-party-podspecs/Folly.podspec'
|
31
|
+
end
|
32
|
+
<% end %>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'commander'
|
2
|
+
require_relative 'converter'
|
3
|
+
require_relative 'metadata'
|
4
|
+
|
5
|
+
module ReactNativeUtil
|
6
|
+
class CLI
|
7
|
+
include Commander::Methods
|
8
|
+
include Util
|
9
|
+
|
10
|
+
def run
|
11
|
+
program :name, SUMMARY
|
12
|
+
program :version, VERSION
|
13
|
+
program :description, DESCRIPTION
|
14
|
+
|
15
|
+
command :react_pod do |c|
|
16
|
+
c.syntax = "#{NAME} react_pod [OPTIONS]"
|
17
|
+
c.summary = 'Convert a React Native app to use the React pod from node_modules.'
|
18
|
+
c.description = "[Work in progress] Removes all static libraries built by the Libraries group and adds a generic " \
|
19
|
+
"Podfile.\nResults in a buildable, working project."
|
20
|
+
|
21
|
+
c.option '--[no-]repo-update', 'Update the local podspec repo (default: update; env. var. REACT_NATIVE_CONVERT_REPO_UPDATE)'
|
22
|
+
|
23
|
+
c.action do |_args, opts|
|
24
|
+
begin
|
25
|
+
converter = Converter.new repo_update: opts.repo_update
|
26
|
+
converter.convert_to_react_pod!
|
27
|
+
rescue ConversionError => e
|
28
|
+
log "Conversion failed: #{e.message}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
run!
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,266 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'json'
|
3
|
+
require 'tty/platform'
|
4
|
+
require 'xcodeproj'
|
5
|
+
require_relative 'util'
|
6
|
+
|
7
|
+
module ReactNativeUtil
|
8
|
+
# Class to perform conversion operations.
|
9
|
+
class Converter
|
10
|
+
include Util
|
11
|
+
|
12
|
+
# [Array<String>] Default contents of Libraries group
|
13
|
+
DEFAULT_DEPENDENCIES = %w[
|
14
|
+
RCTAnimation
|
15
|
+
React
|
16
|
+
RCTActionSheet
|
17
|
+
RCTBlob
|
18
|
+
RCTGeolocation
|
19
|
+
RCTImage
|
20
|
+
RCTLinking
|
21
|
+
RCTNetwork
|
22
|
+
RCTSettings
|
23
|
+
RCTText
|
24
|
+
RCTVibration
|
25
|
+
RCTWebSocket
|
26
|
+
]
|
27
|
+
|
28
|
+
# [String] Path to the Podfile template
|
29
|
+
PODFILE_TEMPLATE_PATH = File.expand_path '../assets/templates/Podfile.erb', __dir__
|
30
|
+
|
31
|
+
# [Hash] Contents of ./package.json
|
32
|
+
attr_reader :package_json
|
33
|
+
|
34
|
+
# [String] Full path to Xcode project
|
35
|
+
attr_reader :xcodeproj_path
|
36
|
+
|
37
|
+
# [Xcodeproj::Project] Contents of the project at xcodproj_path
|
38
|
+
attr_reader :xcodeproj
|
39
|
+
|
40
|
+
attr_reader :options
|
41
|
+
|
42
|
+
def initialize(repo_update: nil)
|
43
|
+
@options = {}
|
44
|
+
if repo_update.nil?
|
45
|
+
@options[:repo_update] = boolean_env_var?(:REACT_NATIVE_CONVERT_REPO_UPDATE, default_value: true)
|
46
|
+
else
|
47
|
+
@options[:repo_update] = repo_update
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Convert project to use React pod
|
52
|
+
# @raise ConversionError on failure
|
53
|
+
def convert_to_react_pod!
|
54
|
+
raise ConversionError, "macOS required." unless mac?
|
55
|
+
|
56
|
+
# Make sure no uncommitted changes
|
57
|
+
check_repo_status!
|
58
|
+
|
59
|
+
load_package_json!
|
60
|
+
log 'package.json:'
|
61
|
+
log " app name: #{app_name.inspect}"
|
62
|
+
|
63
|
+
log 'Installing NPM dependencies with yarn'
|
64
|
+
execute 'yarn'
|
65
|
+
|
66
|
+
# 1. Detect project. TODO: Add an option to override.
|
67
|
+
@xcodeproj_path = File.expand_path "ios/#{package_json['name']}.xcodeproj"
|
68
|
+
load_xcodeproj!
|
69
|
+
log "Found Xcode project at #{xcodeproj_path}"
|
70
|
+
|
71
|
+
# 2. Detect native dependencies in Libraries group.
|
72
|
+
log 'Dependencies:'
|
73
|
+
dependencies.each { |d| log " #{d}" }
|
74
|
+
|
75
|
+
# Save for after Libraries removed.
|
76
|
+
deps_to_add = dependencies
|
77
|
+
|
78
|
+
# 3. Run react-native unlink for each one.
|
79
|
+
dependencies.each do |dep|
|
80
|
+
execute 'react-native', 'unlink', dep
|
81
|
+
end
|
82
|
+
|
83
|
+
# reload after react-native unlink
|
84
|
+
load_xcodeproj!
|
85
|
+
|
86
|
+
# 4a. TODO: Add Start Packager script
|
87
|
+
validate_app_target!
|
88
|
+
add_packager_script
|
89
|
+
|
90
|
+
# 4b. Remove Libraries group from Xcode project.
|
91
|
+
remove_libraries_group_from_project!
|
92
|
+
|
93
|
+
xcodeproj.save
|
94
|
+
|
95
|
+
# 5. Generate boilerplate Podfile.
|
96
|
+
# TODO: Determine appropriate subspecs
|
97
|
+
generate_podfile!
|
98
|
+
|
99
|
+
# 6. Run react-native link for each dependency.
|
100
|
+
deps_to_add.each do |dep|
|
101
|
+
execute 'react-native', 'link', dep
|
102
|
+
end
|
103
|
+
|
104
|
+
# 7. pod install
|
105
|
+
command = %w[pod install --silent]
|
106
|
+
command << '--repo-update' if options[:repo_update]
|
107
|
+
execute(*command, chdir: 'ios')
|
108
|
+
|
109
|
+
# 8. SCM/git (add, commit - optional)
|
110
|
+
|
111
|
+
# 9. Open workspace/build
|
112
|
+
execute 'open', File.join('ios', "#{app_name}.xcworkspace")
|
113
|
+
end
|
114
|
+
|
115
|
+
# Read the contents of ./package.json into @package_json
|
116
|
+
# @raise ConversionError on failure
|
117
|
+
def load_package_json!
|
118
|
+
@package_json = File.open('package.json') { |f| JSON.parse f.read }
|
119
|
+
rescue Errno::ENOENT
|
120
|
+
raise ConversionError, 'Failed to load package.json. File not found. Please run from the project root.'
|
121
|
+
rescue JSON::ParserError => e
|
122
|
+
raise ConversionError, "Failed to parse package.json: #{e.message}"
|
123
|
+
end
|
124
|
+
|
125
|
+
# Load the project at @xcodeproj_path into @xcodeproj
|
126
|
+
# @raise ConversionError on failure
|
127
|
+
def load_xcodeproj!
|
128
|
+
@xcodeproj = nil # in case of exception on reopen
|
129
|
+
@xcodeproj = Xcodeproj::Project.open xcodeproj_path
|
130
|
+
rescue Errno::ENOENT
|
131
|
+
raise ConversionError, "Failed to open #{xcodeproj_path}. File not found."
|
132
|
+
rescue Xcodeproj::PlainInformative => e
|
133
|
+
raise ConversionError, "Failed to load #{xcodeproj_path}: #{e.message}"
|
134
|
+
end
|
135
|
+
|
136
|
+
# A list, usually of PBXFileReferences, of children of the
|
137
|
+
# Libraries group from the xcodeproj.
|
138
|
+
# @return [Array] an array of child references
|
139
|
+
def libraries_group
|
140
|
+
xcodeproj['Libraries']
|
141
|
+
end
|
142
|
+
|
143
|
+
# Remove the Libraries group from the xcodeproj in memory.
|
144
|
+
# Resets @libraries_group to nil as well.
|
145
|
+
def remove_libraries_group_from_project!
|
146
|
+
# Remove links against these static libraries
|
147
|
+
xcodeproj.targets.reject { |t| t.name =~ /-tvOS/ }.each do |t|
|
148
|
+
remove_libraries_from_target t
|
149
|
+
end
|
150
|
+
|
151
|
+
log 'Removing Libraries group'
|
152
|
+
libraries_group.remove_from_project
|
153
|
+
end
|
154
|
+
|
155
|
+
def remove_libraries_from_target(target)
|
156
|
+
log "Removing Libraries from #{target.name}"
|
157
|
+
to_remove = target.frameworks_build_phase.files.select do |file|
|
158
|
+
path = file.file_ref.pretty_print
|
159
|
+
next false unless /^lib(.+)\.a$/.match?(path)
|
160
|
+
|
161
|
+
static_libs.include?(path)
|
162
|
+
end
|
163
|
+
|
164
|
+
to_remove.each { |f| target.frameworks_build_phase.remove_build_file f }
|
165
|
+
end
|
166
|
+
|
167
|
+
# A list of external dependencies from NPM requiring react-native link.
|
168
|
+
# @return [Array<String>] a list of NPM package names
|
169
|
+
def dependencies
|
170
|
+
return [] if libraries_group.nil?
|
171
|
+
|
172
|
+
dependency_paths.map do |path|
|
173
|
+
# Find the root above the ios/*.xcodeproj under node_modules
|
174
|
+
root = File.expand_path '../..', path
|
175
|
+
File.basename root
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# Paths to Xcode projects in the Libraries group from external deps.
|
180
|
+
# @return [Array<String>] a list of absolute paths to Xcode projects
|
181
|
+
def dependency_paths
|
182
|
+
return [] if libraries_group.nil?
|
183
|
+
|
184
|
+
paths = libraries_group.children.reject { |c| DEFAULT_DEPENDENCIES.include?(c.name.sub(/\.xcodeproj$/, '')) }.map(&:path)
|
185
|
+
paths.map { |p| File.expand_path p, File.join(Dir.pwd, 'ios') }
|
186
|
+
end
|
187
|
+
|
188
|
+
# All static libraries from the Libraries group
|
189
|
+
# @return [Array<String>] an array of filenames
|
190
|
+
def static_libs
|
191
|
+
libraries_group.children.map do |library|
|
192
|
+
root = File.basename(library.path).sub(/\.xcodeproj$/, '')
|
193
|
+
"lib#{root}.a"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# The name of the app as specified in package.json
|
198
|
+
# @return [String] the app name
|
199
|
+
def app_name
|
200
|
+
@app_name ||= package_json['name']
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_target
|
204
|
+
xcodeproj.targets.select(&:test_target_type?).reject { |t| t.name =~ /tvOS/ }.first
|
205
|
+
end
|
206
|
+
|
207
|
+
# Validate an assumption about the project. TODO: Provide override option.
|
208
|
+
# @raise ConversionError if an application target is not found with the same name as the project.
|
209
|
+
def validate_app_target!
|
210
|
+
app_target = xcodeproj.targets.find { |t| t.name = app_name }
|
211
|
+
raise ConversionError, "Unable to find target #{app_name} in #{xcodeproj_path}." if app_target.nil?
|
212
|
+
raise ConversionError, "Target #{app_name} is not an application target." unless app_target.product_type == 'com.apple.product-type.application'
|
213
|
+
end
|
214
|
+
|
215
|
+
# Generate a Podfile from a template.
|
216
|
+
def generate_podfile!
|
217
|
+
podfile_contents = ERB.new(File.read(PODFILE_TEMPLATE_PATH)).result binding
|
218
|
+
File.open 'ios/Podfile', 'w' do |file|
|
219
|
+
file.write podfile_contents
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def check_repo_status!
|
224
|
+
# If the git command is not installed, there's not much we can do.
|
225
|
+
# Don't want to use verify_git here, which will insist on installing
|
226
|
+
# the command. The logic of that method could change.
|
227
|
+
return if `which git`.empty?
|
228
|
+
|
229
|
+
unless Dir.exist? ".git"
|
230
|
+
`git rev-parse --git-dir > /dev/null 2>&1`
|
231
|
+
# Not a git repo
|
232
|
+
return unless $?.success?
|
233
|
+
end
|
234
|
+
|
235
|
+
`git diff-index --quiet HEAD --`
|
236
|
+
return if $?.success?
|
237
|
+
|
238
|
+
raise ConversionError, 'Uncommitted changes in repo. Please commit or stash before continuing.'
|
239
|
+
end
|
240
|
+
|
241
|
+
def add_packager_script
|
242
|
+
script = packager_script
|
243
|
+
return unless script
|
244
|
+
|
245
|
+
target = xcodeproj.targets.find { |t| t.name == app_name }
|
246
|
+
phase = target.new_shell_script_build_phase 'Start Packager'
|
247
|
+
phase.shell_script = packager_script
|
248
|
+
|
249
|
+
# TODO: Move this build phase to the top of the list before the pod install.
|
250
|
+
end
|
251
|
+
|
252
|
+
def react_project!
|
253
|
+
return @react_project if @react_project
|
254
|
+
|
255
|
+
path = libraries_group.children.find { |c| c.path =~ /React.xcodeproj/ }.real_path
|
256
|
+
@react_project = Xcodeproj::Project.open path
|
257
|
+
end
|
258
|
+
|
259
|
+
def packager_script
|
260
|
+
react_project!.targets.first.build_phases.find { |p| p.name =~ /packager/i }.shell_script.gsub(%r{../scripts}, '../node_modules/react-native/scripts')
|
261
|
+
rescue Errno::ENOENT
|
262
|
+
log 'Could not open React.xcodeproj'
|
263
|
+
nil
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
require 'time'
|
3
|
+
require_relative 'string'
|
4
|
+
|
5
|
+
# Logging extensions to the IO class
|
6
|
+
class IO
|
7
|
+
# Logs a message with obfuscation and a timestamp.
|
8
|
+
# @see String#obfuscate!
|
9
|
+
#
|
10
|
+
# @param message [#to_s] A message to log. Will be converted to a String and obfuscated.
|
11
|
+
# @param obfuscate [true, false] Obfuscate the message to be logged
|
12
|
+
# @return nil
|
13
|
+
def log(message, obfuscate: true)
|
14
|
+
message = message.to_s.obfuscate if obfuscate
|
15
|
+
puts "#{DateTime.now} #{message}"
|
16
|
+
end
|
17
|
+
|
18
|
+
# Logs a command to be executed by a call such as Kernel#system.
|
19
|
+
# If the command parameter is an Array, it will be joined using
|
20
|
+
# Array#shelljoin from shellwords. Otherwise it will be interpolated
|
21
|
+
# in a String.
|
22
|
+
#
|
23
|
+
# @param command [Array, #to_s] A command to be logged
|
24
|
+
# @return nil
|
25
|
+
def log_command(command)
|
26
|
+
string_to_log = (command.kind_of?(Array) ? command.shelljoin : command)
|
27
|
+
log "$ #{string_to_log}".cyan.bold
|
28
|
+
flush
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class String
|
2
|
+
# Get an obfuscated copy of the string.
|
3
|
+
# @see #obfuscate!
|
4
|
+
#
|
5
|
+
# @return [String] An obfuscated copy of self
|
6
|
+
def obfuscate
|
7
|
+
string = clone
|
8
|
+
string.obfuscate!
|
9
|
+
string
|
10
|
+
end
|
11
|
+
|
12
|
+
# Obfuscates the receiver by first replacing all instances
|
13
|
+
# of the HOME environment variable with '~' and then all instances of
|
14
|
+
# USER with '$USER'.
|
15
|
+
# @see #obfuscate
|
16
|
+
#
|
17
|
+
# @return nil
|
18
|
+
def obfuscate!
|
19
|
+
gsub!(/#{Regexp.quote ENV['HOME']}/, '~')
|
20
|
+
gsub!(/#{Regexp.quote ENV['USER']}/, '$USER')
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
# Determine whether the path represented by the receiver is
|
25
|
+
# an MP4 video, whether or not it exists.
|
26
|
+
#
|
27
|
+
# @return true If the file extension is .mp4, false Otherwise
|
28
|
+
def is_mp4?
|
29
|
+
video_type == :mp4
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the video type for the path represented by the
|
33
|
+
# receiver, whether or not the file exists. This is just
|
34
|
+
# the file extension as a lowercase symbol, e.g. :mp4, :mov,
|
35
|
+
# :avi, etc.
|
36
|
+
#
|
37
|
+
# @return [Symbol] The file extension as a lowercase symbol
|
38
|
+
def video_type
|
39
|
+
# Just file extension as a symbol
|
40
|
+
File.extname(self).sub(/^\./, '').downcase.to_sym
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ReactNativeUtil
|
2
|
+
# Base class for exceptions from this gem
|
3
|
+
class ReactNativeUtilException < RuntimeError
|
4
|
+
end
|
5
|
+
|
6
|
+
# Exception raised when command execution fails
|
7
|
+
class ExecutionError < ReactNativeUtilException
|
8
|
+
end
|
9
|
+
|
10
|
+
# Generic conversion error
|
11
|
+
class ConversionError < ReactNativeUtilException
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# Conversion tools for React Native projects
|
2
|
+
module ReactNativeUtil
|
3
|
+
NAME = 'react_native_util'
|
4
|
+
VERSION = '0.1.0'
|
5
|
+
SUMMARY = 'Community utility CLI for React Native projects'
|
6
|
+
DESCRIPTION = 'Automatically modifies a project created with react-native ' \
|
7
|
+
'init to use the React pod from node_modules.'
|
8
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'colored'
|
2
|
+
require_relative 'core_ext/io'
|
3
|
+
require_relative 'exceptions'
|
4
|
+
|
5
|
+
module ReactNativeUtil
|
6
|
+
# Module with utility methods
|
7
|
+
module Util
|
8
|
+
# [TTY::Platform] Object with platform information
|
9
|
+
attr_reader :platform
|
10
|
+
|
11
|
+
# Execute the specified command. If output is non-nil, generate a log
|
12
|
+
# at that location. Main log (open) is log.
|
13
|
+
#
|
14
|
+
# @param command Variadic command to be executed
|
15
|
+
# @param chdir [String, nil] Directory in which to execute the command
|
16
|
+
# @param output [String, Symbol, IO] Output for command (path, IO or a symbol such as :close)
|
17
|
+
# @param log [IO, nil] Open IO for main log (nil to suppress logging command to main log)
|
18
|
+
# @return nil
|
19
|
+
# @raise ExecutionError If the command fails
|
20
|
+
def execute(*command, chdir: nil, output: STDOUT, log: STDOUT)
|
21
|
+
log.log_command command unless log.nil?
|
22
|
+
|
23
|
+
options = chdir.nil? ? {} : { chdir: chdir }
|
24
|
+
system(*command, options.merge(%i[err out] => output))
|
25
|
+
|
26
|
+
raise ExecutionError unless $?.success?
|
27
|
+
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
# Return a Boolean value associated with an environment variable.
|
32
|
+
#
|
33
|
+
# @param var [#to_s] The name of an environment variable
|
34
|
+
# @param default_value [true, false] Returned if the environment variable is not set
|
35
|
+
# @return true if the value of the environment variable begins with y or t (case-insensitive)
|
36
|
+
def boolean_env_var?(var, default_value: false)
|
37
|
+
value = ENV[var.to_s]
|
38
|
+
return default_value if value.nil?
|
39
|
+
|
40
|
+
/^(y|t)/i.match? value
|
41
|
+
end
|
42
|
+
|
43
|
+
# Return a Float value associated with an environment variable.
|
44
|
+
#
|
45
|
+
# @param var [#to_s] The name of an environment variable
|
46
|
+
# @param default_value [#to_f] Returned if the environment variable is not set
|
47
|
+
# @return [Float] the numeric value of the environment variable or the default_value
|
48
|
+
def float_env_var(var, default_value: 0)
|
49
|
+
value = ENV[var.to_s]
|
50
|
+
return default_value.to_f if value.nil?
|
51
|
+
|
52
|
+
value.to_f
|
53
|
+
end
|
54
|
+
|
55
|
+
# Convenience method to determine if running on a Mac.
|
56
|
+
# @return true if running on a Mac
|
57
|
+
# @return false otherwise
|
58
|
+
def mac?
|
59
|
+
@platform ||= TTY::Platform.new
|
60
|
+
@platform.mac?
|
61
|
+
end
|
62
|
+
|
63
|
+
# Wrapper for STDOUT.log
|
64
|
+
# @param message [#to_s] message to log
|
65
|
+
def log(message)
|
66
|
+
STDOUT.log message
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
metadata
ADDED
@@ -0,0 +1,241 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: react_native_util
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jimmy Dee
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-05-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: cocoapods
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: colored
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: commander
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '4.4'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4.4'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: tty-platform
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.2'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.12'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.12'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '12.3'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '12.3'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3.8'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.8'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rspec-simplecov
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.2'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.2'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rspec_junit_formatter
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.4'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.4'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rubocop
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - '='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 0.65.0
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - '='
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 0.65.0
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: simplecov
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0.16'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0.16'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: yard
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0.9'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0.9'
|
195
|
+
description: Automatically modifies a project created with react-native init to use
|
196
|
+
the React pod from node_modules.
|
197
|
+
email:
|
198
|
+
- jgvdthree@gmail.com
|
199
|
+
executables:
|
200
|
+
- react_native_util
|
201
|
+
- rn
|
202
|
+
extensions: []
|
203
|
+
extra_rdoc_files: []
|
204
|
+
files:
|
205
|
+
- LICENSE
|
206
|
+
- README.md
|
207
|
+
- bin/react_native_util
|
208
|
+
- bin/rn
|
209
|
+
- lib/assets/templates/Podfile.erb
|
210
|
+
- lib/react_native_util.rb
|
211
|
+
- lib/react_native_util/cli.rb
|
212
|
+
- lib/react_native_util/converter.rb
|
213
|
+
- lib/react_native_util/core_ext/io.rb
|
214
|
+
- lib/react_native_util/core_ext/string.rb
|
215
|
+
- lib/react_native_util/exceptions.rb
|
216
|
+
- lib/react_native_util/metadata.rb
|
217
|
+
- lib/react_native_util/util.rb
|
218
|
+
homepage: https://github.com/jdee/react_native_util
|
219
|
+
licenses:
|
220
|
+
- MIT
|
221
|
+
metadata: {}
|
222
|
+
post_install_message:
|
223
|
+
rdoc_options: []
|
224
|
+
require_paths:
|
225
|
+
- lib
|
226
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
227
|
+
requirements:
|
228
|
+
- - ">="
|
229
|
+
- !ruby/object:Gem::Version
|
230
|
+
version: 2.3.0
|
231
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
232
|
+
requirements:
|
233
|
+
- - ">="
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
version: '0'
|
236
|
+
requirements: []
|
237
|
+
rubygems_version: 3.0.3
|
238
|
+
signing_key:
|
239
|
+
specification_version: 4
|
240
|
+
summary: Community utility CLI for React Native projects
|
241
|
+
test_files: []
|