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
@@ -22,7 +22,6 @@ module RokuBuilder
22
22
  genkey: { klass: Keyer, method: :genkey, config_key: :genkey },
23
23
  screens: { klass: Navigator, method: :screens },
24
24
  text: { klass: Navigator, method: :type, config_key: :text_config },
25
- test: { klass: Tester, method: :run_tests, config_key: :test_config },
26
25
  screencapture: { klass: Inspector, method: :screencapture, config_key: :screencapture_config,
27
26
  failure: FAILED_SCREENCAPTURE },
28
27
  applist: {klass: Linker, method: :list},
@@ -30,74 +29,86 @@ module RokuBuilder
30
29
  }
31
30
  end
32
31
  # Validate Config
33
- # @param logger [Logger] system logger
34
32
  # @return [Integer] Success or Failure Code
35
- def self.validate(logger:)
36
- logger.info "Config validated"
33
+ def self.validate()
34
+ Logger.instance.info "Config validated"
37
35
  SUCCESS
38
36
  end
39
37
  # Run Sideload
40
38
  # @param options [Hash] user options
41
- # @param configs [Hash] parsed configs
42
- # @param logger [Logger] system logger
39
+ # @param config [Config] parsed config
43
40
  # @return [Integer] Success or Failure Code
44
- def self.sideload(options:, configs:, logger:)
45
- config = configs[:device_config].dup
46
- config[:init_params] = configs[:init_params][:loader]
47
- stager = Stager.new(**configs[:stage_config])
41
+ def self.sideload(options:, config:)
42
+ device_config = config.parsed[:device_config].dup
43
+ device_config[:init_params] = config.parsed[:init_params][:loader]
44
+ stager = Stager.new(**config.parsed[:stage_config])
48
45
  success = nil
49
46
  if stager.stage
50
- loader = Loader.new(**config)
51
- build_version = ManifestManager.build_version(**configs[:manifest_config])
47
+ loader = Loader.new(**device_config)
48
+ build_version = ManifestManager.build_version(**config.parsed[:manifest_config])
52
49
  options[:build_version] = build_version
53
- configs = ConfigManager.update_configs(configs: configs, options: options)
54
- success = loader.sideload(**configs[:sideload_config])[0]
50
+ config.update
51
+ success = loader.sideload(**config.parsed[:sideload_config])[0]
55
52
  end
56
53
  stager.unstage
57
54
  if success == SUCCESS
58
- logger.info "App Sideloaded; staged using #{stager.method}"
55
+ Logger.instance.info "App Sideloaded; staged using #{stager.method}"
59
56
  end
60
57
  success
61
58
  end
62
59
  # Run Package
63
60
  # @param options [Hash] user options
64
- # @param configs [Hash] parsed configs
65
- # @param logger [Logger] system logger
61
+ # @param config [Conifg] config object
66
62
  # @return [Integer] Success or Failure Code
67
- def self.package(options:, configs:, logger:)
68
- loader_config = configs[:device_config].dup
69
- loader_config[:init_params] = configs[:init_params][:loader]
70
- keyer = Keyer.new(**configs[:device_config])
71
- stager = Stager.new(**configs[:stage_config])
63
+ def self.package(options:, config:)
64
+ loader_config = config.parsed[:device_config].dup
65
+ loader_config[:init_params] = config.parsed[:init_params][:loader]
66
+ keyer = Keyer.new(**config.parsed[:device_config])
67
+ stager = Stager.new(**config.parsed[:stage_config])
72
68
  loader = Loader.new(**loader_config)
73
- packager = Packager.new(**configs[:device_config])
74
- logger.warn "Packaging working directory" if options[:working]
69
+ packager = Packager.new(**config.parsed[:device_config])
70
+ Logger.instance.warn "Packaging working directory" if options[:working]
75
71
  if stager.stage
76
72
  # Sideload #
77
- code, build_version = loader.sideload(**configs[:sideload_config])
73
+ code, build_version = loader.sideload(**config.parsed[:sideload_config])
78
74
  return code unless code == SUCCESS
79
75
  # Key #
80
- _success = keyer.rekey(**configs[:key])
76
+ _success = keyer.rekey(**config.parsed[:key])
81
77
  # Package #
82
78
  options[:build_version] = build_version
83
- configs = ConfigManager.update_configs(configs: configs, options: options)
84
- success = packager.package(**configs[:package_config])
85
- logger.info "Signing Successful: #{configs[:package_config][:out_file]}" if success
79
+ config.update
80
+ success = packager.package(**config.parsed[:package_config])
81
+ Logger.instance.info "Signing Successful: #{config.parsed[:package_config][:out_file]}" if success
86
82
  return FAILED_SIGNING unless success
