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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +1158 -0
- data/.travis.yml +3 -0
- data/Gemfile.lock +19 -14
- data/README.md +5 -0
- data/bin/roku +32 -37
- data/config.json.example +2 -2
- data/lib/roku_builder/config_manager.rb +83 -118
- data/lib/roku_builder/config_parser.rb +192 -0
- data/lib/roku_builder/config_validator.rb +125 -0
- data/lib/roku_builder/controller.rb +97 -484
- data/lib/roku_builder/controller_commands.rb +112 -0
- data/lib/roku_builder/error_handler.rb +116 -0
- data/lib/roku_builder/inspector.rb +5 -18
- data/lib/roku_builder/keyer.rb +3 -11
- data/lib/roku_builder/linker.rb +3 -15
- data/lib/roku_builder/loader.rb +52 -89
- data/lib/roku_builder/manifest_manager.rb +2 -3
- data/lib/roku_builder/monitor.rb +15 -12
- data/lib/roku_builder/navigator.rb +2 -10
- data/lib/roku_builder/packager.rb +1 -7
- data/lib/roku_builder/tester.rb +1 -0
- data/lib/roku_builder/util.rb +39 -0
- data/lib/roku_builder/version.rb +1 -1
- data/lib/roku_builder.rb +96 -1
- data/roku_builder.gemspec +5 -4
- data/tests/roku_builder/config_manager_test.rb +80 -241
- data/tests/roku_builder/{controller_config_test.rb → config_parser_test.rb} +5 -5
- data/tests/roku_builder/config_validator_test.rb +158 -0
- data/tests/roku_builder/controller_commands_test.rb +304 -0
- data/tests/roku_builder/controller_test.rb +61 -620
- data/tests/roku_builder/error_handler_test.rb +76 -0
- data/tests/roku_builder/inspector_test.rb +3 -0
- data/tests/roku_builder/keyer_test.rb +3 -2
- data/tests/roku_builder/linker_test.rb +2 -1
- data/tests/roku_builder/loader_test.rb +2 -0
- data/tests/roku_builder/manifest_manager_test.rb +3 -6
- data/tests/roku_builder/monitor_test.rb +5 -13
- data/tests/roku_builder/navigator_test.rb +2 -0
- data/tests/roku_builder/test_helper.rb +38 -0
- 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 =
|
|
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.
|
|
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.
|
|
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 =
|
|
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 =
|
|
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
|
|
data/lib/roku_builder/keyer.rb
CHANGED
|
@@ -12,18 +12,13 @@ module RokuBuilder
|
|
|
12
12
|
|
|
13
13
|
# upload new key with password
|
|
14
14
|
path = "/plugin_inspect"
|
|
15
|
-
conn =
|
|
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
|
-
|
|
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 =
|
|
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)
|
data/lib/roku_builder/linker.rb
CHANGED
|
@@ -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
|
-
|
|
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 =
|
|
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
|
-
|
|
31
|
+
params.collect{|k,v| "#{k}=#{CGI.escape(v)}"}.join('&')
|
|
44
32
|
end
|
|
45
33
|
end
|
|
46
34
|
end
|
data/lib/roku_builder/loader.rb
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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
|
|
21
|
+
build_version = ManifestManager.update_build(root_dir: root_dir)
|
|
40
22
|
else
|
|
41
|
-
build_version = ManifestManager.build_version(root_dir: root_dir
|
|
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 =
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
141
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
|
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|
|
data/lib/roku_builder/monitor.rb
CHANGED
|
@@ -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) {|
|
|
32
|
-
@logger.info "Monitoring #{type} console(#{
|
|
33
|
-
connection = Net::Telnet.new(
|
|
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(
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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,
|