roku_builder 3.12.8 → 3.13.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -2
  3. data/CHANGELOG +9 -0
  4. data/Gemfile.lock +17 -11
  5. data/bin/roku +4 -8
  6. data/lib/roku_builder.rb +16 -24
  7. data/lib/roku_builder/config.rb +213 -0
  8. data/lib/roku_builder/config_parser.rb +304 -267
  9. data/lib/roku_builder/config_validator.rb +149 -126
  10. data/lib/roku_builder/controller.rb +34 -184
  11. data/lib/roku_builder/controller_commands.rb +85 -79
  12. data/lib/roku_builder/error_handler.rb +0 -11
  13. data/lib/roku_builder/errors.rb +12 -0
  14. data/lib/roku_builder/inspector.rb +6 -4
  15. data/lib/roku_builder/keyer.rb +1 -1
  16. data/lib/roku_builder/loader.rb +1 -1
  17. data/lib/roku_builder/logger.rb +32 -0
  18. data/lib/roku_builder/manifest_manager.rb +2 -2
  19. data/lib/roku_builder/monitor.rb +1 -1
  20. data/lib/roku_builder/options.rb +113 -0
  21. data/lib/roku_builder/stager.rb +2 -2
  22. data/lib/roku_builder/tester.rb +57 -11
  23. data/lib/roku_builder/util.rb +3 -4
  24. data/lib/roku_builder/version.rb +1 -1
  25. data/roku_builder.gemspec +2 -1
  26. data/test/roku_builder/test_config.rb +168 -0
  27. data/test/roku_builder/test_config_parser.rb +347 -394
  28. data/test/roku_builder/test_config_validator.rb +193 -190
  29. data/test/roku_builder/test_controller.rb +59 -178
  30. data/test/roku_builder/test_controller_commands.rb +407 -394
  31. data/test/roku_builder/test_error_handler.rb +67 -69
  32. data/test/roku_builder/test_files/config_test/bad.json +2 -0
  33. data/test/roku_builder/test_files/config_test/child.json +11 -0
  34. data/test/roku_builder/test_files/config_test/config.json +29 -0
  35. data/test/roku_builder/test_files/config_test/non_json.json +1 -0
  36. data/test/roku_builder/test_files/config_test/parent.json +21 -0
  37. data/test/roku_builder/test_files/config_test/parent_projects.json +35 -0
  38. data/test/roku_builder/test_files/manifest_manager_test/manifest_template_2 +1 -1
  39. data/test/roku_builder/test_helper.rb +55 -45
  40. data/test/roku_builder/test_inspector.rb +278 -213
  41. data/test/roku_builder/test_keyer.rb +144 -147
  42. data/test/roku_builder/test_linker.rb +91 -95
  43. data/test/roku_builder/test_loader.rb +279 -289
  44. data/test/roku_builder/test_logger.rb +47 -0
  45. data/test/roku_builder/test_manifest_manager.rb +92 -94
  46. data/test/roku_builder/test_monitor.rb +101 -103
  47. data/test/roku_builder/test_navigator.rb +240 -245
  48. data/test/roku_builder/test_options.rb +156 -0
  49. data/test/roku_builder/test_packager.rb +108 -108
  50. data/test/roku_builder/test_profiler.rb +20 -19
  51. data/test/roku_builder/test_scripter.rb +83 -81
  52. data/test/roku_builder/test_stager.rb +299 -311
  53. data/test/roku_builder/test_tester.rb +112 -115
  54. data/test/roku_builder/test_util.rb +18 -17
  55. metadata +39 -6
  56. data/lib/roku_builder/config_manager.rb +0 -161
  57. data/test/roku_builder/test_config_manager.rb +0 -372
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3a562753d6f0b7fb5e05b78835ac660754faddda
4
- data.tar.gz: 3c4fbf513f28f9f1c59b5776497be3b9ea626f65
3
+ metadata.gz: dd32080b9b4c8246240b9aaf4a7a2dae7d0e18e9
4
+ data.tar.gz: 421453a021d14e16253702b07d8dfb356a750a2c
5
5
  SHA512:
6
- metadata.gz: a44be2123c1949593a9221855c8e7feb3b4df08d17c5ed4aa316de2c95d25b34e31ad165a947064dbf86c2d089379ce8005df2d899334ae20dffb87bbe9641ec
7
- data.tar.gz: 55ca8895e575e0ffc84170920821430e03081c1388bc171310b920b9827f6676e0a6ae867e06e6b97e5afcf813977abfcb3a3d52ac4d280fe107a8f7686a5d78
6
+ metadata.gz: 70e119253bf7a0379f466070e0fd97e69d2c50c2f353d32cc7985e6e6a69841840674c831f0c1873c39920453d234dc0501b93218eb34c3fae541ad38ad36465
7
+ data.tar.gz: ee473164b0297a43f6034b25adb3e8d75e2dd275db33d2c3bf8fbd231cfb51720645569f0c2da1c96ef2f768a2cb67d53261c5f0342cbe2c79dca68375ed38fb
data/.rubocop.yml CHANGED
@@ -221,9 +221,9 @@ Metrics/BlockNesting:
221
221
  Max: 4
222
222
 
223
223
  Metrics/ClassLength:
224
- Description: 'Avoid classes longer than 250 lines of code.'
224
+ Description: 'Avoid classes longer than 350 lines of code.'
225
225
  Enabled: true
226
- Max: 250
226
+ Max: 350
227
227
 
228
228
  Metrics/CyclomaticComplexity:
229
229
  Description: >-
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ = 3.13.0 =
2
+
3
+ - Windows combatability
4
+ - Save screenshot using correct ext
5
+ - Allow integer build version
6
+ - Update Dependencies
7
+ - Code refactor
8
+ - Fixes for Test Suite
9
+
1
10
  = 3.12.8 =
