roku_builder 3.3.3 → 3.3.4

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +1158 -0
  4. data/.travis.yml +3 -0
  5. data/Gemfile.lock +19 -14
  6. data/README.md +5 -0
  7. data/bin/roku +32 -37
  8. data/config.json.example +2 -2
  9. data/lib/roku_builder/config_manager.rb +83 -118
  10. data/lib/roku_builder/config_parser.rb +192 -0
  11. data/lib/roku_builder/config_validator.rb +125 -0
  12. data/lib/roku_builder/controller.rb +97 -484
  13. data/lib/roku_builder/controller_commands.rb +112 -0
  14. data/lib/roku_builder/error_handler.rb +116 -0
  15. data/lib/roku_builder/inspector.rb +5 -18
  16. data/lib/roku_builder/keyer.rb +3 -11
  17. data/lib/roku_builder/linker.rb +3 -15
  18. data/lib/roku_builder/loader.rb +52 -89
  19. data/lib/roku_builder/manifest_manager.rb +2 -3
  20. data/lib/roku_builder/monitor.rb +15 -12
  21. data/lib/roku_builder/navigator.rb +2 -10
  22. data/lib/roku_builder/packager.rb +1 -7
  23. data/lib/roku_builder/tester.rb +1 -0
  24. data/lib/roku_builder/util.rb +39 -0
  25. data/lib/roku_builder/version.rb +1 -1
  26. data/lib/roku_builder.rb +96 -1
  27. data/roku_builder.gemspec +5 -4
  28. data/tests/roku_builder/config_manager_test.rb +80 -241
  29. data/tests/roku_builder/{controller_config_test.rb → config_parser_test.rb} +5 -5
  30. data/tests/roku_builder/config_validator_test.rb +158 -0
  31. data/tests/roku_builder/controller_commands_test.rb +304 -0
  32. data/tests/roku_builder/controller_test.rb +61 -620
  33. data/tests/roku_builder/error_handler_test.rb +76 -0
  34. data/tests/roku_builder/inspector_test.rb +3 -0
  35. data/tests/roku_builder/keyer_test.rb +3 -2
  36. data/tests/roku_builder/linker_test.rb +2 -1
  37. data/tests/roku_builder/loader_test.rb +2 -0
  38. data/tests/roku_builder/manifest_manager_test.rb +3 -6
  39. data/tests/roku_builder/monitor_test.rb +5 -13
  40. data/tests/roku_builder/navigator_test.rb +2 -0
  41. data/tests/roku_builder/test_helper.rb +38 -0
  42. metadata +34 -11
