roku_builder 3.3.3 → 3.3.4

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