roku_builder 4.7.2 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +8 -0
  3. data/Gemfile.lock +4 -2
  4. data/lib/roku_builder/hash.rb +3 -0
  5. data/lib/roku_builder/manifest.rb +4 -0
  6. data/lib/roku_builder/plugins/analyzer.rb +102 -0
  7. data/lib/roku_builder/plugins/inspector_config.json +358 -0
  8. data/lib/roku_builder/plugins/line_inspector.rb +50 -0
  9. data/lib/roku_builder/plugins/loader.rb +17 -0
  10. data/lib/roku_builder/plugins/manifest_attributes.json +229 -0
  11. data/lib/roku_builder/plugins/manifest_inspector.rb +142 -0
  12. data/lib/roku_builder/plugins/raf_inspector.rb +74 -0
  13. data/lib/roku_builder/version.rb +1 -1
  14. data/lib/roku_builder.rb +2 -0
  15. data/roku_builder.gemspec +1 -0
  16. data/test/roku_builder/plugins/test_analyzer.rb +344 -0
  17. data/test/roku_builder/plugins/test_loader.rb +9 -0
  18. data/test/roku_builder/test_config_parser.rb +1 -1
  19. data/test/roku_builder/test_files/analyzer_test/analyzer_config.json +1 -0
  20. data/test/roku_builder/test_files/analyzer_test/images/focus.png +0 -0
  21. data/test/roku_builder/test_files/analyzer_test/images/focus_hd.png +0 -0
  22. data/test/roku_builder/test_files/analyzer_test/images/focus_sd.png +0 -0
  23. data/test/roku_builder/test_files/analyzer_test/images/splash.png +0 -0
  24. data/test/roku_builder/test_files/analyzer_test/images/splash_hd.png +0 -0
  25. data/test/roku_builder/test_files/analyzer_test/images/splash_sd.png +0 -0
  26. data/test/roku_builder/test_files/analyzer_test/images/too_small.png +0 -0
  27. data/test/roku_builder/test_files/analyzer_test/manifest_depricated_attribute +9 -0
  28. data/test/roku_builder/test_files/analyzer_test/manifest_duplicate_attribute +9 -0
  29. data/test/roku_builder/test_files/analyzer_test/manifest_empty_value +9 -0
  30. data/test/roku_builder/test_files/analyzer_test/manifest_has_value +9 -0
  31. data/test/roku_builder/test_files/analyzer_test/manifest_incorrect_image_resolution +8 -0
  32. data/test/roku_builder/test_files/analyzer_test/manifest_invalid_value_equals +9 -0
  33. data/test/roku_builder/test_files/analyzer_test/manifest_invalid_value_float +9 -0
  34. data/test/roku_builder/test_files/analyzer_test/manifest_invalid_value_integer +8 -0
  35. data/test/roku_builder/test_files/analyzer_test/manifest_invalid_value_negative +8 -0
  36. data/test/roku_builder/test_files/analyzer_test/manifest_invalid_value_not_equal +8 -0
  37. data/test/roku_builder/test_files/analyzer_test/manifest_invalid_value_starts_with +8 -0
  38. data/test/roku_builder/test_files/analyzer_test/manifest_missing_attribute +7 -0
  39. data/test/roku_builder/test_files/analyzer_test/manifest_missing_file +8 -0
  40. data/test/roku_builder/test_files/analyzer_test/manifest_raf +9 -0
  41. data/test/roku_builder/test_files/analyzer_test/manifest_template +8 -0
  42. data/test/roku_builder/test_files/analyzer_test/test.pkg +0 -0
  43. data/test/roku_builder/test_helper.rb +2 -2
  44. metadata +72 -2
