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
data/.travis.yml
ADDED
data/Gemfile.lock
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
roku_builder (3.3.
|
|
4
|
+
roku_builder (3.3.4)
|
|
5
5
|
faraday (~> 0.9)
|
|
6
6
|
faraday-digestauth (~> 0.2)
|
|
7
|
-
git (~> 1.
|
|
7
|
+
git (~> 1.3)
|
|
8
8
|
net-ping (~> 1.7)
|
|
9
|
-
rubyzip (~> 1.
|
|
9
|
+
rubyzip (~> 1.2)
|
|
10
10
|
|
|
11
11
|
GEM
|
|
12
12
|
remote: https://rubygems.org/
|
|
13
13
|
specs:
|
|
14
|
-
byebug (
|
|
15
|
-
columnize (~> 0.8)
|
|
16
|
-
debugger-linecache (~> 1.2)
|
|
17
|
-
slop (~> 3.6)
|
|
14
|
+
byebug (8.2.2)
|
|
18
15
|
coderay (1.1.0)
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
coveralls (0.8.13)
|
|
17
|
+
json (~> 1.8)
|
|
18
|
+
simplecov (~> 0.11.0)
|
|
19
|
+
term-ansicolor (~> 1.3)
|
|
20
|
+
thor (~> 0.19.1)
|
|
21
|
+
tins (~> 1.6.0)
|
|
21
22
|
docile (1.1.5)
|
|
22
23
|
em-websocket (0.5.1)
|
|
23
24
|
eventmachine (>= 0.12.9)
|
|
@@ -30,7 +31,7 @@ GEM
|
|
|
30
31
|
net-http-digest_auth (~> 1.4)
|
|
31
32
|
ffi (1.9.10)
|
|
32
33
|
formatador (0.2.5)
|
|
33
|
-
git (1.
|
|
34
|
+
git (1.3.0)
|
|
34
35
|
guard (2.13.0)
|
|
35
36
|
formatador (>= 0.2.4)
|
|
36
37
|
listen (>= 2.7, <= 4.0)
|
|
@@ -70,11 +71,11 @@ GEM
|
|
|
70
71
|
coderay (~> 1.1.0)
|
|
71
72
|
method_source (~> 0.8.1)
|
|
72
73
|
slop (~> 3.4)
|
|
73
|
-
rake (
|
|
74
|
+
rake (11.1.1)
|
|
74
75
|
rb-fsevent (0.9.7)
|
|
75
76
|
rb-inotify (0.9.7)
|
|
76
77
|
ffi (>= 0.5.0)
|
|
77
|
-
rubyzip (1.
|
|
78
|
+
rubyzip (1.2.0)
|
|
78
79
|
shellany (0.0.1)
|
|
79
80
|
simplecov (0.11.2)
|
|
80
81
|
docile (~> 1.1.0)
|
|
@@ -82,7 +83,10 @@ GEM
|
|
|
82
83
|
simplecov-html (~> 0.10.0)
|
|
83
84
|
simplecov-html (0.10.0)
|
|
84
85
|
slop (3.6.0)
|
|
86
|
+
term-ansicolor (1.3.2)
|
|
87
|
+
tins (~> 1.0)
|
|
85
88
|
thor (0.19.1)
|
|
89
|
+
tins (1.6.0)
|
|
86
90
|
yard (0.8.7.6)
|
|
87
91
|
|
|
88
92
|
PLATFORMS
|
|
@@ -90,12 +94,13 @@ PLATFORMS
|
|
|
90
94
|
|
|
91
95
|
DEPENDENCIES
|
|
92
96
|
bundler (~> 1.7)
|
|
93
|
-
byebug (~>
|
|
97
|
+
byebug (~> 8.2)
|
|
98
|
+
coveralls (~> 0.8)
|
|
94
99
|
guard-livereload (~> 2.5)
|
|
95
100
|
minitest (~> 5.8)
|
|
96
101
|
minitest-autotest (~> 1.0)
|
|
97
102
|
minitest-server (~> 1.0)
|
|
98
|
-
rake (~>
|
|
103
|
+
rake (~> 11.1)
|
|
99
104
|
roku_builder!
|
|
100
105
|
simplecov (~> 0.11)
|
|
101
106
|
yard (~> 0.8.7)
|
data/README.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# RokuBuilder
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/rb/roku_builder)
|
|
4
|
+
[](https://gemnasium.com/ViacomInc/roku_builder)
|
|
5
|
+
[](https://travis-ci.org/ViacomInc/roku_builder)
|
|
6
|
+
[](https://coveralls.io/github/ViacomInc/roku_builder?branch=master)
|
|
7
|
+
[](https://codeclimate.com/github/ViacomInc/roku_builder)
|
|
4
8
|
|
|
5
9
|
A tool to help with Roku Development. Assists with the following roku
|
|
6
10
|
development tasks:
|
|
@@ -271,6 +275,7 @@ directory:
|
|
|
271
275
|
|
|
272
276
|
* Account for missing folders or files
|
|
273
277
|
* Increase testing
|
|
278
|
+
* Config Unit Tests
|
|
274
279
|
* Intergration Tests
|
|
275
280
|
* Move RokuBuilder::Controller to RokuBuilder?
|
|
276
281
|
* Allow start and end delimiter for tests to be configured
|
data/bin/roku
CHANGED
|
@@ -11,80 +11,79 @@ options = {}
|
|
|
11
11
|
options[:config] = '~/.roku_config.json'
|
|
12
12
|
options[:stage] = 'production'
|
|
13
13
|
options[:update_manifest] = false
|
|
14
|
-
options[:fetch] = false
|
|
15
14
|
|
|
16
15
|
OptionParser.new do |opts|
|
|
17
16
|
opts.banner = "Usage: roku <command> [options]"
|
|
18
17
|
|
|
19
|
-
opts.on("-l", "--sideload", "Command: Sideload an app") do
|
|
20
|
-
options[:sideload] =
|
|
18
|
+
opts.on("-l", "--sideload", "Command: Sideload an app") do
|
|
19
|
+
options[:sideload] = true
|
|
21
20
|
end
|
|
22
21
|
|
|
23
|
-
opts.on("-p", "--package", "Command: Package an app") do
|
|
24
|
-
options[:package] =
|
|
22
|
+
opts.on("-p", "--package", "Command: Package an app") do
|
|
23
|
+
options[:package] = true
|
|
25
24
|
end
|
|
26
25
|
|
|
27
|
-
opts.on("-t", "--test", "Command: Test an app") do
|
|
28
|
-
options[:test] =
|
|
26
|
+
opts.on("-t", "--test", "Command: Test an app") do
|
|
27
|
+
options[:test] = true
|
|
29
28
|
end
|
|
30
29
|
|
|
31
|
-
opts.on("-L", "--deeplink", "Command: Deeplink into app. Requires mgid and type options.") do
|
|
32
|
-
options[:deeplink] =
|
|
30
|
+
opts.on("-L", "--deeplink", "Command: Deeplink into app. Requires mgid and type options.") do
|
|
31
|
+
options[:deeplink] = true
|
|
33
32
|
end
|
|
34
33
|
|
|
35
|
-
opts.on("--configure", "Command: Copy base configuration file to the --config location. Default: '~/.roku_config.json'") do
|
|
36
|
-
options[:configure] =
|
|
34
|
+
opts.on("--configure", "Command: Copy base configuration file to the --config location. Default: '~/.roku_config.json'") do
|
|
35
|
+
options[:configure] = true
|
|
37
36
|
end
|
|
38
37
|
|
|
39
|
-
opts.on("--validate", "Command: Validate configuration'") do
|
|
40
|
-
options[:validate] =
|
|
38
|
+
opts.on("--validate", "Command: Validate configuration'") do
|
|
39
|
+
options[:validate] = true
|
|
41
40
|
end
|
|
42
41
|
|
|
43
|
-
opts.on("-d", "--delete", "Command: Delete the currently sideloaded app") do
|
|
44
|
-
options[:delete] =
|
|
42
|
+
opts.on("-d", "--delete", "Command: Delete the currently sideloaded app") do
|
|
43
|
+
options[:delete] = true
|
|
45
44
|
end
|
|
46
45
|
|
|
47
46
|
opts.on("-N", "--navigate CMD", "Command: send the given command to the roku") do |n|
|
|
48
47
|
options[:navigate] = n
|
|
49
48
|
end
|
|
50
49
|
|
|
51
|
-
opts.on("-S", "--screencapture", "Command: save a screencapture to the output file/folder") do
|
|
52
|
-
options[:screencapture] =
|
|
50
|
+
opts.on("-S", "--screencapture", "Command: save a screencapture to the output file/folder") do
|
|
51
|
+
options[:screencapture] = true
|
|
53
52
|
end
|
|
54
53
|
|
|
55
54
|
opts.on("-y", "--type TEXT", "Command: type the given text on the roku device") do |t|
|
|
56
55
|
options[:text] = t
|
|
57
56
|
end
|
|
58
57
|
|
|
59
|
-
opts.on("-b", "--build", "Command: build a zip to be sideloaded") do
|
|
60
|
-
options[:build] =
|
|
58
|
+
opts.on("-b", "--build", "Command: build a zip to be sideloaded") do
|
|
59
|
+
options[:build] = true
|
|
61
60
|
end
|
|
62
61
|
|
|
63
62
|
opts.on("--screen SCREEN", "Command: show a screen") do |s|
|
|
64
63
|
options[:screen] = s
|
|
65
64
|
end
|
|
66
65
|
|
|
67
|
-
opts.on("--screens", "Command: show possible screens") do
|
|
68
|
-
options[:screens] =
|
|
66
|
+
opts.on("--screens", "Command: show possible screens") do
|
|
67
|
+
options[:screens] = true
|
|
69
68
|
end
|
|
70
69
|
|
|
71
70
|
opts.on("-m", "--monitor TYPE", "Command: run telnet to monitor roku log") do |m|
|
|
72
71
|
options[:monitor] = m
|
|
73
72
|
end
|
|
74
73
|
|
|
75
|
-
opts.on("-u", "--update-manifest", "Command: update the manifest file") do
|
|
76
|
-
options[:update] =
|
|
74
|
+
opts.on("-u", "--update-manifest", "Command: update the manifest file") do
|
|
75
|
+
options[:update] = true
|
|
77
76
|
end
|
|
78
77
|
|
|
79
78
|
opts.on("-r", "--ref REF", "Git referance to use for sideloading") do |r|
|
|
80
79
|
options[:ref] = r
|
|
81
80
|
end
|
|
82
81
|
|
|
83
|
-
opts.on("-w", "--working", "Use working directory to sideload or test") do
|
|
84
|
-
options[:working] =
|
|
82
|
+
opts.on("-w", "--working", "Use working directory to sideload or test") do
|
|
83
|
+
options[:working] = true
|
|
85
84
|
end
|
|
86
85
|
|
|
87
|
-
opts.on("-c", "--current", "Use current directory to sideload or test. Overides any project config") do
|
|
86
|
+
opts.on("-c", "--current", "Use current directory to sideload or test. Overides any project config") do
|
|
88
87
|
options[:current] = true
|
|
89
88
|
end
|
|
90
89
|
|
|
@@ -93,18 +92,14 @@ OptionParser.new do |opts|
|
|
|
93
92
|
options[:set_stage] = true
|
|
94
93
|
end
|
|
95
94
|
|
|
96
|
-
opts.on("-M", "--manifest-update", "Update the manifest file while packaging") do
|
|
95
|
+
opts.on("-M", "--manifest-update", "Update the manifest file while packaging") do
|
|
97
96
|
options[:update_manifest] = true
|
|
98
97
|
end
|
|
99
98
|
|
|
100
|
-
opts.on("-i", "--inspect", "Print inspection information while packaging") do
|
|
99
|
+
opts.on("-i", "--inspect", "Print inspection information while packaging") do
|
|
101
100
|
options[:inspect] = true
|
|
102
101
|
end
|
|
103
102
|
|
|
104
|
-
opts.on("-f", "--fetch", "Preform a `git fetch --all` on the repository before building or sideloading.") do
|
|
105
|
-
options[:fetch] = true
|
|
106
|
-
end
|
|
107
|
-
|
|
108
103
|
opts.on("-o", "--deeplink-options TYPE", "Additional deeplink options. (eg. a:b, c:d,e:f)") do |o|
|
|
109
104
|
options[:deeplink_options] = o
|
|
110
105
|
end
|
|
@@ -134,15 +129,15 @@ OptionParser.new do |opts|
|
|
|
134
129
|
options[:in] = i
|
|
135
130
|
end
|
|
136
131
|
|
|
137
|
-
opts.on("-V", "--verbose", "Print Info message") do
|
|
138
|
-
options[:verbose] =
|
|
132
|
+
opts.on("-V", "--verbose", "Print Info message") do
|
|
133
|
+
options[:verbose] = true
|
|
139
134
|
end
|
|
140
135
|
|
|
141
|
-
opts.on("--debug", "Print Debug messages") do
|
|
142
|
-
options[:debug] =
|
|
136
|
+
opts.on("--debug", "Print Debug messages") do
|
|
137
|
+
options[:debug] = true
|
|
143
138
|
end
|
|
144
139
|
|
|
145
|
-
opts.on("-h", "--help", "Show this message") do
|
|
140
|
+
opts.on("-h", "--help", "Show this message") do
|
|
146
141
|
puts opts
|
|
147
142
|
exit
|
|
148
143
|
end
|
data/config.json.example
CHANGED
|
@@ -1,25 +1,44 @@
|
|
|
1
1
|
module RokuBuilder
|
|
2
2
|
|
|
3
|
-
MISSING_DEVICES = 1
|
|
4
|
-
MISSING_DEVICES_DEFAULT = 2
|
|
5
|
-
DEVICE_DEFAULT_BAD = 3
|
|
6
|
-
MISSING_PROJECTS = 4
|
|
7
|
-
MISSING_PROJECTS_DEFAULT = 5
|
|
8
|
-
PROJECTS_DEFAULT_BAD = 6
|
|
9
|
-
DEVICE_MISSING_IP = 7
|
|
10
|
-
DEVICE_MISSING_USER = 8
|
|
11
|
-
DEVICE_MISSING_PASSWORD = 9
|
|
12
|
-
PROJECT_MISSING_APP_NAME = 10
|
|
13
|
-
PROJECT_MISSING_DIRECTORY = 11
|
|
14
|
-
PROJECT_MISSING_FOLDERS = 12
|
|
15
|
-
PROJECT_FOLDERS_BAD = 13
|
|
16
|
-
PROJECT_MISSING_FILES = 14
|
|
17
|
-
PROJECT_FILES_BAD = 15
|
|
18
|
-
STAGE_MISSING_BRANCH = 16
|
|
19
|
-
|
|
20
3
|
# Load and validate config files.
|
|
21
4
|
class ConfigManager
|
|
22
5
|
|
|
6
|
+
# Load config file and generate intermeidate configs
|
|
7
|
+
# @param options [Hash] The options hash
|
|
8
|
+
# @param logger [Logger] system logger
|
|
9
|
+
# @return [Integer] Return code
|
|
10
|
+
# @return [Hash] Loaded config
|
|
11
|
+
# @return [Hash] Intermeidate configs
|
|
12
|
+
def self.load_config(options:, logger:)
|
|
13
|
+
config_file = File.expand_path(options[:config])
|
|
14
|
+
return MISSING_CONFIG unless File.exist?(config_file)
|
|
15
|
+
code = SUCCESS
|
|
16
|
+
config = ConfigManager.get_config(config: config_file, logger: logger)
|
|
17
|
+
return INVALID_CONFIG unless config
|
|
18
|
+
codes = ConfigValidator.validate_config(config: config)
|
|
19
|
+
fatal = false
|
|
20
|
+
warning = false
|
|
21
|
+
codes.each {|a_code|
|
|
22
|
+
if a_code > 0
|
|
23
|
+
logger.fatal "Invalid Config: "+ ConfigValidator.error_codes()[a_code]
|
|
24
|
+
fatal = true
|
|
25
|
+
elsif a_code < 0
|
|
26
|
+
logger.warn "Depricated Config: "+ ConfigValidator.error_codes()[a_code]
|
|
27
|
+
warning = true
|
|
28
|
+
elsif a_code == 0 and options[:validate]
|
|
29
|
+
logger.info "Config Valid"
|
|
30
|
+
end
|
|
31
|
+
}
|
|
32
|
+
return [INVALID_CONFIG, nil, nil] if fatal
|
|
33
|
+
code = DEPRICATED_CONFIG if warning
|
|
34
|
+
|
|
35
|
+
parse_code, configs = ConfigParser.parse_config(options: options, config: config, logger: logger)
|
|
36
|
+
unless parse_code == SUCCESS
|
|
37
|
+
return [parse_code, nil, nil]
|
|
38
|
+
end
|
|
39
|
+
[code, config, configs]
|
|
40
|
+
end
|
|
41
|
+
|
|
23
42
|
# Loads the roku config from file
|
|
24
43
|
# @param config [String] path for the roku config
|
|
25
44
|
# @return [Hash] roku config object
|
|
@@ -35,75 +54,6 @@ module RokuBuilder
|
|
|
35
54
|
end
|
|
36
55
|
end
|
|
37
56
|
|
|
38
|
-
# Validates the roku config
|
|
39
|
-
# @param config [Hash] roku config object
|
|
40
|
-
# @return [Array] error codes for valid config (see self.error_codes)
|
|
41
|
-
def self.validate_config(config:, logger:)
|
|
42
|
-
codes = []
|
|
43
|
-
codes.push(MISSING_DEVICES) if not config[:devices]
|
|
44
|
-
codes.push(MISSING_DEVICES_DEFAULT) if config[:devices] and not config[:devices][:default]
|
|
45
|
-
codes.push(DEVICE_DEFAULT_BAD) if config[:devices] and config[:devices][:default] and not config[:devices][:default].is_a?(Symbol)
|
|
46
|
-
codes.push(MISSING_PROJECTS) if not config[:projects]
|
|
47
|
-
codes.push(MISSING_PROJECTS_DEFAULT) if config[:projects] and not config[:projects][:default]
|
|
48
|
-
codes.push(MISSING_PROJECTS_DEFAULT) if config[:projects] and config[:projects][:default] == "<project id>".to_sym
|
|
49
|
-
codes.push(PROJECTS_DEFAULT_BAD) if config[:projects] and config[:projects][:default] and not config[:projects][:default].is_a?(Symbol)
|
|
50
|
-
if config[:devices]
|
|
51
|
-
config[:devices].each {|k,v|
|
|
52
|
-
next if k == :default
|
|
53
|
-
codes.push(DEVICE_MISSING_IP) if not v[:ip]
|
|
54
|
-
codes.push(DEVICE_MISSING_IP) if v[:ip] == "xxx.xxx.xxx.xxx"
|
|
55
|
-
codes.push(DEVICE_MISSING_IP) if v[:ip] == ""
|
|
56
|
-
codes.push(DEVICE_MISSING_USER) if not v[:user]
|
|
57
|
-
codes.push(DEVICE_MISSING_USER) if v[:user] == "<username>"
|
|
58
|
-
codes.push(DEVICE_MISSING_USER) if v[:user] == ""
|
|
59
|
-
codes.push(DEVICE_MISSING_PASSWORD) if not v[:password]
|
|
60
|
-
codes.push(DEVICE_MISSING_PASSWORD) if v[:password] == "<password>"
|
|
61
|
-
codes.push(DEVICE_MISSING_PASSWORD) if v[:password] == ""
|
|
62
|
-
}
|
|
63
|
-
end
|
|
64
|
-
if config[:projects]
|
|
65
|
-
config[:projects].each {|k,v|
|
|
66
|
-
next if k == :default
|
|
67
|
-
codes.push(PROJECT_MISSING_APP_NAME) if not v[:app_name]
|
|
68
|
-
codes.push(PROJECT_MISSING_DIRECTORY) if not v[:directory]
|
|
69
|
-
codes.push(PROJECT_MISSING_FOLDERS) if not v[:folders]
|
|
70
|
-
codes.push(PROJECT_FOLDERS_BAD) if v[:folders] and not v[:folders].is_a?(Array)
|
|
71
|
-
codes.push(PROJECT_MISSING_FILES) if not v[:files]
|
|
72
|
-
codes.push(PROJECT_FILES_BAD) if v[:files] and not v[:files].is_a?(Array)
|
|
73
|
-
v[:stages].each {|k,v|
|
|
74
|
-
codes.push(STAGE_MISSING_BRANCH) if not v[:branch]
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
end
|
|
78
|
-
codes.push(0) if codes.empty?
|
|
79
|
-
codes
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# Error code messages for config validation
|
|
83
|
-
# @return [Array] error code messages
|
|
84
|
-
def self.error_codes()
|
|
85
|
-
[
|
|
86
|
-
#===============FATAL ERRORS===============#
|
|
87
|
-
"Valid Config.",
|
|
88
|
-
"Devices config is missing.",
|
|
89
|
-
"Devices default is missing.",
|
|
90
|
-
"Devices default is not a hash.",
|
|
91
|
-
"Projects config is missing.",
|
|
92
|
-
"Projects default is missing.", #5
|
|
93
|
-
"Projects default is not a hash.",
|
|
94
|
-
"A device config is missing its IP address.",
|
|
95
|
-
"A device config is missing its username.",
|
|
96
|
-
"A device config is missing its password.",
|
|
97
|
-
"A project config is missing its app_name.", #10
|
|
98
|
-
"A project config is missing its directorty.",
|
|
99
|
-
"A project config is missing its folders.",
|
|
100
|
-
"A project config's folders is not an array.",
|
|
101
|
-
"A project config is missing its files.",
|
|
102
|
-
"A project config's files is not an array.", #15
|
|
103
|
-
"A project stage is missing its branch."
|
|
104
|
-
#===============WARNINGS===============#
|
|
105
|
-
]
|
|
106
|
-
end
|
|
107
57
|
|
|
108
58
|
# Edit the roku config
|
|
109
59
|
# @param config [String] path for the roku config
|
|
@@ -112,46 +62,61 @@ module RokuBuilder
|
|
|
112
62
|
# @param project [String] which project to use
|
|
113
63
|
# @param stage[String] which stage to use
|
|
114
64
|
# @return [Boolean] success
|
|
115
|
-
def self.edit_config(config:, options:,
|
|
65
|
+
def self.edit_config(config:, options:, logger:)
|
|
116
66
|
config_object = get_config(config: config, logger: logger)
|
|
117
67
|
return false unless config_object
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
unless
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
device
|
|
127
|
-
|
|
128
|
-
unless stage
|
|
129
|
-
stage = :production
|
|
130
|
-
else
|
|
131
|
-
stage = stage.to_sym
|
|
132
|
-
end
|
|
133
|
-
changes = {}
|
|
134
|
-
opts = options.split(/,\s*/)
|
|
135
|
-
opts.each do |opt|
|
|
136
|
-
opt = opt.split(":")
|
|
137
|
-
key = opt.shift.to_sym
|
|
138
|
-
value = opt.join(":")
|
|
139
|
-
changes[key] = value
|
|
140
|
-
end
|
|
141
|
-
changes.each {|key,value|
|
|
142
|
-
if [:ip, :user, :password].include?(key)
|
|
143
|
-
config_object[:devices][device][key] = value
|
|
144
|
-
elsif [:directory, :app_name].include?(key) #:folders, :files
|
|
145
|
-
config_object[:projects][project][key] = value
|
|
146
|
-
elsif [:branch]
|
|
147
|
-
config_object[:projects][project][:stages][stage][key] = value
|
|
148
|
-
end
|
|
68
|
+
project = options[:project].to_sym if options[:project]
|
|
69
|
+
project = config_object[:projects][:default] unless options[:project]
|
|
70
|
+
device = options[:device].to_sym if options[:device]
|
|
71
|
+
device = config_object[:devices][:default] unless options[:device]
|
|
72
|
+
stage = options[:stage].to_sym if options[:stage]
|
|
73
|
+
stage = :production unless options[:stage]
|
|
74
|
+
state = {
|
|
75
|
+
project: project,
|
|
76
|
+
device: device,
|
|
77
|
+
stage: stage
|
|
149
78
|
}
|
|
79
|
+
apply_options(config_object: config_object, options: options[:edit_params], state: state)
|
|
150
80
|
config_string = JSON.pretty_generate(config_object)
|
|
151
81
|
file = File.open(config, "w")
|
|
152
82
|
file.write(config_string)
|
|
153
83
|
file.close
|
|
154
84
|
return true
|
|
155
85
|
end
|
|
86
|
+
|
|
87
|
+
# Apply the changes in the options string to the config object
|
|
88
|
+
# @param config_object [Hash] The config loaded from file
|
|
89
|
+
# @param options [String] The string of options passed in by the user
|
|
90
|
+
# @param state [Hash] The state of the config the user is editing
|
|
91
|
+
def self.apply_options(config_object:, options:, state:)
|
|
92
|
+
changes = Util.options_parse(options: options)
|
|
93
|
+
changes.each {|key,value|
|
|
94
|
+
if [:ip, :user, :password].include?(key)
|
|
95
|
+
config_object[:devices][state[:device]][key] = value
|
|
96
|
+
elsif [:directory, :app_name].include?(key) #:folders, :files
|
|
97
|
+
config_object[:projects][state[:project]][key] = value
|
|
98
|
+
elsif [:branch].include?(key)
|
|
99
|
+
config_object[:projects][state[:project]][:stages][state[:stage]][key] = value
|
|
100
|
+
end
|
|
101
|
+
}
|
|
102
|
+
end
|
|
103
|
+
private_class_method :apply_options
|
|
104
|
+
|
|
105
|
+
# Update the intermeidate configs
|
|
106
|
+
# @param configs [Hash] Intermeidate configs hash
|
|
107
|
+
# @param options [Hash] Options hash
|
|
108
|
+
# @return [Hash] New intermeidate configs hash
|
|
109
|
+
def self.update_configs(configs:, options:)
|
|
110
|
+
if options[:build_version]
|
|
111
|
+
configs[:package_config][:app_name_version] = "#{configs[:project_config][:app_name]} - #{configs[:stage]} - #{options[:build_version]}" if configs[:package_config]
|
|
112
|
+
unless options[:outfile]
|
|
113
|
+
pathname = File.join(options[:out_folder], "#{configs[:project_config][:app_name]}_#{configs[:stage]}_#{options[:build_version]}")
|
|
114
|
+
configs[:package_config][:out_file] = pathname+".pkg" if configs[:package_config]
|
|
115
|
+
configs[:build_config][:outfile] = pathname+".zip" if configs[:build_config]
|
|
116
|
+
configs[:inspect_config][:pkg] = configs[:package_config][:out_file] if configs[:inspect_config] and configs[:package_config]
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
return configs
|
|
120
|
+
end
|
|
156
121
|
end
|
|
157
122
|
end
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
module RokuBuilder
|
|
2
|
+
|
|
3
|
+
# Contains methods that will parse the loaded config and generate
|
|
4
|
+
# intermeidate configs for each of the tools.
|
|
5
|
+
class ConfigParser
|
|
6
|
+
|
|
7
|
+
# Parse config and generate intermeidate configs
|
|
8
|
+
# @param options [Hash] The options hash
|
|
9
|
+
# @param config [Hash] The loaded config hash
|
|
10
|
+
# @param logger [Logger] system logger
|
|
11
|
+
# @return [Integer] Return code
|
|
12
|
+
# @return [Hash] Intermeidate configs
|
|
13
|
+
def self.parse_config(options:, config:, logger:)
|
|
14
|
+
configs = {}
|
|
15
|
+
#set device
|
|
16
|
+
unless options[:device]
|
|
17
|
+
options[:device] = config[:devices][:default]
|
|
18
|
+
end
|
|
19
|
+
#set project
|
|
20
|
+
setup_project(config: config, options: options)
|
|
21
|
+
#set outfile
|
|
22
|
+
setup_outfile(options: options)
|
|
23
|
+
# Create Device Config
|
|
24
|
+
configs[:device_config] = config[:devices][options[:device].to_sym]
|
|
25
|
+
return [UNKNOWN_DEVICE, nil, nil] unless configs[:device_config]
|
|
26
|
+
configs[:device_config][:logger] = logger
|
|
27
|
+
project_config = setup_project_config(config: config, options: options)
|
|
28
|
+
return [UNKNOWN_PROJECT, nil, nil] unless project_config
|
|
29
|
+
configs[:project_config] = project_config
|
|
30
|
+
stage = options[:stage].to_sym
|
|
31
|
+
return [UNKNOWN_STAGE, nil, nil] unless project_config[:stages][stage]
|
|
32
|
+
configs[:stage] = stage
|
|
33
|
+
branch = project_config[:stages][stage][:branch]
|
|
34
|
+
branch = options[:ref] if options[:ref]
|
|
35
|
+
branch = nil if options[:current]
|
|
36
|
+
branch = nil if options[:working]
|
|
37
|
+
setup_sideload_config(configs: configs, options: options, branch: branch)
|
|
38
|
+
setup_package_config(configs: configs, options: options, stage: stage)
|
|
39
|
+
setup_simple_configs(configs: configs, options: options, logger: logger)
|
|
40
|
+
return [SUCCESS, configs]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Pick or choose the project being used
|
|
44
|
+
# @param config [Hash] The loaded config hash
|
|
45
|
+
# @param options [Hash] The options hash
|
|
46
|
+
def self.setup_project(config:, options:)
|
|
47
|
+
if options[:current] or not options[:project]
|
|
48
|
+
path = Controller.system(command: "pwd")
|
|
49
|
+
project = nil
|
|
50
|
+
config[:projects].each_pair {|key,value|
|
|
51
|
+
if value.is_a?(Hash)
|
|
52
|
+
repo_path = Pathname.new(value[:directory]).realdirpath.to_s
|
|
53
|
+
if path.start_with?(repo_path)
|
|
54
|
+
project = key
|
|
55
|
+
break
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
}
|
|
59
|
+
if project
|
|
60
|
+
options[:project] = project
|
|
61
|
+
else
|
|
62
|
+
options[:project] = config[:projects][:default]
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
private_class_method :setup_project
|
|
67
|
+
|
|
68
|
+
# Setup the out folder/file options
|
|
69
|
+
# @param options [Hash] The options hash
|
|
70
|
+
def self.setup_outfile(options:)
|
|
71
|
+
options[:out_folder] = nil
|
|
72
|
+
options[:out_file] = nil
|
|
73
|
+
if options[:out]
|
|
74
|
+
if options[:out].end_with?(".zip") or options[:out].end_with?(".pkg") or options[:out].end_with?(".jpg")
|
|
75
|
+
options[:out_folder], options[:out_file] = Pathname.new(options[:out]).split.map{|p| p.to_s}
|
|
76
|
+
else
|
|
77
|
+
options[:out_folder] = options[:out]
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
unless options[:out_folder]
|
|
81
|
+
options[:out_folder] = "/tmp"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
private_class_method :setup_outfile
|
|
85
|
+
|
|
86
|
+
# Setup the project config with the chosen project
|
|
87
|
+
# @param config [Hash] The loaded config hash
|
|
88
|
+
# @param options [Hash] The options hash
|
|
89
|
+
# @return [Hash] The project config hash
|
|
90
|
+
def self.setup_project_config(config:, options:)
|
|
91
|
+
#Create Project Config
|
|
92
|
+
project_config = {}
|
|
93
|
+
if options[:current]
|
|
94
|
+
pwd = Controller.system(command: "pwd")
|
|
95
|
+
return [MISSING_MANIFEST, nil, nil] unless File.exist?(File.join(pwd, "manifest"))
|
|
96
|
+
project_config = {
|
|
97
|
+
directory: pwd,
|
|
98
|
+
folders: nil,
|
|
99
|
+
files: nil,
|
|
100
|
+
stages: { production: { branch: nil } }
|
|
101
|
+
}
|
|
102
|
+
else
|
|
103
|
+
project_config = config[:projects][options[:project].to_sym]
|
|
104
|
+
end
|
|
105
|
+
project_config
|
|
106
|
+
end
|
|
107
|
+
private_class_method :setup_project_config
|
|
108
|
+
|
|
109
|
+
# Setup config hashes for sideloading
|
|
110
|
+
# @param configs [Hash] The parsed configs hash
|
|
111
|
+
# @param options [Hash] The options hash
|
|
112
|
+
# @param branch [String] the branch to sideload
|
|
113
|
+
def self.setup_sideload_config(configs:, options:, branch:)
|
|
114
|
+
root_dir = configs[:project_config][:directory]
|
|
115
|
+
# Create Sideload Config
|
|
116
|
+
configs[:sideload_config] = {
|
|
117
|
+
root_dir: root_dir,
|
|
118
|
+
branch: branch,
|
|
119
|
+
update_manifest: options[:update_manifest],
|
|
120
|
+
folders: configs[:project_config][:folders],
|
|
121
|
+
files: configs[:project_config][:files]
|
|
122
|
+
}
|
|
123
|
+
# Create Build Config
|
|
124
|
+
configs[:build_config] = {
|
|
125
|
+
root_dir: root_dir,
|
|
126
|
+
branch: branch,
|
|
127
|
+
folders: configs[:project_config][:folders],
|
|
128
|
+
files: configs[:project_config][:files]
|
|
129
|
+
}
|
|
130
|
+
end
|
|
131
|
+
private_class_method :setup_sideload_config
|
|
132
|
+
|
|
133
|
+
# Setup config hashes for packaging
|
|
134
|
+
# @param configs [Hash] The parsed configs hash
|
|
135
|
+
# @param options [Hash] The options hash
|
|
136
|
+
# @param stage [Symbol] The stage to package
|
|
137
|
+
def self.setup_package_config(configs:, options:, stage:)
|
|
138
|
+
if options[:package]
|
|
139
|
+
# Create Key Config
|
|
140
|
+
configs[:key] = configs[:project_config][:stages][stage][:key]
|
|
141
|
+
# Create Package Config
|
|
142
|
+
configs[:package_config] = {
|
|
143
|
+
password: configs[:key][:password],
|
|
144
|
+
app_name_version: "#{configs[:project_config][:app_name]} - #{stage}"
|
|
145
|
+
}
|
|
146
|
+
if options[:out_file]
|
|
147
|
+
configs[:package_config][:out_file] = File.join(options[:out_folder], options[:out_file])
|
|
148
|
+
end
|
|
149
|
+
# Create Inspector Config
|
|
150
|
+
configs[:inspect_config] = {
|
|
151
|
+
pkg: configs[:package_config][:out_file],
|
|
152
|
+
password: configs[:key][:password]
|
|
153
|
+
}
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
private_class_method :setup_package_config
|
|
157
|
+
|
|
158
|
+
# Setup other configs
|
|
159
|
+
# @param configs [Hash] The parsed configs hash
|
|
160
|
+
# @param options [Hash] The options hash
|
|
161
|
+
# @param logger [Logger] System logger
|
|
162
|
+
def self.setup_simple_configs(configs:, options:, logger:)
|
|
163
|
+
# Create Manifest Config
|
|
164
|
+
configs[:manifest_config] = {
|
|
165
|
+
root_dir: configs[:project_config][:directory]
|
|
166
|
+
}
|
|
167
|
+
# Create Deeplink Config
|
|
168
|
+
configs[:deeplink_config] ={options: options[:deeplink_options]}
|
|
169
|
+
# Create Monitor Config
|
|
170
|
+
if options[:monitor]
|
|
171
|
+
configs[:monitor_config] = {type: options[:monitor].to_sym}
|
|
172
|
+
end
|
|
173
|
+
# Create Navigate Config
|
|
174
|
+
if options[:navigate]
|
|
175
|
+
configs[:navigate_config] = {command: options[:navigate].to_sym}
|
|
176
|
+
end
|
|
177
|
+
# Create Text Config
|
|
178
|
+
configs[:text_config] = {text: options[:text]}
|
|
179
|
+
# Create Test Config
|
|
180
|
+
configs[:test_config] = {sideload_config: configs[:sideload_config]}
|
|
181
|
+
#Create screencapture config
|
|
182
|
+
configs[:screencapture_config] = {
|
|
183
|
+
out_folder: options[:out_folder],
|
|
184
|
+
out_file: options[:out_file]
|
|
185
|
+
}
|
|
186
|
+
if options[:screen]
|
|
187
|
+
configs[:screen_config] = {type: options[:screen].to_sym}
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
private_class_method :setup_simple_configs
|
|
191
|
+
end
|
|
192
|
+
end
|