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
@@ -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