branch_io_cli 0.13.0.pre.1 → 0.13.0.pre.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +112 -7
- data/lib/assets/completions/completion.bash +6 -1
- data/lib/assets/completions/completion.zsh +1 -1
- data/lib/assets/templates/completion.bash.erb +4 -1
- data/lib/assets/templates/completion.zsh.erb +1 -1
- data/lib/assets/templates/env_description.erb +1 -0
- data/lib/branch_io_cli.rb +9 -9
- data/lib/branch_io_cli/branch_app.rb +18 -5
- data/lib/branch_io_cli/cli.rb +1 -1
- data/lib/branch_io_cli/command.rb +5 -4
- data/lib/branch_io_cli/command/command.rb +4 -0
- data/lib/branch_io_cli/command/env_command.rb +22 -0
- data/lib/branch_io_cli/command/report_command.rb +9 -0
- data/lib/branch_io_cli/command/setup_command.rb +2 -2
- data/lib/branch_io_cli/configuration.rb +13 -10
- data/lib/branch_io_cli/configuration/configuration.rb +11 -5
- data/lib/branch_io_cli/configuration/env_configuration.rb +47 -0
- data/lib/branch_io_cli/configuration/env_options.rb +30 -0
- data/lib/branch_io_cli/configuration/environment.rb +107 -0
- data/lib/branch_io_cli/configuration/report_configuration.rb +8 -0
- data/lib/branch_io_cli/configuration/validate_configuration.rb +9 -0
- data/lib/branch_io_cli/core_ext.rb +4 -3
- data/lib/branch_io_cli/core_ext/tty_platform.rb +13 -0
- data/lib/branch_io_cli/core_ext/xcodeproj.rb +4 -4
- data/lib/branch_io_cli/format.rb +3 -3
- data/lib/branch_io_cli/helper.rb +6 -6
- data/lib/branch_io_cli/helper/branch_helper.rb +24 -10
- data/lib/branch_io_cli/helper/ios_helper.rb +15 -17
- data/lib/branch_io_cli/helper/report_helper.rb +5 -1
- data/lib/branch_io_cli/helper/tool_helper.rb +70 -31
- data/lib/branch_io_cli/rake_task.rb +2 -4
- data/lib/branch_io_cli/version.rb +1 -1
- metadata +112 -58
@@ -0,0 +1,47 @@
|
|
1
|
+
module BranchIOCLI
|
2
|
+
module Configuration
|
3
|
+
class EnvConfiguration < Configuration
|
4
|
+
class << self
|
5
|
+
def summary
|
6
|
+
"Output information about CLI environment."
|
7
|
+
end
|
8
|
+
|
9
|
+
def examples
|
10
|
+
{
|
11
|
+
"Show CLI environment" => "br env",
|
12
|
+
"Get completion script for zsh" => "br env -cs zsh"
|
13
|
+
}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(options)
|
18
|
+
@quiet = !options.verbose
|
19
|
+
@ruby_version = options.ruby_version
|
20
|
+
@rubygems_version = options.rubygems_version
|
21
|
+
@lib_path = options.lib_path
|
22
|
+
@assets_path = options.assets_path
|
23
|
+
@completion_script = options.completion_script
|
24
|
+
@shell = options.shell
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def log
|
29
|
+
super
|
30
|
+
return if quiet
|
31
|
+
|
32
|
+
say <<EOF
|
33
|
+
<%= color('Show completion script:', BOLD) %> #{completion_script}
|
34
|
+
<%= color('Shell for completion script:', BOLD) %> #{shell}
|
35
|
+
EOF
|
36
|
+
end
|
37
|
+
|
38
|
+
def show_all?
|
39
|
+
!show_completion_script?
|
40
|
+
end
|
41
|
+
|
42
|
+
def show_completion_script?
|
43
|
+
completion_script
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module BranchIOCLI
|
2
|
+
module Configuration
|
3
|
+
class EnvOptions
|
4
|
+
def self.available_options
|
5
|
+
[
|
6
|
+
Option.new(
|
7
|
+
name: :completion_script,
|
8
|
+
description: "Get the path to the completion script for this shell",
|
9
|
+
default_value: false,
|
10
|
+
aliases: "-c"
|
11
|
+
),
|
12
|
+
Option.new(
|
13
|
+
name: :shell,
|
14
|
+
env_name: "SHELL",
|
15
|
+
description: "Specify shell for completion script",
|
16
|
+
type: String,
|
17
|
+
example: "zsh",
|
18
|
+
aliases: "-s"
|
19
|
+
),
|
20
|
+
Option.new(
|
21
|
+
name: :verbose,
|
22
|
+
description: "Generate verbose output",
|
23
|
+
default_value: false,
|
24
|
+
aliases: "-V"
|
25
|
+
)
|
26
|
+
]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require "active_support/core_ext/string"
|
2
|
+
require "rbconfig"
|
3
|
+
require_relative "../core_ext/tty_platform"
|
4
|
+
|
5
|
+
module BranchIOCLI
|
6
|
+
module Configuration
|
7
|
+
class Environment
|
8
|
+
PLATFORM = TTY::Platform.new
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def config
|
12
|
+
Configuration.current
|
13
|
+
end
|
14
|
+
|
15
|
+
def os_version
|
16
|
+
PLATFORM.version
|
17
|
+
end
|
18
|
+
|
19
|
+
def os_name
|
20
|
+
PLATFORM.os.to_s.capitalize
|
21
|
+
end
|
22
|
+
|
23
|
+
def os_arch
|
24
|
+
PLATFORM.architecture
|
25
|
+
end
|
26
|
+
|
27
|
+
def operating_system
|
28
|
+
if PLATFORM.br_high_sierra?
|
29
|
+
os = "macOS High Sierra"
|
30
|
+
elsif PLATFORM.br_sierra?
|
31
|
+
os = "macOS Sierra"
|
32
|
+
else
|
33
|
+
os = os_name if os_name
|
34
|
+
os += " #{os_version}" if os_version
|
35
|
+
end
|
36
|
+
|
37
|
+
os += " (#{os_arch})"
|
38
|
+
|
39
|
+
os
|
40
|
+
end
|
41
|
+
|
42
|
+
def ruby_path
|
43
|
+
File.join(RbConfig::CONFIG["bindir"],
|
44
|
+
RbConfig::CONFIG["RUBY_INSTALL_NAME"] +
|
45
|
+
RbConfig::CONFIG["EXEEXT"])
|
46
|
+
end
|
47
|
+
|
48
|
+
def from_homebrew?
|
49
|
+
ENV["BRANCH_IO_CLI_INSTALLED_FROM_HOMEBREW"] == "true"
|
50
|
+
end
|
51
|
+
|
52
|
+
def lib_path
|
53
|
+
File.expand_path File.join("..", "..", ".."), __FILE__
|
54
|
+
end
|
55
|
+
|
56
|
+
def assets_path
|
57
|
+
File.join lib_path, "assets"
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns the last path component. Uses the SHELL env. var. unless overriden
|
61
|
+
# at the command line (br env -cs zsh).
|
62
|
+
def shell
|
63
|
+
return ENV["SHELL"].split("/").last unless config.class.available_options.map(&:name).include?(:shell)
|
64
|
+
config.shell.split("/").last
|
65
|
+
end
|
66
|
+
|
67
|
+
def completion_script
|
68
|
+
path = File.join assets_path, "completions", "completion.#{shell}"
|
69
|
+
path if File.readable?(path)
|
70
|
+
end
|
71
|
+
|
72
|
+
def ruby_header(terminal: true, include_load_path: false)
|
73
|
+
header = header_item("Operating system", operating_system, terminal: terminal)
|
74
|
+
header += header_item("Ruby version", RUBY_VERSION, terminal: terminal)
|
75
|
+
header += header_item("Ruby path", display_path(ruby_path), terminal: terminal)
|
76
|
+
header += header_item("RubyGems version", Gem::VERSION, terminal: terminal)
|
77
|
+
header += header_item("Bundler", defined?(Bundler) ? Bundler::VERSION : "no", terminal: terminal)
|
78
|
+
header += header_item("Installed from Homebrew", from_homebrew? ? "yes" : "no", terminal: terminal)
|
79
|
+
header += header_item("GEM_HOME", obfuscate_user(Gem.dir), terminal: terminal)
|
80
|
+
header += header_item("Lib path", display_path(lib_path), terminal: terminal)
|
81
|
+
header += header_item("LOAD_PATH", $LOAD_PATH.map { |p| display_path(p) }, terminal: terminal) if include_load_path
|
82
|
+
header += header_item("Shell", ENV["SHELL"], terminal: terminal)
|
83
|
+
header += "\n"
|
84
|
+
header
|
85
|
+
end
|
86
|
+
|
87
|
+
def header_item(label, value, terminal: true)
|
88
|
+
if terminal
|
89
|
+
"<%= color('#{label}:', BOLD) %> #{value}\n"
|
90
|
+
else
|
91
|
+
"label: #{value}\n"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def obfuscate_user(path)
|
96
|
+
path.gsub(ENV['HOME'], '~').gsub(ENV['USER'], '$USER')
|
97
|
+
end
|
98
|
+
|
99
|
+
def display_path(path)
|
100
|
+
path = path.gsub(Gem.dir, '$GEM_HOME')
|
101
|
+
path = obfuscate_user(path)
|
102
|
+
path
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -8,6 +8,14 @@ module BranchIOCLI
|
|
8
8
|
def summary
|
9
9
|
"Generate and optionally submit a build diagnostic report."
|
10
10
|
end
|
11
|
+
|
12
|
+
def examples
|
13
|
+
{
|
14
|
+
"Show general project information without building" => "br report -H",
|
15
|
+
"Perform a full build and report all errors to report.txt" => "br report",
|
16
|
+
"Don't clean before building" => "br report --no-clean"
|
17
|
+
}
|
18
|
+
end
|
11
19
|
end
|
12
20
|
|
13
21
|
attr_reader :report_path
|
@@ -9,6 +9,15 @@ module BranchIOCLI
|
|
9
9
|
def return_value
|
10
10
|
"If validation passes, this command returns 0. If validation fails, it returns 1."
|
11
11
|
end
|
12
|
+
|
13
|
+
def examples
|
14
|
+
{
|
15
|
+
"Ensure project has at least one correctly configured Branch key and domain" => "br validate",
|
16
|
+
"Ensure project is correctly configured for certain Branch keys" => "br validate -L key_live_xxxx -T key_test_yyyy",
|
17
|
+
"Ensure project is correctly configured to use specific domains" => "br validate -D myapp.app.link,myapp-alternate.app.link",
|
18
|
+
"Validate only Universal Link configuration" => "br validate --universal-links-only"
|
19
|
+
}
|
20
|
+
end
|
12
21
|
end
|
13
22
|
|
14
23
|
def initialize(options)
|
@@ -1,3 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative "core_ext/io.rb"
|
2
|
+
require_relative "core_ext/regexp.rb"
|
3
|
+
require_relative "core_ext/tty_platform.rb"
|
4
|
+
require_relative "core_ext/xcodeproj.rb"
|
@@ -73,7 +73,7 @@ module Xcodeproj
|
|
73
73
|
end
|
74
74
|
|
75
75
|
# TODO: What is the correct resolution order here? Which overrides which in
|
76
|
-
# Xcode?
|
76
|
+
# Xcode? Or does it matter here?
|
77
77
|
if setting_value.nil? && defined?(BranchIOCLI::Configuration::XcodeSettings)
|
78
78
|
setting_value = BranchIOCLI::Configuration::XcodeSettings[configuration][setting_name]
|
79
79
|
end
|
@@ -120,13 +120,13 @@ module Xcodeproj
|
|
120
120
|
# Everything else becomes a hyphen, including underscores.
|
121
121
|
expanded_macro.gsub!(/[^A-Za-z0-9-]/, '-') if modifier == "rfc1034identifier"
|
122
122
|
|
123
|
-
string.gsub!(/\$\(#{original_macro}\)|\$\{#{original_macro}\}
|
123
|
+
string.gsub!(/\$\(#{original_macro}\)|\$\{#{original_macro}\}/, expanded_macro)
|
124
124
|
search_position += expanded_macro.length
|
125
125
|
end
|
126
126
|
|
127
127
|
# HACK: When matching against an xcconfig, as here, sometimes the macro is just returned
|
128
|
-
# without delimiters, e.g. TARGET_NAME or
|
129
|
-
#
|
128
|
+
# without delimiters as the entire string or as a path component, e.g. TARGET_NAME or
|
129
|
+
# PROJECT_DIR/PROJECT_NAME/BridgingHeader.h.
|
130
130
|
string = string.split("/").map do |component|
|
131
131
|
next component unless component =~ /^[A-Z0-9_]+$/
|
132
132
|
expanded_build_setting(component, configuration) || component
|
data/lib/branch_io_cli/format.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative "format/highline_format"
|
2
|
+
require_relative "format/markdown_format"
|
3
|
+
require_relative "format/shell_format"
|
4
4
|
|
5
5
|
module BranchIOCLI
|
6
6
|
module Format
|
data/lib/branch_io_cli/helper.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
require_relative "helper/branch_helper"
|
2
|
+
require_relative "helper/methods"
|
3
|
+
require_relative "helper/patch_helper"
|
4
|
+
require_relative "helper/report_helper"
|
5
|
+
require_relative "helper/tool_helper"
|
6
|
+
require_relative "helper/util"
|
@@ -1,8 +1,9 @@
|
|
1
1
|
require "active_support/core_ext/hash"
|
2
|
-
|
3
|
-
|
2
|
+
require_relative "android_helper"
|
3
|
+
require_relative "ios_helper"
|
4
4
|
require "net/http"
|
5
5
|
require "set"
|
6
|
+
require "tty/spinner"
|
6
7
|
|
7
8
|
module BranchIOCLI
|
8
9
|
module Helper
|
@@ -19,22 +20,33 @@ module BranchIOCLI
|
|
19
20
|
@changes << change.to_s
|
20
21
|
end
|
21
22
|
|
22
|
-
def fetch(url)
|
23
|
+
def fetch(url, spin: true)
|
24
|
+
if spin
|
25
|
+
@spinner = TTY::Spinner.new "[:spinner] GET #{url}.", format: :flip
|
26
|
+
@spinner.auto_spin
|
27
|
+
end
|
28
|
+
|
23
29
|
response = Net::HTTP.get_response URI(url)
|
24
30
|
|
25
31
|
case response
|
26
32
|
when Net::HTTPSuccess
|
33
|
+
@spinner.success "#{response.code} #{response.message}" if @spinner
|
34
|
+
@spinner = nil
|
27
35
|
response.body
|
28
36
|
when Net::HTTPRedirection
|
29
|
-
fetch response['location']
|
37
|
+
fetch response['location'], spin: false
|
30
38
|
else
|
39
|
+
@spinner.error "#{response.code} #{response.message}" if @spinner
|
40
|
+
@spinner = nil
|
31
41
|
raise "Error fetching #{url}: #{response.code} #{response.message}"
|
32
42
|
end
|
33
43
|
end
|
34
44
|
|
35
|
-
def download(url, dest)
|
45
|
+
def download(url, dest, spin: true)
|
36
46
|
uri = URI(url)
|
37
47
|
|
48
|
+
@spinner = TTY::Spinner.new "[:spinner] GET #{uri}.", format: :flip if spin
|
49
|
+
|
38
50
|
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
|
39
51
|
request = Net::HTTP::Get.new uri
|
40
52
|
|
@@ -43,7 +55,7 @@ module BranchIOCLI
|
|
43
55
|
when Net::HTTPSuccess
|
44
56
|
bytes_downloaded = 0
|
45
57
|
dots_reported = 0
|
46
|
-
#
|
58
|
+
# spin every 100 kB
|
47
59
|
per_dot = 102_400
|
48
60
|
|
49
61
|
File.open dest, 'w' do |io|
|
@@ -53,16 +65,18 @@ module BranchIOCLI
|
|
53
65
|
# print progress
|
54
66
|
bytes_downloaded += chunk.length
|
55
67
|
while (bytes_downloaded - per_dot * dots_reported) >= per_dot
|
56
|
-
|
68
|
+
@spinner.spin
|
57
69
|
dots_reported += 1
|
58
70
|
end
|
59
|
-
STDOUT.flush
|
60
71
|
end
|
61
72
|
end
|
62
|
-
|
73
|
+
@spinner.success "#{response.code} #{response.message}" if @spinner
|
74
|
+
@spinner = nil
|
63
75
|
when Net::HTTPRedirection
|
64
|
-
download response['location'], dest
|
76
|
+
download response['location'], dest, spin: false
|
65
77
|
else
|
78
|
+
@spinner.error "#{response.code} #{response.message}" if @spinner
|
79
|
+
@spinner = nil
|
66
80
|
raise "Error downloading #{url}: #{response.code} #{response.message}"
|
67
81
|
end
|
68
82
|
end
|
@@ -2,9 +2,10 @@ require "active_support/core_ext/object"
|
|
2
2
|
require "json"
|
3
3
|
require "openssl"
|
4
4
|
require "plist"
|
5
|
+
require "tty/spinner"
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
require_relative "../configuration"
|
8
|
+
require_relative "methods"
|
8
9
|
|
9
10
|
module BranchIOCLI
|
10
11
|
module Helper
|
@@ -279,19 +280,25 @@ module BranchIOCLI
|
|
279
280
|
|
280
281
|
Net::HTTP.start uri.host, uri.port, use_ssl: uri.scheme == "https" do |http|
|
281
282
|
request = Net::HTTP::Get.new uri
|
283
|
+
spinner = TTY::Spinner.new "[:spinner] GET #{uri}.", format: :flip
|
284
|
+
spinner.auto_spin
|
282
285
|
response = http.request request
|
283
286
|
|
284
287
|
# Better to use Net::HTTPRedirection and Net::HTTPSuccess here, but
|
285
288
|
# having difficulty with the unit tests.
|
286
289
|
if (300..399).cover?(response.code.to_i)
|
290
|
+
spinner.error "#{response.code} #{response.message}"
|
287
291
|
say "#{uri} cannot result in a redirect. Ignoring."
|
288
292
|
next
|
289
293
|
elsif response.code.to_i != 200
|
290
294
|
# Try the next URI.
|
291
|
-
|
295
|
+
spinner.error "#{response.code} #{response.message}"
|
296
|
+
say "Could not retrieve #{uri}. Ignoring."
|
292
297
|
next
|
293
298
|
end
|
294
299
|
|
300
|
+
spinner.success "#{response.code} #{response.message}"
|
301
|
+
|
295
302
|
content_type = response["Content-type"]
|
296
303
|
@errors << "[#{domain}] AASA Response does not contain a Content-type header" and next if content_type.nil?
|
297
304
|
|
@@ -307,8 +314,6 @@ module BranchIOCLI
|
|
307
314
|
@errors << "[#{domain}] Unsigned AASA files must be served via HTTPS" and next if uri.scheme == "http"
|
308
315
|
data = response.body
|
309
316
|
end
|
310
|
-
|
311
|
-
say "GET #{uri}: #{response.code} #{response.message} (Content-type:#{content_type}) ✅"
|
312
317
|
end
|
313
318
|
end
|
314
319
|
|
@@ -447,19 +452,12 @@ module BranchIOCLI
|
|
447
452
|
|
448
453
|
branch_keys = branch_keys.map { |key| config.target.expand_build_settings key, configuration }
|
449
454
|
|
450
|
-
valid = true
|
451
|
-
|
452
455
|
# Retrieve app data from Branch API for all keys in the Info.plist
|
453
|
-
apps = branch_keys.map
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
say "[#{key}] #{e.message} ❌"
|
459
|
-
valid = false
|
460
|
-
nil
|
461
|
-
end
|
462
|
-
end.compact.uniq
|
456
|
+
apps = branch_keys.map { |k| BranchApp[k] }.compact.uniq
|
457
|
+
invalid_keys = apps.reject(&:valid?).map(&:key)
|
458
|
+
|
459
|
+
valid = invalid_keys.empty?
|
460
|
+
say "Invalid Branch key(s) in Info.plist for #{configuration} configuration: #{invalid_keys}. ❌" unless valid
|
463
461
|
|
464
462
|
# Get domains and URI schemes loaded from API
|
465
463
|
domains_from_api = domains apps
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require "plist"
|
2
2
|
require "shellwords"
|
3
|
-
|
3
|
+
require_relative "../configuration/configuration"
|
4
4
|
|
5
5
|
module BranchIOCLI
|
6
6
|
module Helper
|
@@ -22,6 +22,10 @@ module BranchIOCLI
|
|
22
22
|
Configuration::Configuration.current
|
23
23
|
end
|
24
24
|
|
25
|
+
def env
|
26
|
+
Configuration::Environment
|
27
|
+
end
|
28
|
+
|
25
29
|
def helper
|
26
30
|
BranchHelper
|
27
31
|
end
|