@@ -0,0 +1,112 @@
1
+ module RokuBuilder
2
+
3
+ # Commands that the controller uses to interface with the rest of the gem.
4
+ class ControllerCommands
5
+
6
+ # Provides a hash of all of the options needed to run simple commands via
7
+ # the simple_command method
8
+ # @return [Hash] options to run simple commands
9
+ def self.simple_commands
10
+ {
11
+ sideload: { klass: Loader, method: :sideload, config_key: :sideload_config,
12
+ failure: FAILED_SIDELOAD },
13
+ deeplink: { klass: Linker, method: :link, config_key: :deeplink_config,
14
+ failure: FAILED_DEEPLINKING },
15
+ delete: { klass: Loader, method: :unload },
16
+ monitor: { klass: Monitor, method: :monitor,
17
+ config_key: :monitor_config },
18
+ navigate: { klass: Navigator, method: :nav, config_key: :navigate_config,
19
+ failure: FAILED_NAVIGATING },
20
+ screen: { klass: Navigator, method: :screen, config_key: :screen_config,
21
+ failure: FAILED_NAVIGATING },
22
+ screens: { klass: Navigator, method: :screens },
23
+ text: { klass: Navigator, method: :type, config_key: :text_config },
24
+ test: { klass: Tester, method: :run_tests, config_key: :test_config },
25
+ screencapture: { klass: Inspector, method: :screencapture, config_key: :screencapture_config,
26
+ failure: FAILED_SCREENCAPTURE }
27
+ }
28
+ end
29
+ # Validate Config
30
+ # @return [Integer] Success or Failure Code
31
+ def self.validate()
32
+ SUCCESS
33
+ end
34
+ # Run Package
35
+ # @param options [Hash] user options
36
+ # @param configs [Hash] parsed configs
37
+ # @param logger [Logger] system logger
38
+ # @return [Integer] Success or Failure Code
39
+ def self.package(options:, configs:, logger:)
40
+ keyer = Keyer.new(**configs[:device_config])
41
+ loader = Loader.new(**configs[:device_config])
42
+ packager = Packager.new(**configs[:device_config])
43
+ inspector = Inspector.new(**configs[:device_config])
44
+ logger.warn "Packaging working directory" if options[:working]
45
+ # Sideload #
46
+ build_version = loader.sideload(**configs[:sideload_config])
47
+ return FAILED_SIGNING unless build_version
48
+ # Key #
49
+ success = keyer.rekey(**configs[:key])
50
+ logger.info "Key did not change" unless success
51
+ # Package #
52
+ options[:build_version] = build_version
53
+ configs = ConfigManager.update_configs(configs: configs, options: options)
54
+ success = packager.package(**configs[:package_config])
55
+ logger.info "Signing Successful: #{configs[:package_config][:out_file]}" if success
56
+ return FAILED_SIGNING unless success
57
+ # Inspect #
58
+ if options[:inspect]
59
+ info = inspector.inspect(configs[:inspect_config])
60
+ logger.unknown "App Name: #{info[:app_name]}"
61
+ logger.unknown "Dev ID: #{info[:dev_id]}"
62
+ logger.unknown "Creation Date: #{info[:creation_date]}"
63
+ logger.unknown "dev.zip: #{info[:dev_zip]}"
64
+ end
65
+ SUCCESS
66
+ end
67
+ # Run Build
68
+ # @param options [Hash] user options
69
+ # @param configs [Hash] parsed configs
70
+ # @param logger [Logger] system logger
71
+ # @return [Integer] Success or Failure Code
72
+ def self.build(options:, configs:, logger:)
73
+ ### Build ###
74
+ loader = Loader.new(**configs[:device_config])
75
+ build_version = ManifestManager.build_version(**configs[:manifest_config])
76
+ options[:build_version] = build_version
77
+ configs = ConfigManager.update_configs(configs: configs, options: options)
78
+ outfile = loader.build(**configs[:build_config])
79
+ logger.info "Build: #{outfile}"
80
+ SUCCESS
81
+ end
82
+ # Run update
83
+ # @param configs [Hash] parsed configs
84
+ # @param logger [Logger] system logger
85
+ # @return [Integer] Success or Failure Code
86
+ def self.update(configs:, logger:)
87
+ ### Update ###
88
+ old_version = ManifestManager.build_version(**configs[:manifest_config])
89
+ new_version = ManifestManager.update_build(**configs[:manifest_config])
90
+ logger.info "Update build version from:\n#{old_version}\nto:\n#{new_version}"
91
+ SUCCESS
92
+ end
93
+
94
+ # Run a simple command
95
+ # @param klass [Class] class of object to create
96
+ # @param method [Symbol] methog to run on klass
97
+ # @param config_key [Symbol] config to send from configs if not nil
98
+ # @param configs [Hash] parsed roku config
99
+ # @param failure [Integer] failure code to return on failure if not nil
100
+ # @return [Integer] Success of failure code
101
+ def self.simple_command(klass:, method:, config_key: nil, configs:, failure: nil)
102
+ instance = klass.new(**configs[:device_config])
103
+ if config_key
104
+ success = instance.send(method, configs[config_key])
105
+ else
106
+ success = instance.send(method)
107
+ end
108
+ return failure unless failure.nil? or success
109
+ SUCCESS
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,116 @@
1
+ module RokuBuilder
2
+
3
+ # Contains methods to handle errors from different sources.
4
+ class ErrorHandler
5
+ # Handle codes returned from validating options
6
+ # @param options_code [Integer] the error code returned by validate_options
7
+ # @param logger [Logger] system logger
8
+ def self.handle_options_codes(options_code:, logger:)
9
+ case options_code
10
+ when EXTRA_COMMANDS
11
+ logger.fatal "Only one command is allowed"
12
+ abort
13
+ when NO_COMMANDS
14
+ logger.fatal "At least one command is required"
15
+ abort
16
+ when EXTRA_SOURCES
17
+ logger.fatal "Only use one of --ref, --working, --current or --stage"
18
+ abort
19
+ when NO_SOURCE
20
+ logger.fatal "Must use at least one of --ref, --working, --current or --stage"
21
+ abort
22
+ when BAD_CURRENT
23
+ logger.fatal "Can only sideload or build 'current' directory"
24
+ abort
25
+ when BAD_DEEPLINK
26
+ logger.fatal "Must supply deeplinking options when deeplinking"
27
+ abort
28
+ when BAD_IN_FILE
29
+ logger.fatal "Can only supply in file for building"
30
+ abort
31
+ end
32
+ end
33
+
34
+ # Handle codes returned from configuring
35
+ # @param configure_code [Integer] the error code returned by configure
36
+ # @param logger [Logger] system logger
37
+ def self.handle_configure_codes(configure_code:, logger:)
38
+ case configure_code
39
+ when CONFIG_OVERWRITE
40
+ logger.fatal 'Config already exists. To create default please remove config first.'
41
+ abort
42
+ when SUCCESS
43
+ logger.info 'Configure successful'
44
+ abort
45
+ end
46
+ end
47
+
48
+ # Handle codes returned from load_config
49
+ # @param options [Hash] the options hash
50
+ # @param load_code [Integer] the error code returned by configure
51
+ # @param logger [Logger] system logger
52
+ def self.handle_load_codes(options:, load_code:, logger:)
53
+ case load_code
54
+ when DEPRICATED_CONFIG
55
+ logger.warn 'Depricated config. See Above'
56
+ when MISSING_CONFIG
57
+ logger.fatal "Missing config file: #{options[:config]}"
58
+ abort
59
+ when INVALID_CONFIG
60
+ logger.fatal 'Invalid config. See Above'
61
+ abort
62
+ when MISSING_MANIFEST
63
+ logger.fatal 'Manifest file missing'
64
+ abort
65
+ when UNKNOWN_DEVICE
66
+ logger.fatal "Unkown device id"
67
+ abort
68
+ when UNKNOWN_PROJECT
69
+ logger.fatal "Unknown project id"
70
+ abort
71
+ when UNKNOWN_STAGE
72
+ logger.fatal "Unknown stage"
73
+ abort
74
+ end
75
+ end
76
+
77
+ # Handle codes returned from checking devices
78
+ # @param device_code [Integer] the error code returned by check_devices
79
+ # @param logger [Logger] system logger
80
+ def self.handle_device_codes(device_code:, logger:)
81
+ case device_code
82
+ when CHANGED_DEVICE
83
+ logger.info "The default device was not online so a secondary device is being used"
84
+ when BAD_DEVICE
85
+ logger.fatal "The selected device was not online"
86
+ abort
87
+ when NO_DEVICES
88
+ logger.fatal "No configured devices were found"
89
+ abort
90
+ end
91
+ end
92
+
93
+ # Handle codes returned from handeling commands devices
94
+ # @param command_code [Integer] the error code returned by handle_options
95
+ # @param logger [Logger] system logger
96
+ def self.handle_command_codes(command_code:, logger:)
97
+ case command_code
98
+ when FAILED_SIDELOAD
99
+ logger.fatal "Failed Sideloading App"
100
+ abort
101
+ when FAILED_SIGNING
102
+ logger.fatal "Failed Signing App"
103
+ abort
104
+ when FAILED_DEEPLINKING
105
+ logger.fatal "Failed Deeplinking To App"
106
+ abort
107
+ when FAILED_NAVIGATING
108
+ logger.fatal "Command not sent"
109
+ abort
110
+ when FAILED_SCREENCAPTURE
111
+ logger.fatal "Failed to Capture Screen"
112
+ abort
113
+ end
114
+ end
115
+ end
116
+ end
@@ -15,12 +15,7 @@ module RokuBuilder
15
15
 