87
83
  # Inspect #
88
84
  if options[:inspect]
89
- inspect_package(configs: configs)
85
+ inspect_package(config: config)
90
86
  end
91
87
  end
92
88
  stager.unstage
93
- logger.info "App Packaged; staged using #{stager.method}"
89
+ Logger.instance.info "App Packaged; staged using #{stager.method}"
90
+ SUCCESS
91
+ end
92
+ # Run Sideload
93
+ # @param options [Hash] user options
94
+ # @param config [Config] parsed config
95
+ # @return [Integer] Success or Failure Code
96
+ def self.test(options:, config:)
97
+ device_config = config.parsed[:device_config].dup
98
+ device_config[:init_params] = config.parsed[:init_params][:tester]
99
+ stager = Stager.new(**config.parsed[:stage_config])
100
+ if stager.stage
101
+ tester = Tester.new(**device_config)
102
+ tester.run_tests(**config.parsed[:test_config])
103
+ end
104
+ stager.unstage
94
105
  SUCCESS
95
106
  end
96
107
 
97
- def self.inspect_package(configs:)
98
- inspector = Inspector.new(**configs[:device_config])
99
- info = inspector.inspect(configs[:inspect_config])
100
- inspect_logger = Logger.new(STDOUT)
108
+ def self.inspect_package(config:)
109
+ inspector = Inspector.new(**config.parsed[:device_config])
110
+ info = inspector.inspect(config.parsed[:inspect_config])
111
+ inspect_logger = ::Logger.new(STDOUT)
101
112
  inspect_logger.formatter = proc {|_severity, _datetime, _progname, msg|
102
113
  "%s\n\r" % [msg]
103
114
  }
@@ -112,37 +123,35 @@ module RokuBuilder
112
123
 
113
124
  # Run Build
114
125
  # @param options [Hash] user options
115
- # @param configs [Hash] parsed configs
116
- # @param logger [Logger] system logger
126
+ # @param config [Config] config object
117
127
  # @return [Integer] Success or Failure Code
118
- def self.build(options:, configs:, logger:)
128
+ def self.build(options:, config:)
119
129
  ### Build ###
120
- loader_config = configs[:device_config].dup
121
- loader_config[:init_params] = configs[:init_params][:loader]
122
- stager = Stager.new(**configs[:stage_config])
130
+ loader_config = config.parsed[:device_config].dup
131
+ loader_config[:init_params] = config.parsed[:init_params][:loader]
132
+ stager = Stager.new(**config.parsed[:stage_config])
123
133
  loader = Loader.new(**loader_config)
124
134
  if stager.stage
125
- build_version = ManifestManager.build_version(**configs[:manifest_config])
135
+ build_version = ManifestManager.build_version(**config.parsed[:manifest_config])
126
136
  options[:build_version] = build_version
127
- configs = ConfigManager.update_configs(configs: configs, options: options)
128
- outfile = loader.build(**configs[:build_config])
129
- logger.info "Build: #{outfile}"
137
+ config.update
138
+ outfile = loader.build(**config.parsed[:build_config])
139
+ Logger.instance.info "Build: #{outfile}"
130
140
  end
131
141
  stager.unstage
132
- logger.info "App build; staged using #{stager.method}"
142
+ Logger.instance.info "App build; staged using #{stager.method}"
133
143
  SUCCESS
134
144
  end
135
145
  # Run update
136
- # @param configs [Hash] parsed configs
137
- # @param logger [Logger] system logger
146
+ # @param config [Config] config object
138
147
  # @return [Integer] Success or Failure Code
139
- def self.update(configs:, logger:)
148
+ def self.update(config:)
140
149
  ### Update ###
141
- stager = Stager.new(**configs[:stage_config])
150
+ stager = Stager.new(**config.parsed[:stage_config])
142
151
  if stager.stage
143
- old_version = ManifestManager.build_version(**configs[:manifest_config])
144
- new_version = ManifestManager.update_build(**configs[:manifest_config])
145
- logger.info "Update build version from:\n#{old_version}\nto:\n#{new_version}"
152
+ old_version = ManifestManager.build_version(**config.parsed[:manifest_config])
153
+ new_version = ManifestManager.update_build(**config.parsed[:manifest_config])
154
+ Logger.instance.info "Update build version from:\n#{old_version}\nto:\n#{new_version}"
146
155
  end
147
156
  stager.unstage
148
157
  SUCCESS