@@ -0,0 +1,229 @@
1
+ {
2
+ "title": {
3
+ "required": true
4
+ },
5
+ "major_version": {
6
+ "required": true,
7
+ "validations": {
8
+ "integer": true,
9
+ "non_negative": true
10
+ }
11
+ },
12
+ "minor_version": {
13
+ "required": true,
14
+ "validations": {
15
+ "integer": true,
16
+ "non_negative": true
17
+ }
18
+ },
19
+ "build_version": {
20
+ "required": true,
21
+ "validations": {
22
+ "integer": true,
23
+ "non_negative": true,
24
+ "not_equal": ["0"]
25
+ }
26
+ },
27
+ "mm_icon_focus_hd": {
28
+ "required": true,
29
+ "validations": {
30
+ "starts_with": "pkg:/"
31
+ },
32
+ "isResource": true,
33
+ "resolution": [336, 210]
34
+ },
35
+ "mm_icon_focus_sd": {
36
+ "required": true,
37
+ "validations": {
38
+ "starts_with": "pkg:/"
39
+ },
40
+ "isResource": true,
41
+ "resolution": [246, 140]
42
+ },
43
+ "splash_screen_fhd": {
44
+ "validations": {
45
+ "starts_with": "pkg:/"
46
+ },
47
+ "isResource": true,
48
+ "resolution": [1920, 1080]
49
+ },
50
+ "splash_screen_hd": {
51
+ "required": true,
52
+ "validations": {
53
+ "starts_with": "pkg:/"
54
+ },
55
+ "isResource": true,
56
+ "resolution": [1280, 720]
57
+ },
58
+ "splash_screen_sd": {
59
+ "required": true,
60
+ "validations": {
61
+ "starts_with": "pkg:/"
62
+ },
63
+ "isResource": true,
64
+ "resolution": [720, 480]
65
+ },
66
+ "splash_color": {
67
+ "validations": {
68
+ "hex": true
69
+ }
70
+ },
71
+ "splash_min_time": {
72
+ "validations": {
73
+ "integer": true,
74
+ "non_negative": true
75
+ }
76
+ },
77
+ "splash_rgs_optimization": {
78
+ "validations": {
79
+ "integer": true,
80
+ "non_negative": true
81
+ }
82
+ },
83
+ "ui_resolutions": {},
84
+ "uri_resolution_autosub": {},
85
+ "supports_input_launch": {
86
+ "validations": {
87
+ "integer": true,
88
+ "non_negative": true
89
+ }
90
+ },
91
+ "requires_audiometadata": {
92
+ "validations": {
93
+ "integer": true,
94
+ "non_negative": true
95
+ }
96
+ },
97
+ "requires_gaming_remote": {
98
+ "validations": {
99
+ "integer": true,
100
+ "non_negative": true
101
+ }
102
+ },
103
+ "requires_mkv": {
104
+ "validations": {
105
+ "integer": true,
106
+ "non_negative": true
107
+ }
108
+ },
109
+ "network_not_required": {
110
+ "validations": {
111
+ "integer": true,
112
+ "non_negative": true
113
+ }
114
+ },
115
+ "bs_libs_required": {},
116
+ "usb_media_handler": {
117
+ "validations": {
118
+ "integer": true,
119
+ "non_negative": true
120
+ }
121
+ },
122
+ "requires_aaxs_drm": {
123
+ "validations": {
124
+ "integer": true,
125
+ "non_negative": true
126
+ }
127
+ },
128
+ "requires_aaxs_drm": {
129
+ "validations": {
130
+ "integer": true,
131
+ "non_negative": true
132
+ }
133
+ },
134
+ "requires_aaxs_version": {
135
+ "validations": {
136
+ "float": true,
137
+ "non_negative": true
138
+ }
139
+ },
140
+ "requires_verimatrix_drm": {
141
+ "validations": {
142
+ "integer": true,
143
+ "non_negative": true
144
+ }
145
+ },
146
+ "requires_verimatrix_version": {
147
+ "validations": {
148
+ "float": true,
149
+ "non_negative": true
150
+ }
151
+ },
152
+ "hidden": {
153
+ "validations": {
154
+ "integer": true,
155
+ "non_negative": true
156
+ }
157
+ },
158
+ "playonly_aware": {
159
+ "validations": {
160
+ "integer": true,
161
+ "non_negative": true
162
+ }
163
+ },
164
+ "rsg_version": {
165
+ "validations": {
166
+ "float": true,
167
+ "non_negative": true
168
+ },
169
+ "notify": ["1.0"]
170
+ },
171
+ "automatic_audio_guide_disabled": {
172
+ "validations": {
173
+ "integer": true,
174
+ "non_negative": true
175
+ }
176
+ },
177
+ "bs_prof_enabled": {
178
+ "validations": {
179
+ "boolean": true
180
+ }
181
+ },
182
+ "bs_prof_sample_ratio": {
183
+ "validations": {
184
+ "float": true,
185
+ "non_negative": true
186
+ }
187
+ },
188
+ "confirm_partner_button": {
189
+ "validations": {
190
+ "integer": true,
191
+ "non_negative": true
192
+ }
193
+ },
194
+ "suppress_unconnected_hud":{
195
+ "validations": {
196
+ "equals": ["0", "1"]
197
+ }
198
+ },
199
+ "screensaver_title": {},
200
+ "screensaver_private":{
201
+ "validations": {
202
+ "equals": ["0", "1"]
203
+ }
204
+ },
205
+ "subtitle": {
206
+ "deprecated": true
207
+ },
208
+ "mm_icon_side_hd": {
209
+ "deprecated": true,
210
+ "validations": {
211
+ "starts_with": "pkg:/"
212
+ },
213
+ "isResource": true
214
+ },
215
+ "mm_icon_side_sd": {
216
+ "deprecated": true,
217
+ "validations": {
218
+ "starts_with": "pkg:/"
219
+ },
220
+ "isResource": true
221
+ },
222
+ "requires_bluetooth": {
223
+ "deprecated": true,
224
+ "validations": {
225
+ "integer": true,
226
+ "non_negative": true
227
+ }
228
+ }
229
+ }
@@ -0,0 +1,142 @@
1
+ # ********** Copyright Viacom, Inc. Apache 2.0 **********
2
+
3
+ module RokuBuilder
4
+
5
+ class ManifestInspector
6
+ def initialize(config:, dir:, raf:)
7
+ @config = config
8
+ @dir = dir
9
+ @raf_inspector = raf
10
+ end
11
+
12
+ def run(inspector_config)
13
+ @warnings = []
14
+ @attributes = {}
15
+ @line_numbers = {}
16
+ @inspector_config = inspector_config
17
+ manifest = File.join(@config.root_dir, "manifest")
18
+ unless File.exist?(manifest)
19
+ add_warning(warning: :packageManifestFile)
20
+ else
21
+ File.open(manifest) do |file|
22
+ current_line = 0
23
+ file.readlines.each do |line|
24
+ current_line += 1
25
+ parts = line.split("=")
26
+ key = parts.shift.to_sym
27
+ if @attributes[key]
28
+ add_warning(warning: :manifestDuplicateAttribute, key: key, line: current_line)
29
+ else
30
+ value = parts.join("=").chomp
31
+ if !value or value == ""
32
+ add_warning(warning: :manifestEmptyValue, key: key, line: current_line)
33
+ else
34
+ @attributes[key] = value
35
+ @line_numbers[key] = current_line
36
+ end
37
+ end
38
+ end
39
+ end
40
+ manifest_attributes.each_pair do |key, attribute_config|
41
+ if @attributes[key]
42
+ if attribute_config[:deprecated]
43
+ add_warning(warning: :manifestDeprecatedAttribute, key: key)
44
+ end
45
+ if attribute_config[:validations]
46
+ attribute_config[:validations].each_pair do |type, value|
47
+ case type
48
+ when :integer
49
+ unless @attributes[key].to_i.to_s == @attributes[key]
50
+ add_warning(warning: :manifestInvalidValue, key: key)
51
+ end
52
+ when :float
53
+ unless @attributes[key].to_f.to_s == @attributes[key]
54
+ add_warning(warning: :manifestInvalidValue, key: key)
55
+ end
56
+ when :non_negative
57
+ unless @attributes[key].to_f >= 0
58
+ add_warning(warning: :manifestInvalidValue, key: key)
59
+ end
60
+ when :not_equal
61
+ if value.include? @attributes[key]
62
+ add_warning(warning: :manifestInvalidValue, key: key)
63
+ end
64
+ when :equals
65
+ unless value.include? @attributes[key]
66
+ add_warning(warning: :manifestInvalidValue, key: key)
67
+ end
68
+ when :starts_with
69
+ unless @attributes[key].start_with? value
70
+ add_warning(warning: :manifestInvalidValue, key: key)
71
+ end
72
+ else
73
+ raise ImplementationError, "Unknown Validation"
74
+ end
75
+ end
76
+ end
77
+ if attribute_config[:notify]
78
+ attribute_config[:notify].each do |regexp|
79
+ if /#{regexp}/ =~ @attributes[key]
80
+ add_warning(warning: :manifestHasValue, key: key)
81
+ break
82
+ end
83
+ end
84
+ end
85
+ if attribute_config[:isResource]
86
+ path = File.join(@dir, @attributes[key].gsub("pkg:/", ""))
87
+ unless File.exist?(path)
88
+ mapping = {"{0}": @attributes[key], "{1}": key }
89
+ add_warning(warning: :manifestMissingFile, key: key, mapping: mapping)
90
+ else
91
+ if attribute_config[:resolution]
92
+ size = ImageSize.path(path).size
93
+ target = ImageSize::Size.new(attribute_config[:resolution])
94
+ unless size == target
95
+ mapping = {
96
+ "{0}": @attributes[key],
97
+ "{1}": key,
98
+ "{2}": size,
99
+ "{3}": target
100
+ }
101
+ add_warning(warning: :manifestIncorrectImageResolution, key: key, mapping: mapping)
102
+ end
103
+ end
104
+ end
105
+ end
106
+ elsif attribute_config[:required]
107
+ add_warning(warning: :manifestMissingAttribute, key: key)
108
+ end
109
+ @raf_inspector.inspect_manifest(attributes: @attributes, line_numbers: @line_numbers)
110
+ end
111
+ end
112
+ @warnings
113
+ end
114
+
115
+ private
116
+
117
+ def manifest_attributes
118
+ file = File.join(File.dirname(__FILE__), "manifest_attributes.json")
119
+ JSON.parse(File.open(file).read, {symbolize_names: true})
120
+ end
121
+
122
+ def add_warning(warning:, key: nil, mapping: nil, line: nil)
123
+ @warnings.push(@inspector_config[warning].deep_dup)
124
+ @warnings.last[:path] = "manifest"
125
+ if line
126
+ @warnings.last[:line] = line
127
+ elsif @line_numbers[key]
128
+ @warnings.last[:line] = @line_numbers[key]
129
+ end
130
+ if mapping
131
+ mapping.each_pair do |map, value|
132
+ @warnings.last[:message].gsub!(map.to_s, value.to_s)
133
+ end
134
+ elsif key
135
+ @warnings.last[:message].gsub!("{0}", key.to_s)
136
+ if @attributes[key]
137
+ @warnings.last[:message].gsub!("{1}", @attributes[key])
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,74 @@
1
+ # ********** Copyright Viacom, Inc. Apache 2.0 **********
2
+
3
+ module RokuBuilder
4
+
5
+ class RafInspector
6
+ RAF_INTERFACE_INITIALIZATION_PATTERN = /roku_ads\(\)/i
7
+ LIBRARY_IMPORT_PATTERN = /\s*library\s*"roku_ads.brs"\s*/i
8
+
9
+ def initialize(config:, dir:)
10
+ @config = config
11
+ @dir = dir
12
+ @has_raf_interface_initialization = false
13
+ @interface_location = {}
14
+ @has_library_import = false
15
+ @import_location = {}
16
+ @has_manifest_entry = false
17
+ @manifest_location = {path: "manifest"}
18
+ end
19
+
20
+ def inspect_line(line:, file:, line_number:)
21
+ unless @has_raf_interface_initialization
22
+ @has_raf_interface_initialization = !!RAF_INTERFACE_INITIALIZATION_PATTERN.match(line)
23
+ if @has_raf_interface_initialization
24
+ @interface_location = {path: file, line: line_number}
25
+ end
26
+ end
27
+ unless @has_library_import
28
+ @has_library_import = !!LIBRARY_IMPORT_PATTERN.match(line)
29
+ if @has_library_import
30
+ @import_location = {path: file, line: line_number}
31
+ end
32
+ end
33
+ end
34
+
35
+ def inspect_manifest(attributes:, line_numbers:)
36
+ if attributes[:bs_libs_required] and attributes[:bs_libs_required].downcase == "roku_ads_lib"
37
+ @has_manifest_entry = true
38
+ @manifest_location[:line] = line_numbers[:bs_libs_required]
39
+ end
40
+ end
41
+
42
+ def run(inspector_config)
43
+ @warnings = []
44
+ @inspector_config = inspector_config
45
+ if @has_raf_interface_initialization and !@has_library_import
46
+ add_warning(warning: :rafConstructorPresentImportMissing, location: @interface_location)
47
+ end
48
+ if @has_raf_interface_initialization and !@has_manifest_entry
49
+ add_warning(warning: :rafConstructorPresentManifestMissing, location: @interface_location)
50
+ end
51
+ if !@has_raf_interface_initialization and @has_manifest_entry
52
+ add_warning(warning: :rafConstructorMissingManifestPresent, location: @manifest_location)
53
+ end
54
+ if @has_manifest_entry and !@has_library_import
55
+ add_warning(warning: :rafManifestPresentImportMissing, location: @manifest_location)
56
+ end
57
+ if !@has_raf_interface_initialization and @has_library_import
58
+ add_warning(warning: :rafConstructorMissingImportPresent, location: @import_location)
59
+ end
60
+ if @has_raf_interface_initialization and @has_library_import and @has_manifest_entry
61
+ add_warning(warning: :rafProperIntegration, location: @import_location)
62
+ end
63
+ @warnings
64
+ end
65
+
66
+ private
67
+
68
+ def add_warning(warning:, location:)
69
+ @warnings.push(@inspector_config[warning].deep_dup)
70
+ @warnings.last[:path] = location[:path]
71
+ @warnings.last[:line] = location[:line]
72
+ end
73
+ end
74
+ end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module RokuBuilder
4
4
  # Version of the RokuBuilder Gem
5
- VERSION = "4.7.2"
5
+ VERSION = "4.8.0"
6
6
  end
data/lib/roku_builder.rb CHANGED
@@ -25,6 +25,8 @@ require "fileutils"
25
25
  require "tempfile"
26
26
  require "tmpdir"
27
27
  require "zip"
28
+ #analyzer
29
+ require "image_size"
28
30
 
29
31
 
30
32
  Dir.glob(File.join(File.dirname(__FILE__), "roku_builder", "*.rb")).each do |path|
data/roku_builder.gemspec CHANGED
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.add_dependency "net-telnet", "~> 0.1"
29
29
  spec.add_dependency "oga", "~> 2.11"
30
30
  spec.add_dependency "win32-security", "~> 0.5" # For windows compatibility
31
+ spec.add_dependency "image_size", "~> 2.0"
31
32
 
32
33
  spec.add_development_dependency "bundler", "~> 1.7"
33
34
  spec.add_development_dependency "rake", "~> 12.0"