branch_io_cli 0.5.3 → 0.6.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 +31 -2
- data/lib/assets/completions/completion.bash +6 -1
- data/lib/branch_io_cli/cli.rb +27 -0
- data/lib/branch_io_cli/commands.rb +1 -0
- data/lib/branch_io_cli/commands/report_command.rb +70 -0
- data/lib/branch_io_cli/helper/configuration_helper.rb +150 -8
- data/lib/branch_io_cli/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6369e446a2ef359946dccb3b93132c75c6ed72c0
|
4
|
+
data.tar.gz: 53affe0e6938179ea185381d139cb18b0c8105d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 99149f86b892a1aaed05a04e221455409c40cf6fd7f97d2fddac0dbfef368cf6ea4d159bd10511bb03e49bf0ba50e00a5df6ef35170ed9f9de86f0fb135b66b2
|
7
|
+
data.tar.gz: 0c3cd173bc20634d51c9469b3b286dab4e49582e1c16588648850c354683cc3c380717cbd1684c760ebc9d58f5b68a595773b25e5069d5f9813a32b54ce4ece6
|
data/README.md
CHANGED
@@ -61,7 +61,7 @@ Currently command-line completion for bash is much more extensive than for zsh.
|
|
61
61
|
### Setup command
|
62
62
|
|
63
63
|
```bash
|
64
|
-
branch_io setup
|
64
|
+
branch_io setup [OPTIONS]
|
65
65
|
```
|
66
66
|
|
67
67
|
Integrates the Branch SDK into a native app project. This currently supports iOS only.
|
@@ -165,7 +165,7 @@ branch_io setup --no-pod-repo-update
|
|
165
165
|
### Validate command
|
166
166
|
|
167
167
|
```bash
|
168
|
-
branch_io validate
|
168
|
+
branch_io validate [OPTIONS]
|
169
169
|
```
|
170
170
|
|
171
171
|
This command validates all Universal Link domains configured in a project without making any modification.
|
@@ -199,6 +199,35 @@ and no Universal Link domain is present that does not pass validation.
|
|
199
199
|
|
200
200
|
If validation passes, this command returns 0. If validation fails, it returns 1.
|
201
201
|
|
202
|
+
### Report command
|
203
|
+
|
204
|
+
```bash
|
205
|
+
branch_io report [OPTIONS]
|
206
|
+
```
|
207
|
+
|
208
|
+
_Work in progress_
|
209
|
+
|
210
|
+
This command optionally cleans and then builds a workspace or project, generating a verbose
|
211
|
+
report with additional diagnostic information suitable for opening a support ticket.
|
212
|
+
|
213
|
+
#### Options
|
214
|
+
|
215
|
+
|Option|Description|
|
216
|
+
|------|-----------|
|
217
|
+
|-h, --help|Prints a list of commands or help for each command|
|
218
|
+
|-v, --version|Prints the current version of the CLI|
|
219
|
+
|-t, --trace|Prints a stack trace when exceptions are raised|
|
220
|
+
|--workspace MyProject.xcworkspace|Path to an Xcode workspace|
|
221
|
+
|--xcodeproj MyProject.xcodeproj|Path to an Xcode project|
|
222
|
+
|--target MyAppTarget|Name of a target to modify in the Xcode project|
|
223
|
+
|--scheme MyAppScheme|Name of a scheme to build|
|
224
|
+
|--configuration Debug/Release/CustomConfig|Name of a build configuration|
|
225
|
+
|--[no-]clean|Clean before building (default: yes)|
|
226
|
+
|--[no-]header-only|Show a diagnostic header and exit without cleaning or building (default: no)|
|
227
|
+
|--podfile /path/to/Podfile|Path to the Podfile for the project|
|
228
|
+
|--cartfile /path/to/Cartfile|Path to the Cartfile for the project|
|
229
|
+
|--out ./report.txt|Path to use for the generated report (default: ./report.txt)|
|
230
|
+
|
202
231
|
## Examples
|
203
232
|
|
204
233
|
See the [examples](./examples) folder for several example projects that can be
|
@@ -8,7 +8,7 @@ _branch_io_complete()
|
|
8
8
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
9
9
|
cmd="${COMP_WORDS[1]}"
|
10
10
|
|
11
|
-
commands="setup validate"
|
11
|
+
commands="report setup validate"
|
12
12
|
global_opts="-h --help -t --trace -v --version"
|
13
13
|
|
14
14
|
setup_opts="$global_opts -L --live-key -T --test-key -D --domains --app-link-subdomain -U --uri-scheme"
|
@@ -18,8 +18,13 @@ _branch_io_complete()
|
|
18
18
|
|
19
19
|
validate_opts="$global_opts -D --domains --xcodeproj --target"
|
20
20
|
|
21
|
+
report_opts="$global_opts --xcodeproj --workspace --header-only --no-clean --scheme --target --configuration --out"
|
22
|
+
|
21
23
|
if [[ ${cur} == -* ]] ; then
|
22
24
|
case "${cmd}" in
|
25
|
+
report)
|
26
|
+
opts=$report_opts
|
27
|
+
;;
|
23
28
|
setup)
|
24
29
|
opts=$setup_opts
|
25
30
|
;;
|
data/lib/branch_io_cli/cli.rb
CHANGED
@@ -145,6 +145,33 @@ EOF
|
|
145
145
|
end
|
146
146
|
end
|
147
147
|
|
148
|
+
command :report do |c|
|
149
|
+
c.syntax = "branch_io report [OPTIONS]"
|
150
|
+
c.summary = "Generate and optionally submit a build diagnostic report."
|
151
|
+
c.description = <<EOF
|
152
|
+
<%= color('Work in progress', BOLD) %>
|
153
|
+
|
154
|
+
This command optionally cleans and then builds a workspace or project, generating a verbose
|
155
|
+
report with additional diagnostic information suitable for opening a support ticket.
|
156
|
+
EOF
|
157
|
+
|
158
|
+
c.option "--xcodeproj MyProject.xcodeproj", String, "Path to an Xcode project"
|
159
|
+
c.option "--workspace MyProject.xcworkspace", String, "Path to an Xcode workspace"
|
160
|
+
c.option "--scheme MyProjectScheme", String, "A scheme from the project or workspace to build"
|
161
|
+
c.option "--target MyProjectTarget", String, "A target to build"
|
162
|
+
c.option "--configuration Debug|Release|CustomConfigName", String, "The build configuration to use (default: Release)"
|
163
|
+
c.option "--podfile /path/to/Podfile", String, "Path to the Podfile for the project"
|
164
|
+
c.option "--cartfile /path/to/Cartfile", String, "Path to the Cartfile for the project"
|
165
|
+
c.option "--[no-]clean", "Clean before attempting to build (default: yes)"
|
166
|
+
c.option "--[no-]header-only", "Write a report header to standard output and exit"
|
167
|
+
c.option "--out branch-report.txt", String, "Report output path (default: ./branch-report.txt)"
|
168
|
+
|
169
|
+
c.action do |args, options|
|
170
|
+
options.default clean: true, header_only: false
|
171
|
+
Commands::ReportCommand.new(options).run!
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
148
175
|
run!
|
149
176
|
end
|
150
177
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module BranchIOCLI
|
2
|
+
module Commands
|
3
|
+
class ReportCommand < Command
|
4
|
+
def initialize(options)
|
5
|
+
super
|
6
|
+
config_helper.validate_report_options options
|
7
|
+
end
|
8
|
+
|
9
|
+
def run!
|
10
|
+
say "\n"
|
11
|
+
|
12
|
+
if config_helper.header_only
|
13
|
+
say report_header
|
14
|
+
exit 0
|
15
|
+
end
|
16
|
+
|
17
|
+
File.open config_helper.report_path, "w" do |report|
|
18
|
+
report.write "Branch.io Xcode build report v #{VERSION}\n\n"
|
19
|
+
# TODO: Write out command-line options or configuration from helper
|
20
|
+
report.write "#{report_header}\n"
|
21
|
+
|
22
|
+
if config_helper.clean
|
23
|
+
say "Cleaning"
|
24
|
+
clean_cmd = "#{base_xcodebuild_cmd} clean"
|
25
|
+
report.write "$ #{clean_cmd}\n\n"
|
26
|
+
report.write `#{clean_cmd}`
|
27
|
+
end
|
28
|
+
|
29
|
+
say "Building"
|
30
|
+
build_cmd = "#{base_xcodebuild_cmd} -verbose"
|
31
|
+
report.write "$ #{build_cmd}\n\n"
|
32
|
+
report.write `#{build_cmd}`
|
33
|
+
|
34
|
+
say "Done ✅"
|
35
|
+
end
|
36
|
+
say "Report generated in #{config_helper.report_path}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def base_xcodebuild_cmd
|
40
|
+
cmd = "xcodebuild"
|
41
|
+
cmd = "#{cmd} -scheme #{config_helper.scheme}" if config_helper.scheme
|
42
|
+
cmd = "#{cmd} -workspace #{config_helper.workspace_path}" if config_helper.workspace_path
|
43
|
+
cmd = "#{cmd} -project #{config_helper.xcodeproj_path}" if config_helper.xcodeproj_path
|
44
|
+
cmd = "#{cmd} -target #{config_helper.target}" if config_helper.target
|
45
|
+
cmd = "#{cmd} -configuration #{config_helper.configuration}" if config_helper.configuration
|
46
|
+
cmd
|
47
|
+
end
|
48
|
+
|
49
|
+
def branch_version
|
50
|
+
if config_helper.podfile_path && File.exist?("#{config_helper.podfile_path}.lock")
|
51
|
+
podfile_lock = File.read "#{config_helper.podfile_path}.lock"
|
52
|
+
matches = %r{Branch/Core \(= (\d+\.\d+\.\d+)\)}m.match podfile_lock
|
53
|
+
return matches[1] if matches
|
54
|
+
elsif config_helper.cartfile_path && File.exist?("#{config_helper.cartfile_path}.resolved")
|
55
|
+
cartfile_resolved = File.read "#{config_helper.cartfile_path}.resolved"
|
56
|
+
matches = /ios-branch-deep-linking" "(\d+\.\d+\.\d+)"/m.match cartfile_resolved
|
57
|
+
return matches[1] if matches
|
58
|
+
end
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
|
62
|
+
def report_header
|
63
|
+
header = `xcodebuild -version`
|
64
|
+
version = branch_version
|
65
|
+
header = "#{header}\nBranch SDK v. #{version}" if version
|
66
|
+
"#{header}\n"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -6,6 +6,7 @@ module BranchIOCLI
|
|
6
6
|
# Processes CLI options.
|
7
7
|
# Validates options.
|
8
8
|
# Prompts for input in a number of cases.
|
9
|
+
# rubocop: disable Metrics/ClassLength
|
9
10
|
class ConfigurationHelper
|
10
11
|
APP_LINK_REGEXP = /\.app\.link$|\.test-app\.link$/
|
11
12
|
SDK_OPTIONS =
|
@@ -19,6 +20,8 @@ module BranchIOCLI
|
|
19
20
|
class << self
|
20
21
|
attr_reader :xcodeproj_path
|
21
22
|
attr_reader :xcodeproj
|
23
|
+
attr_reader :workspace_path
|
24
|
+
attr_reader :workspace
|
22
25
|
attr_reader :keys
|
23
26
|
attr_reader :all_domains
|
24
27
|
attr_reader :podfile_path
|
@@ -32,6 +35,11 @@ module BranchIOCLI
|
|
32
35
|
attr_reader :patch_source
|
33
36
|
attr_reader :commit
|
34
37
|
attr_reader :sdk_integration_mode
|
38
|
+
attr_reader :clean
|
39
|
+
attr_reader :header_only
|
40
|
+
attr_reader :scheme
|
41
|
+
attr_reader :configuration
|
42
|
+
attr_reader :report_path
|
35
43
|
|
36
44
|
def validate_setup_options(options)
|
37
45
|
print_identification "setup"
|
@@ -60,10 +68,10 @@ module BranchIOCLI
|
|
60
68
|
|
61
69
|
# If --cartfile is present, don't look for a Podfile. Just validate that
|
62
70
|
# Cartfile.
|
63
|
-
validate_buildfile_path options, "Podfile" if options.cartfile.nil?
|
71
|
+
validate_buildfile_path options.podfile, "Podfile" if options.cartfile.nil? && options.add_sdk
|
64
72
|
|
65
73
|
# If --podfile is present or a Podfile was found, don't look for a Cartfile.
|
66
|
-
validate_buildfile_path options, "Cartfile" if @
|
74
|
+
validate_buildfile_path options.cartfile, "Cartfile" if @sdk_integration_mode.nil? && options.add_sdk
|
67
75
|
|
68
76
|
validate_sdk_addition options
|
69
77
|
|
@@ -79,6 +87,32 @@ module BranchIOCLI
|
|
79
87
|
print_validation_configuration
|
80
88
|
end
|
81
89
|
|
90
|
+
def validate_report_options(options)
|
91
|
+
print_identification "report"
|
92
|
+
|
93
|
+
@clean = options.clean
|
94
|
+
@header_only = options.header_only
|
95
|
+
@scheme = options.scheme
|
96
|
+
@target = options.target
|
97
|
+
@configuration = options.configuration
|
98
|
+
@report_path = options.out || "./report.txt"
|
99
|
+
|
100
|
+
validate_xcodeproj_and_workspace options
|
101
|
+
validate_scheme options
|
102
|
+
|
103
|
+
# If neither --podfile nor --cartfile is present, arbitrarily look for a Podfile
|
104
|
+
# first.
|
105
|
+
|
106
|
+
# If --cartfile is present, don't look for a Podfile. Just validate that
|
107
|
+
# Cartfile.
|
108
|
+
validate_buildfile_path(options.podfile, "Podfile") if options.cartfile.nil?
|
109
|
+
|
110
|
+
# If --podfile is present or a Podfile was found, don't look for a Cartfile.
|
111
|
+
validate_buildfile_path(options.cartfile, "Cartfile") if @sdk_integration_mode.nil?
|
112
|
+
|
113
|
+
print_report_configuration
|
114
|
+
end
|
115
|
+
|
82
116
|
def print_identification(command)
|
83
117
|
say <<EOF
|
84
118
|
|
@@ -120,6 +154,22 @@ EOF
|
|
120
154
|
EOF
|
121
155
|
end
|
122
156
|
|
157
|
+
def print_report_configuration
|
158
|
+
say <<EOF
|
159
|
+
<%= color('Configuration:', BOLD) %>
|
160
|
+
|
161
|
+
<%= color('Xcode workspace:', BOLD) %> #{@workspace_path || '(none)'}
|
162
|
+
<%= color('Xcode project:', BOLD) %> #{@xcodeproj_path || '(none)'}
|
163
|
+
<%= color('Scheme:', BOLD) %> #{@scheme || '(none)'}
|
164
|
+
<%= color('Target:', BOLD) %> #{@target || '(none)'}
|
165
|
+
<%= color('Configuration:', BOLD) %> #{@configuration || '(none)'}
|
166
|
+
<%= color('Podfile:', BOLD) %> #{@podfile_path || '(none)'}
|
167
|
+
<%= color('Cartfile:', BOLD) %> #{@cartfile_path || '(none)'}
|
168
|
+
<%= color('Clean:', BOLD) %> #{@clean.inspect}
|
169
|
+
<%= color('Report path:', BOLD) %> #{@report_path}
|
170
|
+
EOF
|
171
|
+
end
|
172
|
+
|
123
173
|
def validate_keys_from_setup_options(options)
|
124
174
|
live_key = options.live_key
|
125
175
|
test_key = options.test_key
|
@@ -200,6 +250,99 @@ EOF
|
|
200
250
|
end
|
201
251
|
end
|
202
252
|
|
253
|
+
# rubocop: disable Metrics/PerceivedComplexity
|
254
|
+
def validate_xcodeproj_and_workspace(options)
|
255
|
+
# 1. What was passed in?
|
256
|
+
begin
|
257
|
+
if options.workspace
|
258
|
+
path = options.workspace
|
259
|
+
@workspace = Xcodeproj::Workspace.new_from_xcworkspace options.workspace
|
260
|
+
@workspace_path = options.workspace
|
261
|
+
end
|
262
|
+
if options.xcodeproj
|
263
|
+
path = options.xcodeproj
|
264
|
+
@xcodeproj = Xcodeproj::Project.open options.xcodeproj
|
265
|
+
@xcodeproj_path = options.xcodeproj
|
266
|
+
end
|
267
|
+
return if @workspace || @xcodeproj
|
268
|
+
rescue StandardError => e
|
269
|
+
say e.message
|
270
|
+
end
|
271
|
+
|
272
|
+
# Try to find first a workspace, then a project
|
273
|
+
all_workspace_paths = Dir[File.expand_path(File.join(".", "**/*.xcworkspace"))]
|
274
|
+
.reject { |w| w =~ %r{/project.pbxproj$} }
|
275
|
+
.select do |p|
|
276
|
+
valid = true
|
277
|
+
Pathname.new(p).each_filename do |f|
|
278
|
+
valid = false && break if f == "Carthage" || f == "Pods"
|
279
|
+
end
|
280
|
+
valid
|
281
|
+
end
|
282
|
+
|
283
|
+
if all_workspace_paths.count == 1
|
284
|
+
path = all_workspace_paths.first
|
285
|
+
elsif all_workspace_paths.count == 0
|
286
|
+
all_xcodeproj_paths = Dir[File.expand_path(File.join(".", "**/*.xcodeproj"))]
|
287
|
+
xcodeproj_paths = all_xcodeproj_paths.select do |p|
|
288
|
+
valid = true
|
289
|
+
Pathname.new(p).each_filename do |f|
|
290
|
+
valid = false && break if f == "Carthage" || f == "Pods"
|
291
|
+
end
|
292
|
+
valid
|
293
|
+
end
|
294
|
+
|
295
|
+
path = xcodeproj_paths.first if xcodeproj_paths.count == 1
|
296
|
+
end
|
297
|
+
# If more than one workspace. Don't try to find a project. Just prompt.
|
298
|
+
|
299
|
+
loop do
|
300
|
+
path = ask "Please enter a path to your Xcode project or workspace: " if path.nil?
|
301
|
+
begin
|
302
|
+
if path =~ /\.xcworkspace$/
|
303
|
+
@workspace = Xcodeproj::Workspace.new_from_xcworkspace path
|
304
|
+
@workspace_path = path
|
305
|
+
return
|
306
|
+
elsif path =~ /\.xcodeproj$/
|
307
|
+
@xcodeproj = Xcodeproj::Project.open path
|
308
|
+
@xcodeproj_path = path
|
309
|
+
return
|
310
|
+
else
|
311
|
+
say "Path must end with .xcworkspace or .xcodeproj"
|
312
|
+
end
|
313
|
+
rescue StandardError => e
|
314
|
+
say e.message
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
# rubocop: enable Metrics/PerceivedComplexity
|
319
|
+
|
320
|
+
def validate_scheme(options)
|
321
|
+
schemes = all_schemes
|
322
|
+
if options.scheme && schemes.include?(options.scheme)
|
323
|
+
@scheme = options.scheme
|
324
|
+
elsif schemes.count == 1
|
325
|
+
@scheme = schemes.first
|
326
|
+
elsif !schemes.empty?
|
327
|
+
say "Please specify one of the following for the --scheme argument:"
|
328
|
+
schemes.each do |scheme|
|
329
|
+
say " #{scheme}"
|
330
|
+
end
|
331
|
+
exit 1
|
332
|
+
else
|
333
|
+
say "No scheme defined in project."
|
334
|
+
exit(-1)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def all_schemes
|
339
|
+
if @workspace_path
|
340
|
+
@workspace.schemes.keys.reject { |scheme| scheme == "Pods" }
|
341
|
+
else
|
342
|
+
Xcodeproj::Project.schemes @xcodeproj_path
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
203
346
|
def validate_target(options, allow_extensions = true)
|
204
347
|
non_test_targets = @xcodeproj.targets.reject(&:test_target_type?)
|
205
348
|
raise "No non-test target found in project" if non_test_targets.empty?
|
@@ -281,11 +424,9 @@ EOF
|
|
281
424
|
scheme.sub %r{://$}, ""
|
282
425
|
end
|
283
426
|
|
284
|
-
def validate_buildfile_path(
|
427
|
+
def validate_buildfile_path(buildfile_path, filename)
|
285
428
|
# Disable Podfile/Cartfile update if --no-add-sdk is present
|
286
|
-
return unless
|
287
|
-
|
288
|
-
buildfile_path = options.send filename.downcase
|
429
|
+
return unless @sdk_integration_mode.nil?
|
289
430
|
|
290
431
|
# Was --podfile/--cartfile used?
|
291
432
|
if buildfile_path
|
@@ -312,8 +453,8 @@ EOF
|
|
312
453
|
end
|
313
454
|
end
|
314
455
|
|
315
|
-
# No: Check for Podfile/Cartfile next to
|
316
|
-
buildfile_path = File.expand_path "../#{filename}", @xcodeproj_path
|
456
|
+
# No: Check for Podfile/Cartfile next to workspace or project
|
457
|
+
buildfile_path = File.expand_path "../#{filename}", (@workspace_path || @xcodeproj_path)
|
317
458
|
return unless File.exist? buildfile_path
|
318
459
|
|
319
460
|
# Exists: Use it (valid if found)
|
@@ -354,5 +495,6 @@ EOF
|
|
354
495
|
end
|
355
496
|
end
|
356
497
|
end
|
498
|
+
# rubocop: enable Metrics/ClassLength
|
357
499
|
end
|
358
500
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: branch_io_cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Branch
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-10-
|
12
|
+
date: 2017-10-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: commander
|
@@ -226,6 +226,7 @@ files:
|
|
226
226
|
- lib/branch_io_cli/cli.rb
|
227
227
|
- lib/branch_io_cli/commands.rb
|
228
228
|
- lib/branch_io_cli/commands/command.rb
|
229
|
+
- lib/branch_io_cli/commands/report_command.rb
|
229
230
|
- lib/branch_io_cli/commands/setup_command.rb
|
230
231
|
- lib/branch_io_cli/commands/validate_command.rb
|
231
232
|
- lib/branch_io_cli/helper.rb
|