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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4a59f8d672ea8d70c83d6bd2e23f1b56c1ace20f
4
- data.tar.gz: 7a1367bb08e6e2bc1b9a496df9b79e9fd23cb0ef
3
+ metadata.gz: 6369e446a2ef359946dccb3b93132c75c6ed72c0
4
+ data.tar.gz: 53affe0e6938179ea185381d139cb18b0c8105d4
5
5
  SHA512:
6
- metadata.gz: f3e1dad4aa4a7e8481275f6c3032ffd71c1f7ab67ff3d8aea9601b09f78b13cc6727c74fbe85aa9301995a622cc8f9f1ba5de0773e7a89fe12214a288380d0b2
7
- data.tar.gz: 597fc8f8ed4f486e97ac60858d145b16bc6c14de69698502cdfcb11d2c538da2c540c6b39f16c3610f7541251318a2b0fbf003ef64c49724437ef2a7d76283e3
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
  ;;
@@ -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
@@ -1,3 +1,4 @@
1
1
  require "branch_io_cli/commands/command"
2
+ require "branch_io_cli/commands/report_command"
2
3
  require "branch_io_cli/commands/setup_command"
3
4
  require "branch_io_cli/commands/validate_command"
@@ -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 @podfile.nil?
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(options, filename)
427
+ def validate_buildfile_path(buildfile_path, filename)
285
428
  # Disable Podfile/Cartfile update if --no-add-sdk is present
286
- return unless options.add_sdk && @sdk_integration_mode.nil?
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 @xcodeproj_path
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
@@ -1,3 +1,3 @@
1
1
  module BranchIOCLI
2
- VERSION = "0.5.3"
2
+ VERSION = "0.6.0"
3
3
  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.5.3
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-27 00:00:00.000000000 Z
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