16
16
  # upload new key with password
17
17
  path = "/plugin_inspect"
18
- conn = Faraday.new(url: @url) do |f|
19
- f.request :digest, @dev_username, @dev_password
20
- f.request :multipart
21
- f.request :url_encoded
22
- f.adapter Faraday.default_adapter
23
- end
18
+ conn = multipart_connection
24
19
  payload = {
25
20
  mysubmit: "Inspect",
26
21
  passwd: password,
@@ -35,12 +30,12 @@ module RokuBuilder
35
30
  if app_name
36
31
  app_name = app_name[1]
37
32
  dev_id = /Dev ID:\s*<\/td>\s*<td>\s*<font[^>]*>([^<]*)<\/font>\s*<\/td>/.match(response.body)[1]
38
- creation_date = /new Date\(([^)]*)\)/.match(response.body.gsub("\n", ''))[1]
33
+ creation_date = /new Date\(([^)]*)\)/.match(response.body.delete("\n"))[1]
39
34
  dev_zip = /dev.zip:\s*<\/td>\s*<td>\s*<font[^>]*>([^<]*)<\/font>\s*<\/td>/.match(response.body)[1]
40
35
  else
41
36
  app_name = /App Name:[^<]*<div[^>]*>([^<]*)<\/div>/.match(response.body)[1]