2
11
 
3
12
  - Always print password/path from genkey
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- roku_builder (3.12.8)
4
+ roku_builder (3.13.0)
5
5
  faraday (~> 0.12)
6
6
  faraday-digestauth (~> 0.2)
7
7
  git (~> 1.3)
@@ -9,25 +9,28 @@ PATH
9
9
  net-telnet (~> 0.1)
10
10
  nokogiri (~> 1.7)
11
11
  rubyzip (~> 1.2)
12
+ win32-security (~> 0.5)
12
13
 
13
14
  GEM
14
15
  remote: https://rubygems.org/
15
16
  specs:
16
17
  byebug (9.0.6)
17
18
  coderay (1.1.1)
18
- coveralls (0.8.20)
19
+ coveralls (0.8.21)
19
20
  json (>= 1.8, < 3)
20
21
  simplecov (~> 0.14.1)
21
22
  term-ansicolor (~> 1.3)
22
23
  thor (~> 0.19.4)
23
24
  tins (~> 1.6)
24
25
  docile (1.1.5)
25
- faraday (0.12.0.1)
26
+ faraday (0.12.1)
26
27
  multipart-post (>= 1.2, < 3)
27
28
  faraday-digestauth (0.2.1)
28
29
  faraday (~> 0.7)
29
30
  net-http-digest_auth (~> 1.4)
30
- ffi (1.9.17)
31
+ ffi (1.9.18)
32
+ ffi-win32-extensions (1.0.3)
33
+ ffi
31
34
  formatador (0.2.5)
32
35
  git (1.3.0)
33
36
  guard (2.14.1)
@@ -43,18 +46,18 @@ GEM
43
46
  guard-minitest (2.4.6)
44
47
  guard-compat (~> 1.2)
45
48
  minitest (>= 3.0)
46
- json (2.0.3)
49
+ json (2.1.0)
47
50
  listen (3.1.5)
48
51
  rb-fsevent (~> 0.9, >= 0.9.4)
49
52
  rb-inotify (~> 0.9, >= 0.9.7)
50
53
  ruby_dep (~> 1.2)
51
- lumberjack (1.0.11)
54
+ lumberjack (1.0.12)
52
55
  m (1.5.0)
53
56
  method_source (>= 0.6.7)
54
57
  rake (>= 0.9.2.2)
55
58
  method_source (0.8.2)
56
59
  mini_portile2 (2.1.0)
57
- minitest (5.10.1)
60
+ minitest (5.10.2)
58
61
  minitest-autotest (1.0.3)
59
62
  minitest-server (~> 1.0)
60
63
  minitest-server (1.0.4)
@@ -64,7 +67,7 @@ GEM
64
67
  net-http-digest_auth (1.4.1)
65
68
  net-ping (2.0.1)
66
69
  net-telnet (0.1.1)
67
- nokogiri (1.7.1)
70
+ nokogiri (1.7.2)
68
71
  mini_portile2 (~> 2.1.0)
69
72
  notiffany (0.1.1)
70
73
  nenv (~> 0.1)
@@ -86,11 +89,14 @@ GEM
86
89
  simplecov-html (~> 0.10.0)
87
90
  simplecov-html (0.10.0)
88
91
  slop (3.6.0)
89
- term-ansicolor (1.5.0)
92
+ term-ansicolor (1.6.0)
90
93
  tins (~> 1.0)
91
94
  thor (0.19.4)
92
- tins (1.13.2)
93
- yard (0.9.8)
95
+ tins (1.14.0)
96
+ win32-security (0.5.0)
97
+ ffi
98
+ ffi-win32-extensions
99
+ yard (0.9.9)
94
100
 
95
101
  PLATFORMS
96
102
  ruby
data/bin/roku CHANGED
@@ -12,10 +12,6 @@ options = {}
12
12
  options[:config] = '~/.roku_config.json'
13
13
  options[:update_manifest] = false
14
14
 
15
- logger = Logger.new(STDOUT)
16
- logger.formatter = proc {|severity, datetime, _progname, msg|
17
- "[%s #%s] %5s: %s\n\r" % [datetime.strftime("%Y-%m-%d %H:%M:%S.%4N"), $$, severity, msg]
18
- }
19
15
 
20
16
  parser = OptionParser.new do |opts|
21
17
  opts.banner = "Usage: roku <command> [options]"
@@ -133,7 +129,7 @@ parser = OptionParser.new do |opts|
133
129
  options[:set_stage] = true
134
130
  end
135
131
 
136
- opts.on("-M", "--manifest-update", "Update the manifest file while packaging") do
132
+ opts.on("-M", "--manifest-update", "Update the manifest file while building or packaging") do
137
133
  options[:update_manifest] = true
138
134
  end
139
135
 
@@ -199,8 +195,8 @@ end
199
195
 
200
196
  begin
201
197
  parser.parse!
202
- RokuBuilder::Controller.run(options: options, logger: logger)
203
- rescue OptionParser::ParseError => e
204
- logger.fatal e.message
198
+ RokuBuilder::Controller.run(options: options)
199
+ rescue StandardError => e
200
+ RokuBuilder::Logger.instance.fatal e.message
205
201
  end
206
202
 
data/lib/roku_builder.rb CHANGED
@@ -10,6 +10,7 @@ require "net/ping"
10
10
  require "net/telnet"
11
11
  require "fileutils"
12
12
  require "tempfile"
13
+ require "tmpdir"
13
14
  require "zip"
14
15
  require "git"
15
16
  #config_manager
@@ -23,28 +24,13 @@ require 'io/console'
23
24
  #monitor