@@ -150,17 +159,15 @@ module RokuBuilder
150
159
 
151
160
  # Run Deeplink
152
161
  # @param options [Hash] user options
153
- # @param configs [Hash] parsed configs
154
- # @param logger [Logger] system logger
155
- def self.deeplink(options:, configs:, logger:)
156
- sources = options.keys & Controller.sources
157
- if sources.count > 0
158
- sideload(options: options, configs: configs, logger:logger)
162
+ # @param config [Config] config object
163
+ def self.deeplink(options:, config:)
164
+ if options.has_source?
165
+ sideload(options: options, config: config)
159
166
  end
160
167
 
161
- linker = Linker.new(configs[:device_config])
162
- if linker.launch(configs[:deeplink_config])
163
- logger.info "Deeplinked into app"
168
+ linker = Linker.new(config.parsed[:device_config])
169
+ if linker.launch(config.parsed[:deeplink_config])
170
+ Logger.instance.info "Deeplinked into app"
164
171
  return SUCCESS
165
172
  else
166
173
  return FAILED_DEEPLINKING
@@ -169,24 +176,24 @@ module RokuBuilder
169
176
 
170
177
  # Run Print
171
178
  # @param options [Hash] user options
172
- # @param configs [Hash] parsed configs
173
- def self.print(options:, configs:)
174
- stager = Stager.new(**configs[:stage_config])
179
+ # @param config [Config] config object
180
+ def self.print(options:, config:)
181
+ stager = Stager.new(**config.parsed[:stage_config])
175
182
  code = nil
176
183
  if stager.stage
177
- code = Scripter.print(attribute: options[:print].to_sym, configs: configs)
184
+ code = Scripter.print(attribute: options[:print].to_sym, configs: config.parsed)
178
185
  end
179
186
  stager.unstage
180
187
  code
181
188
  end
182
189
 
183
- def self.dostage(configs:)
184
- stager = Stager.new(**configs[:stage_config])
190
+ def self.dostage(config:)
191
+ stager = Stager.new(**config.parsed[:stage_config])
185
192
  stager.stage
186
193
  end
187
194
 
188
- def self.dounstage(configs:)
189
- stager = Stager.new(**configs[:stage_config])
195
+ def self.dounstage(config:)
196
+ stager = Stager.new(**config.parsed[:stage_config])
190
197
  stager.unstage
191
198
  end
192
199
 
@@ -194,24 +201,23 @@ module RokuBuilder
194
201
  # @param klass [Class] class of object to create
195
202
  # @param method [Symbol] methog to run on klass
196
203
  # @param config_key [Symbol] config to send from configs if not nil
197
- # @param configs [Hash] parsed roku config
204
+ # @param config [Configs] config object
198
205
  # @param failure [Integer] failure code to return on failure if not nil
199
- # @param logger [Logger] system logger
200
206
  # @return [Integer] Success of failure code
201
- def self.simple_command(klass:, method:, config_key: nil, configs:, failure: nil, logger:)
202
- config = configs[:device_config].dup
207
+ def self.simple_command(klass:, method:, config_key: nil, config:, failure: nil)
208
+ klass_config = config.parsed[:device_config].dup
203
209
  key = klass.to_s.split("::")[-1].underscore.to_sym
204
- if configs[:init_params][key]
205
- config[:init_params] = configs[:init_params][key]
210
+ if config.parsed[:init_params][key]
211
+ klass_config[:init_params] = config.parsed[:init_params][key]
206
212
  end
207
- instance = klass.new(**config)
213
+ instance = klass.new(**klass_config)
208
214
  if config_key
209
- success = instance.send(method, configs[config_key])
215
+ success = instance.send(method, config.parsed[config_key])
210
216
  else
211
217
  success = instance.send(method)
212
218
  end
213
219
  return failure unless failure.nil? or success
214
- logger.debug "#{klass} call #{method} successfully"
220
+ Logger.instance.debug "#{klass} call #{method} successfully"
215
221
  SUCCESS
216
222
  end
217
223
  end
@@ -138,16 +138,5 @@ module RokuBuilder
138
138
  abort
139
139
  end
140
140
  end
141
-
142
- # Print Options Deprications
143
- # @param options [Hash] The options hash.
144
- # @param logger [Logger] system logger
145
- def self.print_options_depricateions(options:, logger:)
146
- depricated = Controller.depricated_options.keys & options.keys
147
- depricated.each do |key|
148
- logger.warn Controller.depricated_options[key]
149
- end
150
- end
151
- private_class_method :print_options_depricateions
152
141
  end
