roku_builder 4.7.2 → 4.8.0

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