24
25
  require 'readline'
25
26
 
26
- require "roku_builder/controller"
27
- require "roku_builder/controller_commands"
28
- require "roku_builder/util"
29
- require "roku_builder/keyer"
30
- require "roku_builder/inspector"
31
- require "roku_builder/stager"
32
- require "roku_builder/loader"
33
- require "roku_builder/packager"
34
- require "roku_builder/linker"
35
- require "roku_builder/tester"
36
- require "roku_builder/scripter"
37
- require "roku_builder/profiler"
38
- require "roku_builder/manifest_manager"
39
- require "roku_builder/config_manager"
40
- require "roku_builder/config_validator"
41
- require "roku_builder/config_parser"
42
- require "roku_builder/error_handler"
43
- require "roku_builder/navigator"
44
- require "roku_builder/monitor"
45
- require "roku_builder/version"
46
-
47
- # Wrapping module for the Roku Builder Gem
27
+
28
+ require 'roku_builder/util'
29
+ Dir.glob(File.join(File.dirname(__FILE__), "roku_builder", "*")).each do |path|
30
+ file = "roku_builder/"+File.basename(path, ".rb")
31
+ require file unless file == "roku_builder/util"
32
+ end
33
+
48
34
  module RokuBuilder
49
35
 
50
36
  ### Global Codes ###
@@ -159,13 +145,19 @@ module RokuBuilder
159
145
  end
160
146
 
161
147
  class ::String
162
- def underscore
163
- word = self.dup
148
+ def underscore!
149
+ word = self
164
150
  word.gsub!(/::/, '/')
165
151
  word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
166
152
  word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
167
153
  word.tr!("-", "_")
168
154
  word.downcase!
155
+ nil
156
+ end
157
+
158
+ def underscore
159
+ word = self.dup
160
+ word.underscore!
169
161
  word
170
162
  end
171
163
  end
@@ -0,0 +1,213 @@
1
+ # ********** Copyright Viacom, Inc. Apache 2.0 **********
2
+
3
+ module RokuBuilder
4
+
5
+ # Load and validate config files.
6
+ class Config
7
+
8
+ attr_reader :parsed
9
+
10
+ def initialize(options:)
11
+ @options = options
12
+ @logger = Logger.instance
13
+ @config = nil
14
+ @parsed = nil
15
+ end
16
+
17
+ def raw
18
+ @config
19
+ end
20
+
21
+ def load
22
+ check_config_file
23
+ load_config
24
+ end
25
+
26
+ def parse
27
+ @parsed = ConfigParser.parse(options: @options, config: @config)
28
+ end
29
+
30
+ def validate
31
+ validator = ConfigValidator.new(config: @config)
32
+ validator.print_errors
33
+ raise InvalidConfig if validator.is_fatal?
34
+ end
35
+
36
+ def edit
37
+ load
38
+ apply_options
39
+ config_string = JSON.pretty_generate(@config)
40
+ file = File.open(@options[:config], "w")
41
+ file.write(config_string)
42
+ file.close
43
+ end
44
+
45
+ def update
46
+ if @options[:build_version]
47
+ update_package_config
48
+ update_build_config
49
+ update_sideload_config
50
+ update_inspect_config
51
+ end
52
+ end
53
+
54
+ def configure
55
+ if @options[:configure]
56
+ source_config = File.expand_path(File.join(File.dirname(__FILE__), "..", '..', 'config.json.example'))
57
+ target_config = File.expand_path(@options[:config])
58
+ if File.exist?(target_config)
59
+ unless @options[:edit_params]
60
+ raise InvalidOptions, "Not overwriting config. Add --edit options to do so."
61
+ end
62
+ end
63
+ FileUtils.copy(source_config, target_config)
64
+ edit if @options[:edit_params]
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def check_config_file
71
+ config_file = File.expand_path(@options[:config])
72
+ raise ArgumentError, "Missing Config" unless File.exist?(config_file)
73
+ end
74
+
75
+
76
+ def load_config
77
+ @config = {parent_config: @options[:config]}
78
+ depth = 1
79
+ while @config[:parent_config]
80
+ parent_config_hash = get_parent_config
81
+ @config[:child_config] = @config[:parent_config]
82
+ @config.delete(:parent_config)
83
+ @config.merge!(parent_config_hash) {|_key, v1, _v2| v1}
84
+ depth += 1
85
+ raise InvalidConfig, "Parent Configs Too Deep." if depth > 10
86
+ end
87
+ fix_config_symbol_values
88
+ end
89
+
90
+ def get_parent_config
91
+ begin
92
+ JSON.parse(parent_io.read, {symbolize_names: true})
93
+ rescue JSON::ParserError
94
+ raise InvalidConfig, "Config file is not valid JSON"
95
+ end
96
+ end
97
+
98
+ def parent_io
99
+ expand_parent_file_path
100
+ File.open(@config[:parent_config])
101
+ end
102
+
103
+ def expand_parent_file_path
104
+ if @config[:child_config]
105
+ @config[:parent_config] = File.expand_path(@config[:parent_config], File.dirname(@config[:child_config]))
106
+ else
107
+ @config[:parent_config] = File.expand_path(@config[:parent_config])
108
+ end
109
+ end
110
+
111
+ def fix_config_symbol_values
112
+ if @config[:devices]
113
+ @config[:devices][:default] = @config[:devices][:default].to_sym
114
+ end
115
+ if @config[:projects]
116
+ fix_project_config_symbol_values
117
+ build_inhearited_project_configs
118
+ end
119
+ end
120
+
121
+ def fix_project_config_symbol_values
122
+ @config[:projects][:default] = @config[:projects][:default].to_sym
123
+ @config[:projects].each_pair do |key,value|
124
+ next if is_skippable_project_key? key
125
+ if value[:stage_method]
126
+ value[:stage_method] = value[:stage_method].to_sym
127
+ end
128
+ end
129
+ end
130
+
131
+ def build_inhearited_project_configs
132
+ @config[:projects].each_pair do |key,value|
133
+ next if is_skippable_project_key? key
134
+ while value[:parent] and @config[:projects][value[:parent].to_sym]
135
+ new_value = @config[:projects][value[:parent].to_sym]
136
+ value.delete(:parent)
137
+ new_value = new_value.deep_merge value
138
+ @config[:projects][key] = new_value
139
+ value = new_value
140
+ end
141
+ end
142
+ end
143
+
144
+ def is_skippable_project_key?(key)
145
+ [:project_dir, :default].include?(key)
146
+ end
147
+
148
+ def build_edit_state
149
+ {
150
+ project: get_key_for(:project),
151
+ device: get_key_for(:device),
152
+ stage: get_stage_key(project: get_key_for(:project))
153
+ }
154
+ end
155
+
156
+ def get_key_for(type)
157
+ project = @options[type].to_sym if @options[type]
158
+ project ||= @config[(type.to_s+"s").to_sym][:default]
159
+ project
160
+ end
161
+
162
+ def get_stage_key(project:)
163
+ stage = @options[:stage].to_sym if @options[:stage]
164
+ stage ||= @config[:projects][project][:stages].keys[0].to_sym
165
+ stage
166
+ end
167
+
168
+ # Apply the changes in the options string to the config object
169
+ def apply_options
170
+ state = build_edit_state
171
+ changes = Util.options_parse(options: @options[:edit_params])
172
+ changes.each {|key,value|
173
+ if [:ip, :user, :password].include?(key)
174
+ @config[:devices][state[:device]][key] = value
175
+ elsif [:directory, :app_name].include?(key) #:folders, :files
176
+ @config[:projects][state[:project]][key] = value
177
+ elsif [:branch].include?(key)
178
+ @config[:projects][state[:project]][:stages][state[:stage]][key] = value
179
+ end
180
+ }
181
+ end
182
+
183
+ def update_package_config
184
+ if @parsed[:package_config]
185
+ @parsed[:package_config][:app_name_version] = "#{@parsed[:project_config][:app_name]} - #{@parsed[:stage]} - #{@options[:build_version]}"
186
+ @parsed[:package_config][:out_file] = out_file_path
187
+ end
188
+ end
189
+
190
+ def update_build_config
191
+ @parsed[:build_config][:out_file] = out_file_path if @parsed[:build_config]
192
+ end
193
+
194
+ def update_sideload_config
195
+ if @parsed[:sideload_config] and @options[:out]
196
+ @parsed[:sideload_config][:out_file] = out_file_path
197
+ end
198
+ end
199
+
200
+ def update_inspect_config
201
+ if @parsed[:inspect_config] and @parsed[:package_config]
202
+ @parsed[:inspect_config][:pkg] = @parsed[:package_config][:out_file]
203
+ end
204
+ end
205
+
206
+ def out_file_path
207
+ unless @parsed[:out][:file]
208
+ @parsed[:out][:file] = "#{@parsed[:project_config][:app_name]}_#{@parsed[:stage]}_#{@options[:build_version]}"
209
+ end
210
+ File.join(@parsed[:out][:folder], @parsed[:out][:file])
211
+ end
212
+ end
213
+ end
@@ -2,312 +2,349 @@
2
2
 