153
142
  end
@@ -0,0 +1,12 @@
1
+ # ********** Copyright Viacom, Inc. Apache 2.0 **********
2
+
3
+ module RokuBuilder
4
+ class InvalidConfig < StandardError
5
+ end
6
+
7
+ class ParseError < StandardError
8
+ end
9
+
10
+ class InvalidOptions < StandardError
11
+ end
12
+ end
@@ -54,7 +54,7 @@ module RokuBuilder
54
54
  payload = {
55
55
  mysubmit: "Screenshot",
56
56
  passwd: @dev_password,
57
- archive: Faraday::UploadIO.new("/dev/null", 'application/octet-stream')
57
+ archive: Faraday::UploadIO.new(File::NULL, 'application/octet-stream')
58
58
  }
59
59
  response = conn.post path, payload
60
60
 
@@ -62,15 +62,17 @@ module RokuBuilder
62
62
  return false unless path
63
63
  path = path[1]
64
64
  unless out_file
65
- out_file = /time=([^"]*)">/.match(response.body)
66
- out_file = "dev_#{out_file[1]}.jpg" if out_file
65
+ out_time = /time=([^"]*)">/.match(response.body)
66
+ out_ext = /dev.([^"]*)\?/.match(response.body)
67
+ out_file = "dev_#{out_time[1]}.#{out_ext[1]}" if out_time and out_ext
68
+ out_file = "dev.jpg" unless out_file
67
69
  end
68
70
 
69
71
  conn = simple_connection
70
72
 
71
73
  response = conn.get path
72
74
 
73
- File.open(File.join(out_folder, out_file), "w") do |io|
75
+ File.open(File.join(out_folder, out_file), "wb") do |io|
74
76
  io.write(response.body)
75
77
  end
76
78
  @logger.info "Screen captured to #{File.join(out_folder, out_file)}"
@@ -11,7 +11,7 @@ module RokuBuilder
11
11
  @logger.info("DevID: "+dev_id)
12
12
 
13
13
  unless out_file
14
- out_file = File.join("/tmp", "key_"+dev_id+".pkg")
14
+ out_file = File.join(Dir.tmpdir, "key_"+dev_id+".pkg")
15
15
  end
16
16
 
17
17
  Dir.mktmpdir { |dir|
@@ -62,7 +62,7 @@ module RokuBuilder
62
62
  content[:folders] ||= Dir.entries(@root_dir).select {|entry| File.directory? File.join(@root_dir, entry) and !(entry =='.' || entry == '..') }
63
63
  content[:files] ||= Dir.entries(@root_dir).select {|entry| File.file? File.join(@root_dir, entry)}
64
64
  content[:excludes] ||= []
65
- out_file = "/tmp/#{build_version}" unless out_file
65
+ out_file = "#{Dir.tmpdir}/#{build_version}" unless out_file
66
66
  out_file = out_file+".zip" unless out_file.end_with?(".zip")
67
67
  File.delete(out_file) if File.exist?(out_file)
68
68
  io = Zip::File.open(out_file, Zip::File::CREATE)
@@ -0,0 +1,32 @@
1
+ # ********** Copyright Viacom, Inc. Apache 2.0 **********
2
+
3
+ module RokuBuilder
4
+ class Logger
5
+
6
+ @@instance = nil
7
+
8
+ def self.instance
9
+ unless @@instance
10
+ @@instance = ::Logger.new(STDOUT)
11
+ @@instance.formatter = proc {|severity, datetime, _progname, msg|
12
+ "[%s #%s] %5s: %s\n\r" % [datetime.strftime("%Y-%m-%d %H:%M:%S.%4N"), $$, severity, msg]
13
+ }
14
+ end
15
+ @@instance
16
+ end
17
+
18
+ def self.set_debug
19
+ instance.level = ::Logger::DEBUG
20
+ end
21
+ def self.set_info
22
+ instance.level = ::Logger::INFO
23
+ end
24
+ def self.set_warn
25
+ instance.level = ::Logger::WARN
26
+ end
27
+
28
+ def self.set_testing
29
+ @@instance = ::Logger.new(File::NULL)
30
+ end
31
+ end
32
+ end
@@ -17,8 +17,8 @@ module RokuBuilder
17
17
  build_version[1] = iteration
18
18
  build_version = build_version.join(".")
19
19
  else
20
- #Use current date.
21
- build_version = Time.now.strftime("%m%d%y")+".0001"
20
+ iteration = build_version[0].to_i + 1
21
+ build_version = iteration.to_s
22
22
  end
23
23
  self.update_manifest(root_dir: root_dir, attributes: {build_version: build_version})
24
24
  self.build_version(root_dir: root_dir)
@@ -59,7 +59,7 @@ module RokuBuilder
59
59
  "exit", "gc", "help", "last", "list", "next", "print", "p", "?", "step",
60
60
  "s", "t", "over", "out", "up", "u", "var", "q"
61
61
  ].sort
62
- commands.collect { |i| i += ' ' } if libedit
62
+ commands.collect { |i| i + ' ' } if libedit
63
63
 
64
64
  comp = proc { |s| commands.grep( /^#{Regexp.escape(s)}/ ) }
65
65
 
@@ -0,0 +1,113 @@
1
+ # ********** Copyright Viacom, Inc. Apache 2.0 **********
2
+
3
+ module RokuBuilder
4
+ class Options < Hash
5
+ def initialize(options:)
6
+ merge!(options)
7
+ @logger = Logger.instance
8
+ validate
9
+ end
10
+
11
+ def command
12
+ (keys & commands).first
13
+ end
14
+
15
+ def exclude_command?
16
+ exclude_commands.include?(command)
17
+ end
18
+
19
+ def source_command?
20
+ (source_commands & keys).count > 0
21
+ end
22
+
23
+ def device_command?
24
+ device_commands.include?(command)
25
+ end
26
+
27
+ def has_source?
28
+ !(keys & sources).empty?
29
+ end
30
+
31
+ private
32
+
33
+ def validate
34
+ validate_commands
35
+ validate_sources
36
+ validate_combinations
37
+ validate_deprivated
38
+ end
39
+
40
+ def validate_commands
41
+ all_commands = keys & commands
42
+ raise InvalidOptions, "Only specify one command" if all_commands.count > 1
43
+ raise InvalidOptions, "Specify at least one command" if all_commands.count < 1
44
+ end
45
+
46
+ def validate_sources
47
+ all_sources = keys & sources
48
+ raise InvalidOptions, "Only spefify one source" if all_sources.count > 1
49
+ if source_command? and !has_source?
50
+ raise InvalidOptions, "Must specify a source for that command"
51
+ end
52
+ end
53
+
54
+ def validate_combinations
55
+ all_sources = keys & sources
56
+ if all_sources.include?(:current) and not (self[:build] or self[:sideload])
57
+ raise InvalidOptions, "Current source onle works for build or sideload"
58
+ end
59
+ if self[:in] and not self[:sideload]
60
+ raise InvalidOptions, "In source only works for sideloading"
61
+ end
62
+ end
63
+
64
+ def validate_deprivated
65
+ depricated = keys & depricated_options.keys
66
+ if depricated.count > 0
67
+ depricated.each do |key|
68
+ @logger.warn depricated_options[key]
69
+ end
70
+ end
71
+ end
72
+
73
+ # List of command options
74
+ # @return [Array<Symbol>] List of command symbols that can be used in the options hash
75
+ def commands
76
+ [:sideload, :package, :test, :deeplink,:configure, :validate, :delete,
77
+ :navigate, :navigator, :text, :build, :monitor, :update, :screencapture,
78
+ :key, :genkey, :screen, :screens, :applist, :print, :profile, :dostage,
79
+ :dounstage]
80
+ end
81
+
82
+ # List of depricated options
83
+ # @return [Hash] Hash of depricated options and the warning message for each
84
+ def depricated_options
85
+ {deeplink_depricated: "-L and --deeplink are depricated. Use -o or --deeplink-options." }
86
+ end
87
+
88
+ # List of source options
89
+ # @return [Array<Symbol>] List of source symbols that can be used in the options hash
90
+ def sources
91
+ [:ref, :set_stage, :working, :current, :in]
92
+ end
93
+
94
+ # List of commands requiring a source option
95
+ # @return [Array<Symbol>] List of command symbols that require a source in the options hash
96
+ def source_commands
97
+ [:sideload, :package, :test, :build, :key, :update, :print]
98
+ end
99
+
100
+ # List of commands the activate the exclude files
101
+ # @return [Array<Symbol] List of commands the will activate the exclude files lists
102
+ def exclude_commands
103
+ [:build, :package]
104
+ end
105
+
106
+ # List of commands that require a device
107
+ # @return [Array<Symbol>] List of commands that require a device
108
+ def device_commands
109
+ [:sideload, :package, :test, :deeplink, :delete, :navigate, :navigator,
110
+ :text, :monitor, :screencapture, :applist, :profile, :key, :genkey ]
111
+ end
112
+ end
113
+ end