42
37
  dev_id = /Dev ID:[^<]*<div[^>]*><font[^>]*>([^<]*)<\/font><\/div>/.match(response.body)[1]
43
- creation_date = /new Date\(([^\/]*)\)/.match(response.body.gsub("\n", ''))[1]
38
+ creation_date = /new Date\(([^\/]*)\)/.match(response.body.delete("\n"))[1]
44
39
  dev_zip = /dev.zip:[^<]*<div[^>]*><font[^>]*>([^<]*)<\/font><\/div>/.match(response.body)[1]
45
40
  end
46
41
 
@@ -52,12 +47,7 @@ module RokuBuilder
52
47
  # @return [Boolean] Success
53
48
  def screencapture(out_folder:, out_file: nil)
54
49
  path = "/plugin_inspect"
55
- conn = Faraday.new(url: @url) do |f|
56
- f.request :digest, @dev_username, @dev_password
57
- f.request :multipart
58
- f.request :url_encoded
59
- f.adapter Faraday.default_adapter
60
- end
50
+ conn = multipart_connection
61
51
  payload = {
62
52
  mysubmit: "Screenshot",
63
53
  passwd: @dev_password,
@@ -73,10 +63,7 @@ module RokuBuilder
73
63
  out_file = "dev_#{out_file[1]}.jpg" if out_file
74
64
  end
75
65
 
76
- conn = Faraday.new(url: @url) do |f|
77
- f.request :digest, @dev_username, @dev_password
78
- f.adapter Faraday.default_adapter
79
- end
66
+ conn = simple_connection
80
67
 
81
68
  response = conn.get path
82
69
 
@@ -12,18 +12,13 @@ module RokuBuilder
12
12
 
13
13
  # upload new key with password
14
14
  path = "/plugin_inspect"
15
- conn = Faraday.new(url: @url) do |f|
16
- f.request :digest, @dev_username, @dev_password
17
- f.request :multipart
18
- f.request :url_encoded
19
- f.adapter Faraday.default_adapter
20
- end
15
+ conn = multipart_connection
21
16
  payload = {
22
17
  mysubmit: "Rekey",
23
18
  passwd: password,
24
19
  archive: Faraday::UploadIO.new(keyed_pkg, 'application/octet-stream')
25
20
  }
26
- response = conn.post path, payload
21
+ conn.post path, payload
27
22
 
28
23
  # check key
29
24
  newId = dev_id
@@ -34,10 +29,7 @@ module RokuBuilder
34
29
  # @return [String] The current dev id
35
30
  def dev_id
36
31
  path = "/plugin_package"
37
- conn = Faraday.new(url: @url) do |f|
38
- f.request :digest, @dev_username, @dev_password
39
- f.adapter Faraday.default_adapter
40
- end
32
+ conn = simple_connection
41
33
  response = conn.get path
42
34
 
43
35
  dev_id = /Your Dev ID:\s*<font[^>]*>([^<]*)<\/font>/.match(response.body)
@@ -8,27 +8,15 @@ module RokuBuilder
8
8
  # @note Any options will be accepted and sent to the app
9
9
  def link(options:)
10
10
  path = "/launch/dev"
11
- payload = {}
12
11
  return false unless options
13
- opts = options.split(/,\s*/)
14
- opts.each do |opt|
15
- opt = opt.split(":")
16
- key = opt.shift.to_sym
17
- value = opt.join(":")
18
- payload[key] = value
19
- end
12
+ payload = Util.options_parse(options: options)
20
13
 
21
14
  unless payload.keys.count > 0
22
15
  return false
23
16
  end
24
17
 
25
18
  path = "#{path}?#{parameterize(payload)}"
26
- conn = Faraday.new(url: "#{@url}:8060") do |f|
27
- f.request :digest, @dev_username, @dev_password
28
- f.request :multipart
29
- f.request :url_encoded
30
- f.adapter Faraday.default_adapter
31
- end
19
+ conn = multipart_connection(port: 8060)
32
20
 
33
21
  response = conn.post path
34
22
  return response.success?
@@ -40,7 +28,7 @@ module RokuBuilder
40
28
  # @param params [Hash] Parameters to be sent
41
29
  # @return [String] Parameters as a string, URI escaped
42
30
  def parameterize(params)
43
- URI.escape(params.collect{|k,v| "#{k}=#{URI.escape(v, "?&")}"}.join('&'))
31
+ params.collect{|k,v| "#{k}=#{CGI.escape(v)}"}.join('&')
44
32
  end
45
33
  end
46
34
  end
@@ -7,75 +7,39 @@ module RokuBuilder
7
7
  # @param root_dir [String] Path to the root directory of the roku app
8
8
  # @param branch [String] Branch of the git repository to sideload. Pass nil to use working directory. Default: nil
9
9
  # @param update_manifest [Boolean] Flag to update the manifest file before sideloading. Default: false
10
- # @param fetch [Boolean] Flag to fetch all remotes before sideloading. Default: false
11
10
  # @param folders [Array<String>] Array of folders to be sideloaded. Pass nil to send all folders. Default: nil
12
11
  # @param files [Array<String>] Array of files to be sideloaded. Pass nil to send all files. Default: nil
13
- # @param infile [String]
14
12
  # @return [String] Build version on success, nil otherwise
15
- def sideload(root_dir:, branch: nil, update_manifest: false, fetch: false, folders: nil, files: nil, infile: nil)
13
+ def sideload(root_dir:, branch: nil, update_manifest: false, folders: nil, files: nil)
16
14
  @root_dir = root_dir
17
15
  result = nil
18
- stash = nil
19
- if branch
20
- git = Git.open(@root_dir)
21
- if fetch
22
- for remote in git.remotes
23
- git.fetch(remote)
24
- end
25
- end
26
- end
27
- current_dir = Dir.pwd
28
16
  begin
29
- if git and branch and branch != git.current_branch
30
- Dir.chdir(@root_dir)
31
- current_branch = git.current_branch
32
- stash = git.branch.stashes.save("roku-builder-temp-stash")
33
- git.checkout(branch)
34
- end
35
-
17
+ git_switch_to(branch: branch)
36
18
  # Update manifest
37
19
  build_version = ""
38
20
  if update_manifest
39
- build_version = ManifestManager.update_build(root_dir: root_dir, logger: @logger)
21
+ build_version = ManifestManager.update_build(root_dir: root_dir)
40
22
  else
41
- build_version = ManifestManager.build_version(root_dir: root_dir, logger: @logger)
23
+ build_version = ManifestManager.build_version(root_dir: root_dir)
42
24
  end
43
-
44
25
  outfile = build(root_dir: root_dir, branch: branch, build_version: build_version, folders: folders, files: files)
45
-
46
26
  path = "/plugin_install"
47
-
48
27
  # Connect to roku and upload file
49
- conn = Faraday.new(url: @url) do |f|
50
- f.request :digest, @dev_username, @dev_password
51
- f.request :multipart
52
- f.request :url_encoded
53
- f.adapter Faraday.default_adapter
54
- end
28
+ conn = multipart_connection
55
29
  payload = {
56
30
  mysubmit: "Replace",
57
31
  archive: Faraday::UploadIO.new(outfile, 'application/zip')
58
32
  }
59
33
  response = conn.post path, payload
60
-
61
34
  # Cleanup
62
35
  File.delete(outfile)
63
-
64
- if git and current_branch
65
- git.checkout(current_branch)
66
- git.branch.stashes.apply if stash
67
- end
68
-
69
- if response.status == 200 and response.body =~ /Install Success/
70
- result = build_version
71
- end
72
-
73
- rescue Git::GitExecuteError => e
74
- @logger.error "Branch or ref does not exist"
75
- @logger.error e.message
76
- @logger.error e.backtrace
36
+ result = build_version if response.status==200 and response.body=~/Install Success/
37
+ git_switch_from(branch: branch)
38
+ rescue Git::GitExecuteError
39
+ git_rescue
77
40
  ensure
78
- Dir.chdir(current_dir) unless current_dir == Dir.pwd
41
+ @current_dir ||= Dir.pwd
42
+ Dir.chdir(@current_dir) unless @current_dir == Dir.pwd
79
43
  end
80
44
  result
81
45
  end
@@ -86,31 +50,13 @@ module RokuBuilder
86
50
  # @param branch [String] Branch of the git repository to sideload. Pass nil to use working directory. Default: nil
87
51
  # @param build_version [String] Version to assigne to the build. If nil will pull the build version form the manifest. Default: nil
88
52
  # @param outfile [String] Path for the output file. If nil will create a file in /tmp. Default: nil
89
- # @param fetch [Boolean] Flag to fetch all remotes before sideloading. Default: false
90
53
  # @param folders [Array<String>] Array of folders to be sideloaded. Pass nil to send all folders. Default: nil
91
54
  # @param files [Array<String>] Array of files to be sideloaded. Pass nil to send all files. Default: nil
92
55
  # @return [String] Path of the build
93
- def build(root_dir:, branch: nil, build_version: nil, outfile: nil, fetch: false, folders: nil, files: nil)
56
+ def build(root_dir:, branch: nil, build_version: nil, outfile: nil, folders: nil, files: nil)
94
57
  @root_dir = root_dir
95
- result = nil
96
- stash = nil
97
- if branch
98
- git = Git.open(@root_dir)
99
- if fetch
100
- for remote in git.remotes
101
- git.fetch(remote)
102
- end
103
- end
104
- end
105
- current_dir = Dir.pwd
106
58
  begin
107
- if git and branch and branch != git.current_branch
108
- Dir.chdir(@root_dir)
109
- current_branch = git.current_branch
110
- stash = git.branch.stashes.save("roku-builder-temp-stash")
111
- git.checkout(branch)
112
- end
113
-
59
+ git_switch_to(branch: branch)
114
60
  build_version = ManifestManager.build_version(root_dir: root_dir, logger: @logger) unless build_version
115
61
  unless folders
116
62
  folders = Dir.entries(root_dir).select {|entry| File.directory? File.join(root_dir, entry) and !(entry =='.' || entry == '..') }
@@ -119,10 +65,8 @@ module RokuBuilder
119
65
  files = Dir.entries(root_dir).select {|entry| File.file? File.join(root_dir, entry)}
120
66
  end
121
67
  outfile = "/tmp/build_#{build_version}.zip" unless outfile
122
-
123
- File.delete(outfile) if File.exists?(outfile)
68
+ File.delete(outfile) if File.exist?(outfile)
124
69
  io = Zip::File.open(outfile, Zip::File::CREATE)
125
-
126
70
  # Add folders to zip
127
71
  folders.each do |folder|
128
72
  base_folder = File.join(@root_dir, folder)
@@ -131,22 +75,15 @@ module RokuBuilder
131
75
  entries.delete("..")
132
76
  writeEntries(@root_dir, entries, folder, io)
133
77
  end
134
-
135
78
  # Add file to zip
136
79
  writeEntries(@root_dir, files, "", io)
137
-
138
80
  io.close()
139
-
140
- if git and current_branch
141
- git.checkout(current_branch)
142
- git.branch.stashes.apply if stash
143
- end
144
- rescue Git::GitExecuteError => e
145
- @logger.error "Branch or ref does not exist"
146
- @logger.error e.message
147
- @logger.error e.backtrace
81
+ git_switch_from(branch: branch)
82
+ rescue Git::GitExecuteError
83
+ git_rescue
148
84
  ensure
149
- Dir.chdir(current_dir) unless current_dir == Dir.pwd
85
+ @current_dir ||= Dir.pwd
86
+ Dir.chdir(@current_dir) unless @current_dir == Dir.pwd
150
87
  end
151
88
  outfile
152
89
  end
@@ -156,13 +93,7 @@ module RokuBuilder
156
93
  path = "/plugin_install"
157
94
 
158
95
  # Connect to roku and upload file
159
- conn = Faraday.new(url: @url) do |f|
160
- f.headers['Content-Type'] = Faraday::Request::Multipart.mime_type
161
- f.request :digest, @dev_username, @dev_password
162
- f.request :multipart
163
- f.request :url_encoded
164
- f.adapter Faraday.default_adapter
165
- end
96
+ conn = multipart_connection
166
97
  payload = {
167
98
  mysubmit: "Delete",
168
99
  archive: ""
@@ -194,5 +125,37 @@ module RokuBuilder
194
125
  end
195
126
  }
196
127
  end
128
+
129
+ # Switch to the correct branch
130
+ def git_switch_to(branch:)
131
+ if branch
132
+ @current_dir = Dir.pwd
133
+ @git ||= Git.open(@root_dir)
134
+ if branch != @git.current_branch
135
+ Dir.chdir(@root_dir)
136
+ @current_branch = @git.current_branch
137
+ @stash = @git.branch.stashes.save("roku-builder-temp-stash")
138
+ @git.checkout(branch)
139
+ end
140
+ end
141
+ end
142
+
143
+ # Switch back to the previous branch
144
+ def git_switch_from(branch:)
145
+ if branch
146
+ @git ||= Git.open(@root_dir)
147
+ if @git and @current_branch
148
+ @git.checkout(@current_branch)
149
+ @git.branch.stashes.apply if @stash
150
+ end
151
+ end
152
+ end
153
+
154
+ # Called if resuce from git exception
155
+ def git_rescue
156
+ @logger.error "Branch or ref does not exist"
157
+ @logger.error e.message
158
+ @logger.error e.backtrace
159
+ end
197
160
  end
198
161
  end
@@ -6,7 +6,7 @@ module RokuBuilder
6
6
  # Updates the build version in the manifest file
7
7
  # @param root_dir [String] Path to the root directory for the app
8
8
  # @return [String] Build version on success, empty string otherwise
9
- def self.update_build(root_dir:, logger:)
9
+ def self.update_build(root_dir:)
10
10
 
11
11
  build_version = ""
12
12
 
@@ -19,7 +19,6 @@ module RokuBuilder
19
19
 
20
20
  #Update build version.
21
21
  build_version = line.split(".")
22
- iteration = 0
23
22
  if 2 == build_version.length
24
23
  iteration = build_version[1].to_i + 1
25
24
  build_version[0] = Time.now.strftime("%m%d%y")
@@ -47,7 +46,7 @@ module RokuBuilder
47
46
  # Retrive the build version from the manifest file
48
47
  # @param root_dir [String] Path to the root directory for the app
49
48
  # @return [String] Build version on success, empty string otherwise
50
- def self.build_version(root_dir:, logger:)
49
+ def self.build_version(root_dir:)
51
50
  path = File.join(root_dir, 'manifest')
52
51
  build_version = ""
53
52
  File.open(path, 'r') do |file|
@@ -17,7 +17,6 @@ module RokuBuilder
17
17
 
18
18
  # Monitor a development log on the Roku device
19
19
  # @param type [Symbol] The log type to monitor
20
- # @param verbose [Boolean] Print status messages.
21
20
  def monitor(type:)
22
21
  telnet_config = {
23
22
  'Host' => @roku_ip_address,
@@ -28,26 +27,30 @@ module RokuBuilder
28
27
  'Timeout' => false
29
28
  }
30
29
 
31
- thread = Thread.new(telnet_config, waitfor_config) {|telnet_config,waitfor_config|
32
- @logger.info "Monitoring #{type} console(#{telnet_config['Port']}) on #{telnet_config['Host'] }"
33
- connection = Net::Telnet.new(telnet_config)
30
+ thread = Thread.new(telnet_config, waitfor_config) {|telnet,waitfor|
31
+ @logger.info "Monitoring #{type} console(#{telnet['Port']}) on #{telnet['Host'] }"
32
+ connection = Net::Telnet.new(telnet)
34
33
  Thread.current[:connection] = connection
35
34
  all_text = ""
36
35
  while true
37
- connection.waitfor(waitfor_config) do |txt|
36
+ connection.waitfor(waitfor) do |txt|
38
37
  all_text = manage_text(all_text: all_text, txt: txt)
39
38
  end
40
39
  end
41
40
  }
42
41
  running = true
43
42
  while running
44
- @logger.info "Q to exit"
45
- command = gets.chomp
46
- if command == "q"
47
- thread.exit
48
- running = false
49
- else
50
- thread[:connection].puts(command)
43
+ begin
44
+ @logger.info "Q to exit"
45
+ command = gets.chomp
46
+ if command == "q"
47
+ thread.exit
48
+ running = false
49
+ else
50
+ thread[:connection].puts(command)
51
+ end
52
+ rescue SystemExit, Interrupt
53
+ thread[:connection].puts("\C-c")
51
54
  end
52
55
  end
53
56
  end
@@ -38,11 +38,7 @@ module RokuBuilder
38
38
  # @return [Boolean] Success
39
39
  def nav(command:)
40
40
  if @commands.has_key?(command)
41
- conn = Faraday.new(url: "#{@url}:8060") do |f|
42
- f.request :multipart
43
- f.request :url_encoded
44
- f.adapter Faraday.default_adapter
45
- end
41
+ conn = multipart_connection(port: 8060)
46
42
 
47
43
  path = "/keypress/#{@commands[command]}"
48
44
  response = conn.post path
@@ -56,11 +52,7 @@ module RokuBuilder
56
52
  # @param text [String] The text to type on the device
57
53
  # @return [Boolean] Success
58
54
  def type(text:)
59
- conn = Faraday.new(url: "#{@url}:8060") do |f|
60
- f.request :multipart
61
- f.request :url_encoded
62
- f.adapter Faraday.default_adapter
63
- end
55
+ conn = multipart_connection(port: 8060)
64
56
  text.split(//).each do |c|
65
57
  path = "/keypress/LIT_#{CGI::escape(c)}"
66
58
  response = conn.post path
@@ -11,13 +11,7 @@ module RokuBuilder
11
11
  def package(app_name_version:, out_file:, password:)
12
12
  # Sign package
13
13
  path = "/plugin_package"
14
- conn = Faraday.new(url: @url) do |f|
15
- f.headers['Content-Type'] = Faraday::Request::Multipart.mime_type
16
- f.request :digest, @dev_username, @dev_password
17
- f.request :multipart
18
- f.request :url_encoded
19
- f.adapter Faraday.default_adapter
20
- end
14
+ conn = multipart_connection
21
15
  payload = {
22
16
  mysubmit: "Package",
23
17
  app_name: app_name_version,