3
3
  module RokuBuilder
4
4
 
5
- # Contains methods that will parse the loaded config and generate
6
- # intermeidate configs for each of the tools.
7
5
  class ConfigParser
8
6
 
9
- # Parse config and generate intermeidate configs
10
- # @param options [Hash] The options hash
11
- # @param config [Hash] The loaded config hash
12
- # @param logger [Logger] system logger
13
- # @return [Integer] Return code
14
- # @return [Hash] Intermeidate configs
15
- def self.parse_config(options:, config:, logger:)
16
- configs = {init_params: {}}
17
- #expand in
18
- options[:in] = File.expand_path(options[:in]) if options[:in]
19
- #set device
20
- options[:device] = config[:devices][:default] unless options[:device]
21
- #set project
22
- setup_project(config: config, options: options) if project_required(options: options)
23
- #set outfile
24
- setup_outfile(options: options, configs: configs)
25
- # Create Device Config
26
- configs[:device_config] = config[:devices][options[:device].to_sym]
27
- return [UNKNOWN_DEVICE, nil, nil] unless configs[:device_config]
28
- configs[:device_config][:logger] = logger
29
- project_config = setup_project_config(config: config, options: options)
30
- return [project_config, nil, nil] unless project_config.class == Hash
31
- configs[:project_config] = project_config
32
- stage = setup_stage_config(configs: configs, options: options, logger: logger)[1]
33
- return [UNKNOWN_STAGE, nil, nil] if stage.nil? and project_required(options: options)
34
- setup_sideload_config(configs: configs, options: options)
35
- code = setup_package_config(config: config, configs: configs, options: options, stage: stage)
36
- return [code, nil, nil] unless code == SUCCESS
37
- setup_active_configs(config: config, configs: configs, options: options)
38
- setup_manifest_configs(configs: configs, options: options)
39
- setup_simple_configs(config: config, configs: configs, options: options)
40
- return [SUCCESS, configs]
41
- end
42
-
43
- # Pick or choose the project being used
44
- # @param config [Hash] The loaded config hash
45
- # @param options [Hash] The options hash
46
- def self.setup_project(config:, options:)
47
- unless options[:project]
48
- path = Pathname.pwd
49
- project = nil
50
- config[:projects].each_pair {|key,value|
51
- if value.is_a?(Hash)
52
- repo_path = ""
53
- if config[:projects][:project_dir]
54
- repo_path = Pathname.new(File.join(config[:projects][:project_dir], value[:directory])).realdirpath
55
- else
56
- repo_path = Pathname.new(value[:directory]).realdirpath
57
- end
58
- path.descend do |path_parent|
59
- if path_parent == repo_path
60
- project = key
61
- break
62
- end
63
- end
64
- break if project
65
- end
66
- }
7
+ attr_reader :parsed
8
+
9
+ def self.parse(options:, config:)
10
+ parser = new(options: options, config: config)
11
+ parser.parsed
12
+ end
13
+
14
+ def initialize(options:, config:)
15
+ @logger = Logger.instance
16
+ @options = options
17
+ @config = config
18
+ @parsed = {init_params: {}}
19
+ parse_config
20
+ end
21
+
22
+ def parse_config
23
+ process_in_argument
24
+ setup_device
25
+ setup_project
26
+ setup_outfile
27
+ setup_project_config
28
+ setup_stage_config
29
+ setup_sideload_config
30
+ setup_package_config
31
+ setup_monitor_configs
32
+ setup_navigate_configs
33
+ setup_manifest_config
34
+ setup_deeplink_configs
35
+ setup_text_configs
36
+ setup_test_configs
37
+ setup_screencapture_configs
38
+ setup_screen_config
39
+ setup_profiler_configs
40
+ setup_genkey_configs
41
+ end
42
+
43
+ def process_in_argument
44
+ @options[:in] = File.expand_path(@options[:in]) if @options[:in]
45
+ end
46
+
47
+ def setup_device
48
+ @options[:device] = @config[:devices][:default] unless @options[:device]
49
+ @parsed[:device_config] = @config[:devices][@options[:device].to_sym]
50
+ raise ArgumentError, "Unknown device: #{@options[:device]}" unless @parsed[:device_config]
51
+ end
52
+
53
+ def setup_project
54
+ if project_required and not @options[:project]
55
+ project = current_project
67
56
  if project
