roku_builder 3.12.8 → 3.13.0

Sign up to get free protection for your applications and to get access to all the features.
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