branch_io_cli 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +58 -50
- data/lib/assets/completions/completion.bash +1 -1
- data/lib/assets/completions/completion.zsh +1 -1
- data/lib/assets/templates/command.erb +5 -5
- data/lib/branch_io_cli/cli.rb +56 -45
- data/lib/branch_io_cli/command/report_command.rb +3 -1
- data/lib/branch_io_cli/command/setup_command.rb +19 -15
- data/lib/branch_io_cli/command/validate_command.rb +3 -3
- data/lib/branch_io_cli/configuration/configuration.rb +159 -22
- data/lib/branch_io_cli/configuration/option.rb +78 -0
- data/lib/branch_io_cli/configuration/option_wrapper.rb +5 -2
- data/lib/branch_io_cli/configuration/report_configuration.rb +7 -42
- data/lib/branch_io_cli/configuration/setup_configuration.rb +43 -15
- data/lib/branch_io_cli/configuration/validate_configuration.rb +4 -0
- data/lib/branch_io_cli/format.rb +1 -1
- data/lib/branch_io_cli/format/{commander_format.rb → highline_format.rb} +1 -1
- data/lib/branch_io_cli/format/markdown_format.rb +4 -0
- data/lib/branch_io_cli/helper.rb +3 -0
- data/lib/branch_io_cli/helper/ios_helper.rb +36 -99
- data/lib/branch_io_cli/helper/methods.rb +18 -2
- data/lib/branch_io_cli/helper/report_helper.rb +11 -8
- data/lib/branch_io_cli/helper/util.rb +7 -0
- data/lib/branch_io_cli/helper/xcodeproj_ext.rb +126 -0
- data/lib/branch_io_cli/rake_task.rb +2 -2
- data/lib/branch_io_cli/version.rb +1 -1
- metadata +5 -3
|
@@ -2,6 +2,7 @@ module BranchIOCLI
|
|
|
2
2
|
module Configuration
|
|
3
3
|
class Option
|
|
4
4
|
attr_accessor :name
|
|
5
|
+
attr_accessor :env_name
|
|
5
6
|
attr_accessor :type
|
|
6
7
|
attr_accessor :description
|
|
7
8
|
attr_accessor :default_value
|
|
@@ -9,9 +10,16 @@ module BranchIOCLI
|
|
|
9
10
|
attr_accessor :argument_optional
|
|
10
11
|
attr_accessor :aliases
|
|
11
12
|
attr_accessor :negatable
|
|
13
|
+
attr_accessor :confirm_symbol
|
|
14
|
+
attr_accessor :valid_values_proc
|
|
15
|
+
attr_accessor :validate_proc
|
|
16
|
+
attr_accessor :convert_proc
|
|
17
|
+
attr_accessor :label
|
|
18
|
+
attr_accessor :skip_confirmation
|
|
12
19
|
|
|
13
20
|
def initialize(options)
|
|
14
21
|
@name = options[:name]
|
|
22
|
+
@env_name = options[:env_name]
|
|
15
23
|
@type = options[:type]
|
|
16
24
|
@description = options[:description]
|
|
17
25
|
@default_value = options[:default_value]
|
|
@@ -19,10 +27,80 @@ module BranchIOCLI
|
|
|
19
27
|
@argument_optional = options[:argument_optional] || false
|
|
20
28
|
@aliases = options[:aliases] || []
|
|
21
29
|
@aliases = [@aliases] unless @aliases.kind_of?(Array)
|
|
30
|
+
@negatable = options[:negatable]
|
|
22
31
|
@negatable = options[:type].nil? if options[:negatable].nil?
|
|
32
|
+
@confirm_symbol = options[:confirm_symbol] || @name
|
|
33
|
+
@valid_values_proc = options[:valid_values_proc]
|
|
34
|
+
@validate_proc = options[:validate_proc]
|
|
35
|
+
@convert_proc = options[:convert_proc]
|
|
36
|
+
@label = options[:label] || @name.to_s.capitalize.gsub(/_/, ' ')
|
|
37
|
+
@skip_confirmation = options[:skip_confirmation]
|
|
23
38
|
|
|
39
|
+
raise ArgumentError, "Use :validate_proc or :valid_values_proc, but not both." if @valid_values_proc && @validate_proc
|
|
40
|
+
|
|
41
|
+
@env_name = "BRANCH_#{@name.to_s.upcase}" if @env_name.nil?
|
|
24
42
|
@argument_optional ||= @negatable
|
|
25
43
|
end
|
|
44
|
+
|
|
45
|
+
def valid_values
|
|
46
|
+
return valid_values_proc.call if valid_values_proc && valid_values_proc.kind_of?(Proc)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def ui_type
|
|
50
|
+
if type.nil?
|
|
51
|
+
"Boolean"
|
|
52
|
+
elsif type == Array
|
|
53
|
+
"Comma-separated list"
|
|
54
|
+
else
|
|
55
|
+
type.to_s
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def env_value
|
|
60
|
+
convert(ENV[env_name]) if env_name
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def convert(value)
|
|
64
|
+
return convert_proc.call(value) if convert_proc
|
|
65
|
+
|
|
66
|
+
if type == Array
|
|
67
|
+
value = value.split(",") if value.kind_of?(String)
|
|
68
|
+
elsif type == String && value.kind_of?(String)
|
|
69
|
+
value = value.strip
|
|
70
|
+
value = nil if value.empty?
|
|
71
|
+
elsif type.nil?
|
|
72
|
+
value = true if value.kind_of?(String) && value =~ /^[ty]/i
|
|
73
|
+
value = false if value.kind_of?(String) && value =~ /^[fn]/i
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
value
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def display_value(value)
|
|
80
|
+
if type.nil?
|
|
81
|
+
value ? "yes" : "no"
|
|
82
|
+
elsif value.nil?
|
|
83
|
+
"(none)"
|
|
84
|
+
else
|
|
85
|
+
value.to_s
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def valid?(value)
|
|
90
|
+
return validate_proc.call(value) if validate_proc
|
|
91
|
+
|
|
92
|
+
return true if value.nil?
|
|
93
|
+
|
|
94
|
+
if valid_values && type != Array
|
|
95
|
+
valid_values.include? value
|
|
96
|
+
elsif valid_values
|
|
97
|
+
value.all? { |v| valid_values.include?(v) }
|
|
98
|
+
elsif type
|
|
99
|
+
value.kind_of? type
|
|
100
|
+
else
|
|
101
|
+
value == true || value == false
|
|
102
|
+
end
|
|
103
|
+
end
|
|
26
104
|
end
|
|
27
105
|
end
|
|
28
106
|
end
|
|
@@ -7,7 +7,7 @@ module BranchIOCLI
|
|
|
7
7
|
attr_reader :add_defaults
|
|
8
8
|
|
|
9
9
|
def initialize(hash, options, add_defaults = true)
|
|
10
|
-
|
|
10
|
+
hash ||= {}
|
|
11
11
|
|
|
12
12
|
@hash = hash
|
|
13
13
|
@options = options
|
|
@@ -22,7 +22,10 @@ module BranchIOCLI
|
|
|
22
22
|
|
|
23
23
|
value = hash[method_sym]
|
|
24
24
|
return value unless add_defaults && value.nil?
|
|
25
|
-
|
|
25
|
+
|
|
26
|
+
default_value = option.env_value
|
|
27
|
+
default_value = option.default_value if default_value.nil?
|
|
28
|
+
default_value
|
|
26
29
|
end
|
|
27
30
|
|
|
28
31
|
def build_option_hash
|
|
@@ -1,51 +1,15 @@
|
|
|
1
1
|
require "plist"
|
|
2
2
|
require "xcodeproj"
|
|
3
3
|
|
|
4
|
-
module Xcodeproj
|
|
5
|
-
class Project
|
|
6
|
-
# Local override to allow for user schemes.
|
|
7
|
-
#
|
|
8
|
-
# Get list of shared and user schemes in project
|
|
9
|
-
#
|
|
10
|
-
# @param [String] path
|
|
11
|
-
# project path
|
|
12
|
-
#
|
|
13
|
-
# @return [Array]
|
|
14
|
-
#
|
|
15
|
-
def self.schemes(project_path)
|
|
16
|
-
base_dirs = [File.join(project_path, 'xcshareddata', 'xcschemes'),
|
|
17
|
-
File.join(project_path, 'xcuserdata', "#{ENV['USER']}.xcuserdatad", 'xcschemes')]
|
|
18
|
-
|
|
19
|
-
# Take any .xcscheme file from base_dirs
|
|
20
|
-
schemes = base_dirs.inject([]) { |memo, dir| memo + Dir[File.join dir, '*.xcscheme'] }
|
|
21
|
-
.map { |f| File.basename(f, '.xcscheme') }
|
|
22
|
-
|
|
23
|
-
# Include any scheme defined in the xcschememanagement.plist, if it exists.
|
|
24
|
-
base_dirs.map { |d| File.join d, 'xcschememanagement.plist' }
|
|
25
|
-
.select { |f| File.exist? f }.each do |plist_path|
|
|
26
|
-
plist = File.open(plist_path) { |f| ::Plist.parse_xml f }
|
|
27
|
-
scheme_user_state = plist["SchemeUserState"]
|
|
28
|
-
schemes += scheme_user_state.keys.map { |k| File.basename k, '.xcscheme' }
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
schemes.uniq!
|
|
32
|
-
if schemes.empty? && File.exist?(project_path)
|
|
33
|
-
# Open the project, get all targets. Add one scheme per target.
|
|
34
|
-
project = self.open project_path
|
|
35
|
-
schemes += project.targets.reject(&:test_target_type?).map(&:name)
|
|
36
|
-
elsif schemes.empty?
|
|
37
|
-
schemes << File.basename(project_path, '.xcodeproj')
|
|
38
|
-
end
|
|
39
|
-
schemes
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
4
|
module BranchIOCLI
|
|
45
5
|
module Configuration
|
|
46
6
|
# rubocop: disable Metrics/ClassLength
|
|
47
7
|
class ReportConfiguration < Configuration
|
|
48
8
|
class << self
|
|
9
|
+
def summary
|
|
10
|
+
"Generate and optionally submit a build diagnostic report."
|
|
11
|
+
end
|
|
12
|
+
|
|
49
13
|
def available_options
|
|
50
14
|
[
|
|
51
15
|
Option.new(
|
|
@@ -119,7 +83,8 @@ module BranchIOCLI
|
|
|
119
83
|
default_value: "./report.txt",
|
|
120
84
|
aliases: "-o",
|
|
121
85
|
example: "./report.txt",
|
|
122
|
-
type: String
|
|
86
|
+
type: String,
|
|
87
|
+
env_name: "BRANCH_REPORT_PATH"
|
|
123
88
|
)
|
|
124
89
|
]
|
|
125
90
|
end
|
|
@@ -456,7 +421,7 @@ EOF
|
|
|
456
421
|
def branch_key_setting_from_info_plist(config = configuration || "Release")
|
|
457
422
|
return @branch_key_setting_from_info_plist if @branch_key_setting_from_info_plist
|
|
458
423
|
|
|
459
|
-
infoplist_path =
|
|
424
|
+
infoplist_path = target.expanded_build_setting "INFOPLIST_FILE", config
|
|
460
425
|
infoplist_path = File.expand_path infoplist_path, File.dirname(xcodeproj_path)
|
|
461
426
|
info_plist = File.open(infoplist_path) { |f| Plist.parse_xml f }
|
|
462
427
|
branch_key = info_plist["branch_key"]
|
|
@@ -3,6 +3,10 @@ module BranchIOCLI
|
|
|
3
3
|
# rubocop: disable Metrics/ClassLength
|
|
4
4
|
class SetupConfiguration < Configuration
|
|
5
5
|
class << self
|
|
6
|
+
def summary
|
|
7
|
+
"Integrates the Branch SDK into a native app project"
|
|
8
|
+
end
|
|
9
|
+
|
|
6
10
|
def examples
|
|
7
11
|
{
|
|
8
12
|
"Test without validation (can use dummy keys and domains)" => "branch_io setup -L key_live_xxxx -D myapp.app.link --no-validate",
|
|
@@ -34,20 +38,24 @@ module BranchIOCLI
|
|
|
34
38
|
description: "Comma-separated list of custom domain(s) or non-Branch domain(s)",
|
|
35
39
|
example: "example.com,www.example.com",
|
|
36
40
|
type: Array,
|
|
37
|
-
aliases: "-D"
|
|
41
|
+
aliases: "-D",
|
|
42
|
+
confirm_symbol: :all_domains
|
|
38
43
|
),
|
|
39
44
|
Option.new(
|
|
40
45
|
name: :app_link_subdomain,
|
|
41
46
|
description: "Branch app.link subdomain, e.g. myapp for myapp.app.link",
|
|
42
47
|
example: "myapp",
|
|
43
|
-
type: String
|
|
48
|
+
type: String,
|
|
49
|
+
label: "app.link subdomain",
|
|
50
|
+
skip_confirmation: true
|
|
44
51
|
),
|
|
45
52
|
Option.new(
|
|
46
53
|
name: :uri_scheme,
|
|
47
54
|
description: "Custom URI scheme used in the Branch Dashboard for this app",
|
|
48
55
|
example: "myurischeme[://]",
|
|
49
56
|
type: String,
|
|
50
|
-
aliases: "-U"
|
|
57
|
+
aliases: "-U",
|
|
58
|
+
label: "URI scheme"
|
|
51
59
|
),
|
|
52
60
|
Option.new(
|
|
53
61
|
name: :setting,
|
|
@@ -55,38 +63,49 @@ module BranchIOCLI
|
|
|
55
63
|
example: "BRANCH_KEY_SETTING",
|
|
56
64
|
type: String,
|
|
57
65
|
argument_optional: true,
|
|
58
|
-
aliases: "-s"
|
|
66
|
+
aliases: "-s",
|
|
67
|
+
label: "User-defined setting for Branch key"
|
|
59
68
|
),
|
|
60
69
|
Option.new(
|
|
61
70
|
name: :test_configurations,
|
|
62
|
-
description: "List of configurations that use the test key with a
|
|
71
|
+
description: "List of configurations that use the test key with a user-defined setting (default: Debug configurations)",
|
|
63
72
|
example: "config1,config2",
|
|
64
73
|
type: Array,
|
|
65
|
-
negatable: true
|
|
74
|
+
negatable: true,
|
|
75
|
+
valid_values_proc: ->() { Configuration.current.xcodeproj.build_configurations.map(&:name) }
|
|
66
76
|
),
|
|
67
77
|
Option.new(
|
|
68
78
|
name: :xcodeproj,
|
|
69
79
|
description: "Path to an Xcode project to update",
|
|
70
80
|
example: "MyProject.xcodeproj",
|
|
71
|
-
type: String
|
|
81
|
+
type: String,
|
|
82
|
+
confirm_symbol: :xcodeproj_path,
|
|
83
|
+
validate_proc: ->(path) { Configuration.open_xcodeproj path }
|
|
72
84
|
),
|
|
73
85
|
Option.new(
|
|
74
86
|
name: :target,
|
|
75
87
|
description: "Name of a target to modify in the Xcode project",
|
|
76
88
|
example: "MyAppTarget",
|
|
77
|
-
type: String
|
|
89
|
+
type: String,
|
|
90
|
+
confirm_symbol: :target_name,
|
|
91
|
+
valid_values_proc: ->() { Configuration.current.xcodeproj.targets.map(&:name) }
|
|
78
92
|
),
|
|
79
93
|
Option.new(
|
|
80
94
|
name: :podfile,
|
|
81
95
|
description: "Path to the Podfile for the project",
|
|
82
96
|
example: "/path/to/Podfile",
|
|
83
|
-
type: String
|
|
97
|
+
type: String,
|
|
98
|
+
confirm_symbol: :podfile_path,
|
|
99
|
+
validate_proc: ->(path) { Configuration.open_podfile path }
|
|
84
100
|
),
|
|
85
101
|
Option.new(
|
|
86
102
|
name: :cartfile,
|
|
87
103
|
description: "Path to the Cartfile for the project",
|
|
88
104
|
example: "/path/to/Cartfile",
|
|
89
|
-
type: String
|
|
105
|
+
type: String,
|
|
106
|
+
confirm_symbol: :cartfile_path,
|
|
107
|
+
validate_proc: ->(path) { !path.nil? && File.exist?(path.to_s) },
|
|
108
|
+
convert_proc: ->(path) { Configuration.absolute_path(path.to_s) unless path.nil? }
|
|
90
109
|
),
|
|
91
110
|
Option.new(
|
|
92
111
|
name: :carthage_command,
|
|
@@ -128,15 +147,17 @@ module BranchIOCLI
|
|
|
128
147
|
),
|
|
129
148
|
Option.new(
|
|
130
149
|
name: :commit,
|
|
131
|
-
description: "Commit the results to Git",
|
|
150
|
+
description: "Commit the results to Git if non-blank",
|
|
132
151
|
type: String,
|
|
133
152
|
example: "message",
|
|
134
|
-
argument_optional: true
|
|
153
|
+
argument_optional: true,
|
|
154
|
+
label: "Commit message"
|
|
135
155
|
),
|
|
136
156
|
Option.new(
|
|
137
|
-
name: :
|
|
138
|
-
description: "
|
|
139
|
-
default_value: true
|
|
157
|
+
name: :confirm,
|
|
158
|
+
description: "Confirm configuration before proceeding",
|
|
159
|
+
default_value: true,
|
|
160
|
+
skip_confirmation: true
|
|
140
161
|
)
|
|
141
162
|
]
|
|
142
163
|
end
|
|
@@ -155,6 +176,12 @@ module BranchIOCLI
|
|
|
155
176
|
attr_reader :keys
|
|
156
177
|
attr_reader :all_domains
|
|
157
178
|
|
|
179
|
+
def initialize(options)
|
|
180
|
+
super
|
|
181
|
+
# Configuration has been validated and logged to the screen.
|
|
182
|
+
confirm_with_user if options.confirm
|
|
183
|
+
end
|
|
184
|
+
|
|
158
185
|
def validate_options
|
|
159
186
|
@validate = options.validate
|
|
160
187
|
@patch_source = options.patch_source
|
|
@@ -266,6 +293,7 @@ module BranchIOCLI
|
|
|
266
293
|
key = ask "Please enter your #{type} Branch key or use --#{type}-key [enter for none]: "
|
|
267
294
|
end
|
|
268
295
|
@keys[type] = key unless key.empty?
|
|
296
|
+
instance_variable_set "@#{type}_key", key
|
|
269
297
|
end
|
|
270
298
|
|
|
271
299
|
def validate_all_domains(options, required = true)
|
|
@@ -2,6 +2,10 @@ module BranchIOCLI
|
|
|
2
2
|
module Configuration
|
|
3
3
|
class ValidateConfiguration < Configuration
|
|
4
4
|
class << self
|
|
5
|
+
def summary
|
|
6
|
+
"Validates all Universal Link domains configured in a project"
|
|
7
|
+
end
|
|
8
|
+
|
|
5
9
|
def return_value
|
|
6
10
|
"If validation passes, this command returns 0. If validation fails, it returns 1."
|
|
7
11
|
end
|
data/lib/branch_io_cli/format.rb
CHANGED
data/lib/branch_io_cli/helper.rb
CHANGED
|
@@ -15,6 +15,8 @@ require "branch_io_cli/helper/methods"
|
|
|
15
15
|
module BranchIOCLI
|
|
16
16
|
module Helper
|
|
17
17
|
module IOSHelper
|
|
18
|
+
include Methods
|
|
19
|
+
|
|
18
20
|
APPLINKS = "applinks"
|
|
19
21
|
ASSOCIATED_DOMAINS = "com.apple.developer.associated-domains"
|
|
20
22
|
CODE_SIGN_ENTITLEMENTS = "CODE_SIGN_ENTITLEMENTS"
|
|
@@ -28,7 +30,7 @@ module BranchIOCLI
|
|
|
28
30
|
|
|
29
31
|
def has_multiple_info_plists?
|
|
30
32
|
config.xcodeproj.build_configurations.inject([]) do |files, c|
|
|
31
|
-
files + [
|
|
33
|
+
files + [config.target.expanded_build_setting("INFOPLIST_FILE", c.name)]
|
|
32
34
|
end.uniq.count > 1
|
|
33
35
|
end
|
|
34
36
|
|
|
@@ -117,7 +119,7 @@ module BranchIOCLI
|
|
|
117
119
|
|
|
118
120
|
def update_info_plist_setting(configuration = RELEASE_CONFIGURATION, &b)
|
|
119
121
|
# find the Info.plist paths for this configuration
|
|
120
|
-
info_plist_path =
|
|
122
|
+
info_plist_path = config.target.expanded_build_setting "INFOPLIST_FILE", configuration
|
|
121
123
|
|
|
122
124
|
raise "Info.plist not found for configuration #{configuration}" if info_plist_path.nil?
|
|
123
125
|
|
|
@@ -139,7 +141,7 @@ module BranchIOCLI
|
|
|
139
141
|
project = config.xcodeproj
|
|
140
142
|
target = config.target
|
|
141
143
|
|
|
142
|
-
relative_entitlements_path = expanded_build_setting
|
|
144
|
+
relative_entitlements_path = target.expanded_build_setting CODE_SIGN_ENTITLEMENTS, configuration
|
|
143
145
|
project_parent = File.dirname project.path
|
|
144
146
|
|
|
145
147
|
if relative_entitlements_path.nil?
|
|
@@ -312,8 +314,8 @@ module BranchIOCLI
|
|
|
312
314
|
def validate_team_and_bundle_ids(domain, configuration)
|
|
313
315
|
target = config.target
|
|
314
316
|
|
|
315
|
-
product_bundle_identifier = expanded_build_setting
|
|
316
|
-
development_team = expanded_build_setting
|
|
317
|
+
product_bundle_identifier = target.expanded_build_setting PRODUCT_BUNDLE_IDENTIFIER, configuration
|
|
318
|
+
development_team = target.expanded_build_setting DEVELOPMENT_TEAM, configuration
|
|
317
319
|
|
|
318
320
|
identifiers = app_ids_from_aasa_file domain
|
|
319
321
|
return false if identifiers.nil?
|
|
@@ -380,7 +382,7 @@ module BranchIOCLI
|
|
|
380
382
|
project = config.xcodeproj
|
|
381
383
|
target = config.target
|
|
382
384
|
|
|
383
|
-
relative_entitlements_path = expanded_build_setting
|
|
385
|
+
relative_entitlements_path = target.expanded_build_setting CODE_SIGN_ENTITLEMENTS, configuration
|
|
384
386
|
return [] if relative_entitlements_path.nil?
|
|
385
387
|
|
|
386
388
|
project_parent = File.dirname project.path
|
|
@@ -393,98 +395,33 @@ module BranchIOCLI
|
|
|
393
395
|
entitlements[ASSOCIATED_DOMAINS].select { |d| d =~ /^applinks:/ }.map { |d| d.sub(/^applinks:/, "") }
|
|
394
396
|
end
|
|
395
397
|
|
|
396
|
-
def expanded_build_setting(target, setting_name, configuration)
|
|
397
|
-
# second arg true means if there is an xcconfig, also consult that
|
|
398
|
-
begin
|
|
399
|
-
setting_value = target.resolved_build_setting(setting_name, true)[configuration]
|
|
400
|
-
rescue Errno::ENOENT
|
|
401
|
-
# If not found, look up without it
|
|
402
|
-
setting_value = target.resolved_build_setting(setting_name, false)[configuration]
|
|
403
|
-
end
|
|
404
|
-
|
|
405
|
-
return if setting_value.nil?
|
|
406
|
-
|
|
407
|
-
expand_build_settings setting_value, target, configuration
|
|
408
|
-
end
|
|
409
|
-
|
|
410
|
-
def expand_build_settings(string, target, configuration)
|
|
411
|
-
search_position = 0
|
|
412
|
-
# It's safest to make a copy of this string, though we probably get a
|
|
413
|
-
# copy from PBXNativeTarget#resolve_build_setting anyway. Copying here
|
|
414
|
-
# avoids a copy on every match.
|
|
415
|
-
string = string.clone
|
|
416
|
-
|
|
417
|
-
# HACK: When matching against an xcconfig, as here, sometimes the macro is just returned
|
|
418
|
-
# without delimiters, e.g. TARGET_NAME or BUILT_PRODUCTS_DIR/Branch.framework. We allow
|
|
419
|
-
# these two patterns for now.
|
|
420
|
-
while (matches = %r{\$\(([^(){}]*)\)|\$\{([^(){}]*)\}|^([A-Z_]+)(/.*)?$}.match(string, search_position))
|
|
421
|
-
original_macro = matches[1] || matches[2] || matches[3]
|
|
422
|
-
delimiter_length = matches[3] ? 0 : 3 # $() or ${}
|
|
423
|
-
delimiter_offset = matches[3] ? 0 : 2 # $( or ${
|
|
424
|
-
search_position = string.index(original_macro) - delimiter_offset
|
|
425
|
-
|
|
426
|
-
modifier_regexp = /^(.+):(.+)$/
|
|
427
|
-
if (matches = modifier_regexp.match original_macro)
|
|
428
|
-
macro_name = matches[1]
|
|
429
|
-
modifier = matches[2]
|
|
430
|
-
else
|
|
431
|
-
macro_name = original_macro
|
|
432
|
-
end
|
|
433
|
-
|
|
434
|
-
case macro_name
|
|
435
|
-
when "SRCROOT"
|
|
436
|
-
expanded_macro = "."
|
|
437
|
-
when "TARGET_NAME"
|
|
438
|
-
# Clone in case of modifier processing
|
|
439
|
-
expanded_macro = target.name.clone
|
|
440
|
-
else
|
|
441
|
-
expanded_macro = expanded_build_setting(target, macro_name, configuration)
|
|
442
|
-
end
|
|
443
|
-
|
|
444
|
-
search_position += original_macro.length + delimiter_length and next if expanded_macro.nil?
|
|
445
|
-
|
|
446
|
-
if modifier == "rfc1034identifier"
|
|
447
|
-
# From the Apple dev portal when creating a new app ID:
|
|
448
|
-
# You cannot use special characters such as @, &, *, ', "
|
|
449
|
-
# From trial and error with Xcode, it appears that only letters, digits and hyphens are allowed.
|
|
450
|
-
# Everything else becomes a hyphen, including underscores.
|
|
451
|
-
special_chars = /[^A-Za-z0-9-]/
|
|
452
|
-
expanded_macro.gsub!(special_chars, '-')
|
|
453
|
-
end
|
|
454
|
-
|
|
455
|
-
string.gsub!(/\$\(#{original_macro}\)|\$\{#{original_macro}\}|^#{original_macro}/, expanded_macro)
|
|
456
|
-
search_position += expanded_macro.length
|
|
457
|
-
end
|
|
458
|
-
string
|
|
459
|
-
end
|
|
460
|
-
|
|
461
398
|
def add_cocoapods(options)
|
|
462
399
|
verify_cocoapods
|
|
463
400
|
|
|
464
|
-
podfile_path =
|
|
401
|
+
podfile_path = options.podfile_path
|
|
465
402
|
|
|
466
403
|
install_command = "pod install"
|
|
467
404
|
install_command += " --repo-update" if options.pod_repo_update
|
|
468
405
|
Dir.chdir(File.dirname(podfile_path)) do
|
|
469
406
|
sh "pod init"
|
|
470
407
|
PatternPatch::Patch.new(
|
|
471
|
-
regexp: /^(\s*)# Pods for #{
|
|
408
|
+
regexp: /^(\s*)# Pods for #{options.target.name}$/,
|
|
472
409
|
mode: :append,
|
|
473
410
|
text: "\n\\1pod \"Branch\""
|
|
474
411
|
).apply podfile_path
|
|
475
412
|
# Store a Pod::Podfile representation of this file.
|
|
476
|
-
|
|
413
|
+
options.open_podfile
|
|
477
414
|
sh install_command
|
|
478
415
|
end
|
|
479
416
|
|
|
480
|
-
return unless
|
|
417
|
+
return unless options.commit
|
|
481
418
|
|
|
482
419
|
add_change podfile_path
|
|
483
420
|
add_change "#{podfile_path}.lock"
|
|
484
421
|
|
|
485
422
|
# For now, add Pods folder to SCM.
|
|
486
423
|
pods_folder_path = Pathname.new(File.expand_path("../Pods", podfile_path)).relative_path_from Pathname.pwd
|
|
487
|
-
workspace_path = Pathname.new(File.expand_path(
|
|
424
|
+
workspace_path = Pathname.new(File.expand_path(options.xcodeproj_path.sub(/.xcodeproj$/, ".xcworkspace"))).relative_path_from Pathname.pwd
|
|
488
425
|
podfile_pathname = Pathname.new(podfile_path).relative_path_from Pathname.pwd
|
|
489
426
|
add_change pods_folder_path
|
|
490
427
|
add_change workspace_path
|
|
@@ -504,7 +441,7 @@ module BranchIOCLI
|
|
|
504
441
|
verify_carthage
|
|
505
442
|
|
|
506
443
|
# 1. Generate Cartfile
|
|
507
|
-
cartfile_path =
|
|
444
|
+
cartfile_path = options.cartfile_path
|
|
508
445
|
File.open(cartfile_path, "w") do |file|
|
|
509
446
|
file.write <<EOF
|
|
510
447
|
github "BranchMetrics/ios-branch-deep-linking"
|
|
@@ -513,18 +450,18 @@ EOF
|
|
|
513
450
|
|
|
514
451
|
# 2. carthage update
|
|
515
452
|
Dir.chdir(File.dirname(cartfile_path)) do
|
|
516
|
-
sh "carthage #{
|
|
453
|
+
sh "carthage #{options.carthage_command}"
|
|
517
454
|
end
|
|
518
455
|
|
|
519
456
|
# 3. Add Cartfile and Cartfile.resolved to commit (in case :commit param specified)
|
|
520
457
|
add_change cartfile_path
|
|
521
458
|
add_change "#{cartfile_path}.resolved"
|
|
522
|
-
add_change
|
|
459
|
+
add_change options.xcodeproj_path
|
|
523
460
|
|
|
524
461
|
# 4. Add to target dependencies
|
|
525
|
-
frameworks_group =
|
|
462
|
+
frameworks_group = options.xcodeproj.frameworks_group
|
|
526
463
|
branch_framework = frameworks_group.new_file "Carthage/Build/iOS/Branch.framework"
|
|
527
|
-
target =
|
|
464
|
+
target = options.target
|
|
528
465
|
target.frameworks_build_phase.add_file_reference branch_framework
|
|
529
466
|
|
|
530
467
|
# 5. Create a copy-frameworks build phase
|
|
@@ -536,9 +473,9 @@ EOF
|
|
|
536
473
|
|
|
537
474
|
update_framework_search_paths "$(SRCROOT)/Carthage/Build/iOS"
|
|
538
475
|
|
|
539
|
-
|
|
476
|
+
options.xcodeproj.save
|
|
540
477
|
|
|
541
|
-
return unless
|
|
478
|
+
return unless options.commit
|
|
542
479
|
|
|
543
480
|
# For now, add Carthage folder to SCM
|
|
544
481
|
|
|
@@ -551,7 +488,7 @@ EOF
|
|
|
551
488
|
|
|
552
489
|
def add_direct(options)
|
|
553
490
|
# Put the framework in the path for any existing Frameworks group in the project.
|
|
554
|
-
frameworks_group =
|
|
491
|
+
frameworks_group = options.xcodeproj.frameworks_group
|
|
555
492
|
framework_path = File.join frameworks_group.real_path, "Branch.framework"
|
|
556
493
|
raise "#{framework_path} exists." if File.exist? framework_path
|
|
557
494
|
|
|
@@ -589,17 +526,17 @@ EOF
|
|
|
589
526
|
|
|
590
527
|
# Now the current framework is in framework_path
|
|
591
528
|
|
|
592
|
-
say "Adding to #{
|
|
529
|
+
say "Adding to #{options.xcodeproj_path}"
|
|
593
530
|
|
|
594
531
|
# Add as a dependency in the Frameworks group
|
|
595
532
|
framework = frameworks_group.new_file "Branch.framework" # relative to frameworks_group.real_path
|
|
596
|
-
|
|
533
|
+
options.target.frameworks_build_phase.add_file_reference framework, true
|
|
597
534
|
|
|
598
535
|
update_framework_search_paths "$(SRCROOT)"
|
|
599
536
|
|
|
600
|
-
|
|
537
|
+
options.xcodeproj.save
|
|
601
538
|
|
|
602
|
-
add_change
|
|
539
|
+
add_change options.xcodeproj_path
|
|
603
540
|
add_change framework_path
|
|
604
541
|
sh ["git", "add", framework_path] if options.commit
|
|
605
542
|
|
|
@@ -625,7 +562,7 @@ EOF
|
|
|
625
562
|
def update_podfile(options)
|
|
626
563
|
verify_cocoapods
|
|
627
564
|
|
|
628
|
-
podfile_path =
|
|
565
|
+
podfile_path = options.podfile_path
|
|
629
566
|
return false if podfile_path.nil?
|
|
630
567
|
|
|
631
568
|
# 1. Patch Podfile. Return if no change (Branch pod already present).
|
|
@@ -659,7 +596,7 @@ EOF
|
|
|
659
596
|
def update_cartfile(options, project)
|
|
660
597
|
verify_carthage
|
|
661
598
|
|
|
662
|
-
cartfile_path =
|
|
599
|
+
cartfile_path = options.cartfile_path
|
|
663
600
|
return false if cartfile_path.nil?
|
|
664
601
|
|
|
665
602
|
# 1. Patch Cartfile. Return if no change (Branch already present).
|
|
@@ -667,18 +604,18 @@ EOF
|
|
|
667
604
|
|
|
668
605
|
# 2. carthage update
|
|
669
606
|
Dir.chdir(File.dirname(cartfile_path)) do
|
|
670
|
-
sh "carthage #{
|
|
607
|
+
sh "carthage #{options.carthage_command} ios-branch-deep-linking"
|
|
671
608
|
end
|
|
672
609
|
|
|
673
610
|
# 3. Add Cartfile and Cartfile.resolved to commit (in case :commit param specified)
|
|
674
611
|
add_change cartfile_path
|
|
675
612
|
add_change "#{cartfile_path}.resolved"
|
|
676
|
-
add_change
|
|
613
|
+
add_change options.xcodeproj_path
|
|
677
614
|
|
|
678
615
|
# 4. Add to target dependencies
|
|
679
616
|
frameworks_group = project.frameworks_group
|
|
680
617
|
branch_framework = frameworks_group.new_file "Carthage/Build/iOS/Branch.framework"
|
|
681
|
-
target =
|
|
618
|
+
target = options.target
|
|
682
619
|
target.frameworks_build_phase.add_file_reference branch_framework
|
|
683
620
|
|
|
684
621
|
# 5. Add to copy-frameworks build phase
|
|
@@ -713,8 +650,8 @@ EOF
|
|
|
713
650
|
exit(-1)
|
|
714
651
|
end
|
|
715
652
|
|
|
716
|
-
install =
|
|
717
|
-
|
|
653
|
+
install = confirm "'pod' command not available in PATH. Install cocoapods (may require a sudo password)?", true
|
|
654
|
+
unless install
|
|
718
655
|
say "Please install cocoapods or use --no-add-sdk to continue."
|
|
719
656
|
exit(-1)
|
|
720
657
|
end
|
|
@@ -740,8 +677,8 @@ EOF
|
|
|
740
677
|
exit(-1)
|
|
741
678
|
end
|
|
742
679
|
|
|
743
|
-
install =
|
|
744
|
-
|
|
680
|
+
install = confirm "'carthage' command not available in PATH. Use Homebrew to install carthage?", true
|
|
681
|
+
unless install
|
|
745
682
|
say "Please install carthage or use --no-add-sdk to continue."
|
|
746
683
|
exit(-1)
|
|
747
684
|
end
|
|
@@ -761,8 +698,8 @@ EOF
|
|
|
761
698
|
exit(-1)
|
|
762
699
|
end
|
|
763
700
|
|
|
764
|
-
install =
|
|
765
|
-
|
|
701
|
+
install = confirm "'git' command not available in PATH. Install Xcode command-line tools (requires password)?", true
|
|
702
|
+
unless install
|
|
766
703
|
say "Please install Xcode command tools or leave out the --commit option to continue."
|
|
767
704
|
exit(-1)
|
|
768
705
|
end
|