68
- options[:project] = project
57
+ @options[:project] = project
69
58
  else
70
- options[:project] = config[:projects][:default]
59
+ @options[:project] = @config[:projects][:default]
71
60
  end
72
61
  end
73
62
  end
74
- private_class_method :setup_project
75
-
76
- # Setup the out folder/file options
77
- # @param options [Hash] The options hash
78
- def self.setup_outfile(options:, configs:)
79
- configs[:out] = {file: nil, folder: nil}
80
- if options[:out]
81
- if options[:out].end_with?(".zip") or options[:out].end_with?(".pkg") or options[:out].end_with?(".jpg")
82
- configs[:out][:folder], configs[:out][:file] = Pathname.new(options[:out]).split.map{|p| p.to_s}
83
- if configs[:out][:folder] == "." and not options[:out].start_with?(".")
84
- configs[:out][:folder] = nil
85
- else
86
- configs[:out][:folder] = File.expand_path(configs[:out][:folder])
87
- end
63
+
64
+ def project_required
65
+ non_project_source = ([:current, :in] & @options.keys).count > 0
66
+ @options.source_command? and not non_project_source
67
+ end
68
+
69
+ def current_project
70
+ @config[:projects].each_pair do |key,value|
71
+ return key if is_current_project?(project_config: value)
72
+ end
73
+ nil
74
+ end
75
+
76
+ def is_current_project?(project_config:)
77
+ return false unless project_config.is_a?(Hash)
78
+ repo_path = get_repo_path(project_config: project_config)
79
+ Pathname.pwd.descend do |path_parent|
80
+ return true if path_parent == repo_path
81
+ end
82
+ end
83
+
84
+ def get_repo_path(project_config:)
85
+ if @config[:projects][:project_dir]
86
+ Pathname.new(File.join(@config[:projects][:project_dir], project_config[:directory])).realdirpath
87
+ else
88
+ Pathname.new(project_config[:directory]).realdirpath
89
+ end
90
+ end
91
+
92
+ def setup_outfile
93
+ @parsed[:out] = {file: nil, folder: nil}
94
+ if @options[:out]
95
+ if out_file_defined?
96
+ setup_outfile_and_folder
88
97
  else
89
- configs[:out][:folder] = options[:out]
98
+ @parsed[:out][:folder] = @options[:out]
90
99
  end
91
100
  end
92
- unless configs[:out][:folder]
93
- configs[:out][:folder] = "/tmp"
101
+ set_default_outfile
102
+ end
103
+
104
+ def out_file_defined?
105
+ @options[:out].end_with?(".zip") or @options[:out].end_with?(".pkg") or @options[:out].end_with?(".jpg")
106
+ end
107
+
108
+ def setup_outfile_and_folder
109
+ @parsed[:out][:folder], @parsed[:out][:file] = Pathname.new(@options[:out]).split.map{|p| p.to_s}
110
+ if @parsed[:out][:folder] == "." and not @options[:out].start_with?(".")
111
+ @parsed[:out][:folder] = nil
112
+ else
113
+ @parsed[:out][:folder] = File.expand_path(@parsed[:out][:folder])
114
+ end
115
+ end
116
+
117
+ def set_default_outfile
118
+ unless @parsed[:out][:folder]
119
+ @parsed[:out][:folder] = Dir.tmpdir
94
120
  end
95
121
  end
96
- private_class_method :setup_outfile
97
-
98
- # Setup the project config with the chosen project
99
- # @param config [Hash] The loaded config hash
100
- # @param options [Hash] The options hash
101
- # @return [Hash] The project config hash
102
- def self.setup_project_config(config:, options:)
103
- #Create Project Config
104
- project_config = {}
105
- if options[:current]
106
- pwd = Pathname.pwd.to_s
107
- return MISSING_MANIFEST unless File.exist?(File.join(pwd, "manifest"))
108
- project_config = {
109
- directory: pwd,
110
- folders: nil,
111
- files: nil,
112
- stage_method: :current
113
- }
114
- elsif project_required(options: options)
115
- project_config = config[:projects][options[:project].to_sym]
116
- return UNKNOWN_PROJECT unless project_config
117
- if config[:projects][:project_dir]
118
- project_config[:directory] = File.join(config[:projects][:project_dir], project_config[:directory])
119
- end
120
- return BAD_PROJECT_DIR unless Dir.exist?(project_config[:directory])
121
- project_config[:stage_method] = :working if options[:working]
122
+
123
+ def setup_project_config
124
+ if @options[:current]
125
+ stub_project_config_for_current
126
+ elsif project_required
127
+ @parsed[:project_config] = @config[:projects][@options[:project].to_sym]
128
+ raise ParseError, "Unknown Project: #{@options[:project]}" unless @parsed[:project_config]
129
+ set_project_directory
130
+ check_for_working
122
131
  end
123
- project_config
124
- end
125
- private_class_method :setup_project_config
126
-
127
- # Determine whether a project is required
128
- # @param options [Hash] The options hash
129
- # @return [Boolean] Whether a project is required or not
130
- def self.project_required(options:)
131
- has_source_command = (Controller.source_commands & options.keys).count > 0
132
- non_project_source = ([:current, :in] & options.keys).count > 0
133
- has_source_command and not non_project_source
134
- end
135
- private_class_method :project_required
136
-
137
- # Setup the project stage config
138
- # @param configs [Hash] The loaded config hash
139
- # @param options [Hash] The options hash
140
- # @return [Hash] The stage config hash
141
- def self.setup_stage_config(configs:, options:, logger:)
142
- stage_config = {logger: logger}
143
- stage_config[:method] = ([:in, :current] & options.keys).first
144
- stage = options[:stage].to_sym if options[:stage]
145
- if project_required(options: options)
146
- project_config = configs[:project_config]
147
- stage ||= project_config[:stages].keys[0].to_sym
148
- options[:stage] = stage
149
- stage_config[:root_dir] = project_config[:directory]
150
- stage_config[:method] = project_config[:stage_method]
151
- stage_config[:method] ||= :git
152
- case stage_config[:method]
153
- when :git
154
- if options[:ref]
155
- stage_config[:key] = options[:ref]
156
- else
157
- return [nil, nil] unless project_config[:stages][stage]
158
- stage_config[:key] = project_config[:stages][stage][:branch]
159
- end
160
- when :script
161
- return [nil, nil] unless project_config[:stages][stage]
162
- stage_config[:key] = project_config[:stages][stage][:script]
163
- end
132
+ end
133
+
134
+ def stub_project_config_for_current
135
+ pwd = Pathname.pwd.to_s
136
+ raise ParseError, "Missing Manifest" unless File.exist?(File.join(pwd, "manifest"))
137
+ @parsed[:project_config] = {
138
+ directory: pwd,
139
+ folders: nil,
140
+ files: nil,
141
+ stage_method: :current
142
+ }
143
+ end
144
+
145
+ def set_project_directory
146
+ if @config[:projects][:project_dir]
147
+ @parsed[:project_config][:directory] = File.join(@config[:projects][:project_dir], @parsed[:project_config][:directory])
164
148
  end
165
- configs[:stage_config] = stage_config
166
- configs[:stage] = stage
167
- [stage_config, stage]
168
- end
169
-
170
- # Setup config hashes for sideloading
171
- # @param configs [Hash] The parsed configs hash
172
- # @param options [Hash] The options hash
173
- # @param branch [String] the branch to sideload
174
- def self.setup_sideload_config(configs:, options:)
175
- root_dir, content = nil, nil
176
- if configs[:project_config]
177
- root_dir = configs[:project_config][:directory]
178
- content = {
179
- folders: configs[:project_config][:folders],
180
- files: configs[:project_config][:files],
181
- }
182
- all_commands = options.keys & Controller.commands
183
- if options[:exclude] or Controller.exclude_commands.include?(all_commands.first)
184
- content[:excludes] = configs[:project_config][:excludes]
149
+ unless Dir.exist?(@parsed[:project_config][:directory])
150
+ raise ParseError, "Missing project dirtectory: #{@parsed[:project_config][:dirtectory]}"
151
+ end
152
+ end
153
+
154
+ def check_for_working
155
+ @parsed[:project_config][:stage_method] = :working if @options[:working]
156
+ end
157
+
158
+
159
+ def setup_stage_config
160
+ setup_mininal_stage_configs
161
+ setup_project_stage_config if project_required
162
+ end
163
+
164
+ def setup_mininal_stage_configs
165
+ @parsed[:stage_config] = {}
166
+ @parsed[:stage_config][:method] = ([:in, :current] & @options.keys).first
167
+ @parsed[:stage] = @options[:stage].to_sym if @options[:stage]
168
+ end
169
+
170
+ def setup_project_stage_config
171
+ @parsed[:stage] ||= @parsed[:project_config][:stages].keys[0].to_sym
172
+ @parsed[:stage_config][:root_dir] = @parsed[:project_config][:directory]
173
+ raise ParseError, "Unknown Stage: #{@parsed[:stage]}" unless @parsed[:project_config][:stages][@parsed[:stage]]
174
+ setup_staging_method
175
+ setup_staging_key
176
+ end
177
+
178
+ def setup_staging_method
179
+ @parsed[:stage_config][:method] = @parsed[:project_config][:stage_method]
180
+ unless [:git, :script, :current, :working].include? @parsed[:stage_config][:method]
181
+ raise ParseError, "Unknown Stage Method: #{@parsed[:stage_config][:method]}"
182
+ end
183
+ end
184
+
185
+ def setup_staging_key
186
+ case @parsed[:stage_config][:method]
187
+ when :git
188
+ if @options[:ref]
189
+ @parsed[:stage_config][:key] = @options[:ref]
190
+ else
191
+ @parsed[:stage_config][:key] = @parsed[:project_config][:stages][@parsed[:stage]][:branch]
185
192
  end
193
+ when :script
194
+ @parsed[:stage_config][:key] = @parsed[:project_config][:stages][@parsed[:stage]][:script]
186
195
  end
196
+ end
197
+
198
+ def setup_sideload_config
199
+ root_dir, content = setup_project_values
187
200
  # Create Sideload Config
188
- configs[:sideload_config] = {
189
- update_manifest: options[:update_manifest],
190
- infile: options[:in],
201
+ @parsed[:sideload_config] = {
202
+ update_manifest: @options[:update_manifest],
203
+ infile: @options[:in],
191
204
  content: content
192
205
  }
193
206
  # Create Build Config
194
- configs[:build_config] = { content: content }
195
- configs[:init_params][:loader] = { root_dir: root_dir }
196
- end
197
- private_class_method :setup_sideload_config
198
-
199
- # Setup config hashes for packaging
200
- # @param configs [Hash] The parsed configs hash
201
- # @param options [Hash] The options hash
202
- # @param stage [Symbol] The stage to package
203
- def self.setup_package_config(config:, configs:, options:, stage:)
204
- if options[:package] or options[:key]
205
- # Create Key Config
206
- configs[:key] = configs[:project_config][:stages][stage][:key]
207
- if configs[:key].class == String
208
- configs[:key] = config[:keys][configs[:key].to_sym]
209
- if config[:keys][:key_dir]
210
- configs[:key][:keyed_pkg] = File.join(config[:keys][:key_dir], configs[:key][:keyed_pkg])
211
- end
212
- return BAD_KEY_FILE unless File.exist?(configs[:key][:keyed_pkg])
213
- end
214
- end
215
- if options[:package]
216
- # Create Package Config
217
- configs[:package_config] = {
218
- password: configs[:key][:password],
219
- app_name_version: "#{configs[:project_config][:app_name]} - #{stage}"
220
- }
221
- # Create Inspector Config
222
- configs[:inspect_config] = {
223
- password: configs[:key][:password]
207
+ @parsed[:build_config] = { content: content }
208
+ @parsed[:init_params][:loader] = { root_dir: root_dir }
209
+ end
210
+
211
+ def setup_project_values
212
+ if @parsed[:project_config]
213
+ root_dir = @parsed[:project_config][:directory]
214
+ content = {
215
+ folders: @parsed[:project_config][:folders],
216
+ files: @parsed[:project_config][:files],
224
217
  }
225
- if configs[:out][:file]
226
- configs[:package_config][:out_file] = File.join(configs[:out][:folder], configs[:out][:file])
227
- configs[:inspect_config][:pkg] = File.join(configs[:out][:folder], configs[:out][:file])
228
- end
218
+ content[:excludes] = @parsed[:project_config][:excludes] if add_excludes?
219
+ [root_dir, content]
220
+ else
221
+ [nil, nil]
222
+ end
223
+ end
224
+
225
+ def add_excludes?
226
+ @options[:exclude] or @options.exclude_command?
227
+ end
228
+
229
+ def setup_package_config
230
+ setup_key_config if @options[:package] or @options[:key]
231
+ if @options[:package]
232
+ setup_package_config_hashes
233
+ setup_package_config_out_files
234
+ end
235
+ end
236
+
237
+ def setup_key_config
238
+ @parsed[:key] = @parsed[:project_config][:stages][@parsed[:stage]][:key]
239
+ get_global_key_config if @parsed[:key].class == String
240
+ end
241
+
242
+ def get_global_key_config
243
+ raise ParseError, "Unknown Key: #{@parsed[:key]}" unless @config[:keys][@parsed[:key].to_sym]
244
+ @parsed[:key] = @config[:keys][@parsed[:key].to_sym]
245
+ if @config[:keys][:key_dir]
246
+ @parsed[:key][:keyed_pkg] = File.join(@config[:keys][:key_dir], @parsed[:key][:keyed_pkg])
229
247
  end
230
- return SUCCESS
231
- end
232
- private_class_method :setup_package_config
233
-
234
- # Setup configs for active methods, monitoring and navigating
235
- # @param configs [Hash] The parsed configs hash
236
- # @param options [Hash] The options hash
237
- # @param logger [Logger] System logger
238
- def self.setup_active_configs(config:, configs:, options:)
239
- # Create Monitor Config
240
- if options[:monitor]
241
- configs[:monitor_config] = {type: options[:monitor].to_sym}
242
- if options[:regexp]
243
- configs[:monitor_config][:regexp] = /#{options[:regexp]}/
248
+ unless File.exist?(@parsed[:key][:keyed_pkg])
249
+ raise ParseError, "Bad key file: #{@parsed[:key][:keyed_pkg]}"
250
+ end
251
+ end
252
+
253
+ def setup_package_config_hashes
254
+ @parsed[:package_config] = {
255
+ password: @parsed[:key][:password],
256
+ app_name_version: "#{@parsed[:project_config][:app_name]} - #{@parsed[:stage]}"
257
+ }
258
+ @parsed[:inspect_config] = {
259
+ password: @parsed[:key][:password]
260
+ }
261
+ end
262
+
263
+ def setup_package_config_out_files
264
+ if @parsed[:out][:file]
265
+ @parsed[:package_config][:out_file] = File.join(@parsed[:out][:folder], @parsed[:out][:file])
266
+ @parsed[:inspect_config][:pkg] = File.join(@parsed[:out][:folder], @parsed[:out][:file])
267
+ end
268
+ end
269
+
270
+ def setup_monitor_configs
271
+ if @options[:monitor]
272
+ @parsed[:monitor_config] = {type: @options[:monitor].to_sym}
273
+ if @options[:regexp]
274
+ @parsed[:monitor_config][:regexp] = /#{@options[:regexp]}/
244
275
  end
245
276
  end
246
- # Create Navigate Config
277
+ end
278
+
279
+ def setup_navigate_configs
280
+ @parsed[:init_params][:navigator] = {mappings: generate_maggings}
281
+ if @options[:navigate]
282
+ @parsed[:navigate_config] = {
283
+ commands: @options[:navigate].split(/, */).map{|c| c.to_sym}
284
+ }
285
+ end
286
+ end
287
+
288
+ def generate_maggings
247
289
  mappings = {}
248
- if config[:input_mapping]
249
- config[:input_mapping].each_pair {|key, value|
290
+ if @config[:input_mapping]
291
+ @config[:input_mapping].each_pair {|key, value|
250
292
  unless "".to_sym == key
251
293
  key = key.to_s.sub(/\\e/, "\e").to_sym
252
294
  mappings[key] = value
253
295
  end
254
296
  }
255
297
  end
256
- configs[:init_params][:navigator] = {mappings: mappings}
257
- if options[:navigate]
258
- commands = options[:navigate].split(/, */).map{|c| c.to_sym}
259
- configs[:navigate_config] = {commands: commands}
260
- end
298
+ mappings
261
299
  end
262
- private_class_method :setup_active_configs
263
-
264
- # Setup manifest configs
265
- # @param configs [Hash] The parsed configs hash
266
- # @param options [Hash] The options hash
267
- # @param logger [Logger] System logger
268
- def self.setup_manifest_configs(configs:, options:)
269
- # Create Manifest Config
270
- root_dir = configs[:project_config][:directory] if configs[:project_config]
271
- root_dir = options[:in] if options[:in]
272
- root_dir = Pathname.pwd.to_s if options[:current]
273
- configs[:manifest_config] = {
274
- root_dir: root_dir
300
+
301
+ def setup_manifest_config
302
+ @parsed[:manifest_config] = {
303
+ root_dir: get_root_dir
275
304
  }
276
305
  end
277
- private_class_method :setup_manifest_configs
278
-
279
- # Setup other configs
280
- # @param configs [Hash] The parsed configs hash
281
- # @param options [Hash] The options hash
282
- # @param logger [Logger] System logger
283
- def self.setup_simple_configs(config:, configs:, options:)
284
- # Create Deeplink Config
285
- configs[:deeplink_config] = {options: options[:deeplink]}
286
- if options[:app_id]
287
- configs[:deeplink_config][:app_id] = options[:app_id]
306
+
307
+ def get_root_dir
308
+ root_dir = @parsed[:project_config][:directory] if @parsed[:project_config]
309
+ root_dir = @options[:in] if @options[:in]
310
+ root_dir = Pathname.pwd.to_s if @options[:current]
311
+ root_dir
312
+ end if
313
+
314
+ def setup_deeplink_configs
315
+ @parsed[:deeplink_config] = {options: @options[:deeplink]}
316
+ if @options[:app_id]
317
+ @parsed[:deeplink_config][:app_id] = @options[:app_id]
288
318
  end
289
- # Create Text Config
290
- configs[:text_config] = {text: options[:text]}
291
- # Create Test Config
292
- configs[:test_config] = {sideload_config: configs[:sideload_config]}
293
- #Create screencapture config
294
- configs[:screencapture_config] = {
295
- out_folder: configs[:out][:folder],
296
- out_file: configs[:out][:file]
319
+ end
320
+ def setup_text_configs
321
+ @parsed[:text_config] = {text: @options[:text]}
322
+ end
323
+ def setup_test_configs
324
+ @parsed[:test_config] = {sideload_config: @parsed[:sideload_config]}
325
+ @parsed[:init_params][:tester] = { root_dir: get_root_dir }
326
+ end
327
+ def setup_screencapture_configs
328
+ @parsed[:screencapture_config] = {
329
+ out_folder: @parsed[:out][:folder],
330
+ out_file: @parsed[:out][:file]
297
331
  }
298
- if options[:screen]
299
- configs[:screen_config] = {type: options[:screen].to_sym}
332
+ end
333
+ def setup_screen_config
334
+ if @options[:screen]
335
+ @parsed[:screen_config] = {type: @options[:screen].to_sym}
300
336
  end
301
- #Create Profiler Config
302
- if options[:profile]
303
- configs[:profiler_config] = {command: options[:profile].to_sym}
337
+ end
338
+ def setup_profiler_configs
339
+ if @options[:profile]
340
+ @parsed[:profiler_config] = {command: @options[:profile].to_sym}
304
341
  end
305
- #Create genkey config
306
- configs[:genkey] = {}
307
- if options[:out_file]
308
- configs[:genkey][:out_file] = File.join(options[:out_folder], options[:out_file])
342
+ end
343
+ def setup_genkey_configs
344
+ @parsed[:genkey] = {}
345
+ if @options[:out_file]
346
+ @parsed[:genkey][:out_file] = File.join(@options[:out_folder], @options[:out_file])
309
347
  end
310
348
  end
311
- private_class_method :setup_simple_configs
312
349
  end
313
350
  end