roku_builder 3.13.0 → 4.0.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 (226) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/CHANGELOG +12 -0
  4. data/Gemfile.lock +22 -7
  5. data/Guardfile +3 -3
  6. data/README.md +22 -398
  7. data/bin/roku +1 -194
  8. data/config.json.example +1 -1
  9. data/intergration/roku_builder/test_core.rb +52 -0
  10. data/intergration/roku_builder/test_files/core_intergration_test/manifest_template +7 -0
  11. data/intergration/roku_builder/test_files/core_intergration_test/test.pkg +0 -0
  12. data/intergration/roku_builder/test_files/inspector_intergration_test/components/rectanglescene.xml +28 -0
  13. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  14. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  15. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rde_splash_fhd.jpg +0 -0
  16. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rde_splash_hd.jpg +0 -0
  17. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rde_splash_sd.jpg +0 -0
  18. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  19. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  20. data/intergration/roku_builder/test_files/inspector_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  21. data/intergration/roku_builder/test_files/inspector_intergration_test/manifest +21 -0
  22. data/intergration/roku_builder/test_files/inspector_intergration_test/source/main.brs +23 -0
  23. data/intergration/roku_builder/test_files/inspector_intergration_test/test.pkg +0 -0
  24. data/intergration/roku_builder/test_files/linker_intergration_test/components/rectanglescene.xml +29 -0
  25. data/intergration/roku_builder/test_files/linker_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  26. data/intergration/roku_builder/test_files/linker_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  27. data/intergration/roku_builder/test_files/linker_intergration_test/images/rde_splash_fhd.jpg +0 -0
  28. data/intergration/roku_builder/test_files/linker_intergration_test/images/rde_splash_hd.jpg +0 -0
  29. data/intergration/roku_builder/test_files/linker_intergration_test/images/rde_splash_sd.jpg +0 -0
  30. data/intergration/roku_builder/test_files/linker_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  31. data/intergration/roku_builder/test_files/linker_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  32. data/intergration/roku_builder/test_files/linker_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  33. data/intergration/roku_builder/test_files/linker_intergration_test/manifest +21 -0
  34. data/intergration/roku_builder/test_files/linker_intergration_test/source/main.brs +21 -0
  35. data/intergration/roku_builder/test_files/linker_intergration_test/test.pkg +0 -0
  36. data/intergration/roku_builder/test_files/loader_intergration_test/components/rectanglescene.xml +29 -0
  37. data/intergration/roku_builder/test_files/loader_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  38. data/intergration/roku_builder/test_files/loader_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  39. data/intergration/roku_builder/test_files/loader_intergration_test/images/rde_splash_fhd.jpg +0 -0
  40. data/intergration/roku_builder/test_files/loader_intergration_test/images/rde_splash_hd.jpg +0 -0
  41. data/intergration/roku_builder/test_files/loader_intergration_test/images/rde_splash_sd.jpg +0 -0
  42. data/intergration/roku_builder/test_files/loader_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  43. data/intergration/roku_builder/test_files/loader_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  44. data/intergration/roku_builder/test_files/loader_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  45. data/intergration/roku_builder/test_files/loader_intergration_test/manifest +21 -0
  46. data/intergration/roku_builder/test_files/loader_intergration_test/source/main.brs +21 -0
  47. data/intergration/roku_builder/test_files/loader_intergration_test/test.pkg +0 -0
  48. data/intergration/roku_builder/test_files/monitor_intergration_test/components/rectanglescene.xml +29 -0
  49. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  50. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  51. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rde_splash_fhd.jpg +0 -0
  52. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rde_splash_hd.jpg +0 -0
  53. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rde_splash_sd.jpg +0 -0
  54. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  55. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  56. data/intergration/roku_builder/test_files/monitor_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  57. data/intergration/roku_builder/test_files/monitor_intergration_test/manifest +21 -0
  58. data/intergration/roku_builder/test_files/monitor_intergration_test/source/main.brs +21 -0
  59. data/intergration/roku_builder/test_files/monitor_intergration_test/test.pkg +0 -0
  60. data/intergration/roku_builder/test_files/navigator_intergration_test/components/rectanglescene.xml +29 -0
  61. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  62. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  63. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rde_splash_fhd.jpg +0 -0
  64. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rde_splash_hd.jpg +0 -0
  65. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rde_splash_sd.jpg +0 -0
  66. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  67. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  68. data/intergration/roku_builder/test_files/navigator_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  69. data/intergration/roku_builder/test_files/navigator_intergration_test/manifest +21 -0
  70. data/intergration/roku_builder/test_files/navigator_intergration_test/source/main.brs +21 -0
  71. data/intergration/roku_builder/test_files/navigator_intergration_test/test.pkg +0 -0
  72. data/intergration/roku_builder/test_files/packager_intergration_test/components/rectanglescene.xml +29 -0
  73. data/intergration/roku_builder/test_files/packager_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  74. data/intergration/roku_builder/test_files/packager_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  75. data/intergration/roku_builder/test_files/packager_intergration_test/images/rde_splash_fhd.jpg +0 -0
  76. data/intergration/roku_builder/test_files/packager_intergration_test/images/rde_splash_hd.jpg +0 -0
  77. data/intergration/roku_builder/test_files/packager_intergration_test/images/rde_splash_sd.jpg +0 -0
  78. data/intergration/roku_builder/test_files/packager_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  79. data/intergration/roku_builder/test_files/packager_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  80. data/intergration/roku_builder/test_files/packager_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  81. data/intergration/roku_builder/test_files/packager_intergration_test/manifest +21 -0
  82. data/intergration/roku_builder/test_files/packager_intergration_test/source/main.brs +21 -0
  83. data/intergration/roku_builder/test_files/packager_intergration_test/test.pkg +0 -0
  84. data/intergration/roku_builder/test_files/profiler_intergration_test/components/rectanglescene.xml +29 -0
  85. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  86. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  87. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rde_splash_fhd.jpg +0 -0
  88. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rde_splash_hd.jpg +0 -0
  89. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rde_splash_sd.jpg +0 -0
  90. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  91. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  92. data/intergration/roku_builder/test_files/profiler_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  93. data/intergration/roku_builder/test_files/profiler_intergration_test/manifest +21 -0
  94. data/intergration/roku_builder/test_files/profiler_intergration_test/source/main.brs +21 -0
  95. data/intergration/roku_builder/test_files/profiler_intergration_test/test.pkg +0 -0
  96. data/intergration/roku_builder/test_files/scripter_intergration_test/components/rectanglescene.xml +29 -0
  97. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  98. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  99. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rde_splash_fhd.jpg +0 -0
  100. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rde_splash_hd.jpg +0 -0
  101. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rde_splash_sd.jpg +0 -0
  102. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  103. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  104. data/intergration/roku_builder/test_files/scripter_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  105. data/intergration/roku_builder/test_files/scripter_intergration_test/manifest +21 -0
  106. data/intergration/roku_builder/test_files/scripter_intergration_test/source/main.brs +21 -0
  107. data/intergration/roku_builder/test_files/scripter_intergration_test/test.pkg +0 -0
  108. data/intergration/roku_builder/test_files/tester_intergration_test/components/rectanglescene.xml +29 -0
  109. data/intergration/roku_builder/test_files/tester_intergration_test/images/rde_mm_focus_hd.jpg +0 -0
  110. data/intergration/roku_builder/test_files/tester_intergration_test/images/rde_mm_focus_sd.jpg +0 -0
  111. data/intergration/roku_builder/test_files/tester_intergration_test/images/rde_splash_fhd.jpg +0 -0
  112. data/intergration/roku_builder/test_files/tester_intergration_test/images/rde_splash_hd.jpg +0 -0
  113. data/intergration/roku_builder/test_files/tester_intergration_test/images/rde_splash_sd.jpg +0 -0
  114. data/intergration/roku_builder/test_files/tester_intergration_test/images/rsgde_bg_hd.jpg +0 -0
  115. data/intergration/roku_builder/test_files/tester_intergration_test/images/rsgde_mm_focus_hd.jpg +0 -0
  116. data/intergration/roku_builder/test_files/tester_intergration_test/images/rsgde_splash_hd.jpg +0 -0
  117. data/intergration/roku_builder/test_files/tester_intergration_test/manifest +21 -0
  118. data/intergration/roku_builder/test_files/tester_intergration_test/source/main.brs +21 -0
  119. data/intergration/roku_builder/test_files/tester_intergration_test/test.pkg +0 -0
  120. data/intergration/roku_builder/test_helper.rb +138 -0
  121. data/intergration/roku_builder/test_inspector.rb +35 -0
  122. data/intergration/roku_builder/test_linker.rb +32 -0
  123. data/intergration/roku_builder/test_loader.rb +38 -0
  124. data/intergration/roku_builder/test_monitor.rb +21 -0
  125. data/intergration/roku_builder/test_navigator.rb +34 -0
  126. data/intergration/roku_builder/test_packager.rb +41 -0
  127. data/intergration/roku_builder/test_profiler.rb +48 -0
  128. data/intergration/roku_builder/test_scripter.rb +38 -0
  129. data/intergration/roku_builder/test_tester.rb +21 -0
  130. data/lib/roku_builder.rb +143 -154
  131. data/lib/roku_builder/config.rb +17 -40
  132. data/lib/roku_builder/config_parser.rb +49 -200
  133. data/lib/roku_builder/config_validator.rb +1 -1
  134. data/lib/roku_builder/errors.rb +12 -0
  135. data/lib/roku_builder/git.rb +28 -0
  136. data/lib/roku_builder/hash.rb +8 -0
  137. data/lib/roku_builder/manifest.rb +121 -0
  138. data/lib/roku_builder/options.rb +68 -29
  139. data/lib/roku_builder/plugin.rb +30 -0
  140. data/lib/roku_builder/plugins/core.rb +117 -0
  141. data/lib/roku_builder/plugins/inspector.rb +104 -0
  142. data/lib/roku_builder/{linker.rb → plugins/linker.rb} +38 -12
  143. data/lib/roku_builder/plugins/loader.rb +152 -0
  144. data/lib/roku_builder/{monitor.rb → plugins/monitor.rb} +20 -9
  145. data/lib/roku_builder/{navigator.rb → plugins/navigator.rb} +136 -88
  146. data/lib/roku_builder/plugins/packager.rb +194 -0
  147. data/lib/roku_builder/plugins/profiler.rb +135 -0
  148. data/lib/roku_builder/plugins/scripter.rb +53 -0
  149. data/lib/roku_builder/{tester.rb → plugins/tester.rb} +28 -19
  150. data/lib/roku_builder/stager.rb +48 -12
  151. data/lib/roku_builder/string.rb +20 -0
  152. data/lib/roku_builder/util.rb +10 -34
  153. data/lib/roku_builder/version.rb +1 -1
  154. data/rakefile +5 -1
  155. data/roku_builder.gemspec +2 -0
  156. data/test/roku_builder/plugins/test_core.rb +112 -0
  157. data/test/roku_builder/plugins/test_inspector.rb +165 -0
  158. data/test/roku_builder/plugins/test_linker.rb +123 -0
  159. data/test/roku_builder/plugins/test_loader.rb +115 -0
  160. data/test/roku_builder/plugins/test_monitor.rb +141 -0
  161. data/test/roku_builder/plugins/test_navigator.rb +274 -0
  162. data/test/roku_builder/plugins/test_packager.rb +202 -0
  163. data/test/roku_builder/plugins/test_profiler.rb +127 -0
  164. data/test/roku_builder/plugins/test_scripter.rb +110 -0
  165. data/test/roku_builder/plugins/test_tester.rb +109 -0
  166. data/test/roku_builder/test_config.rb +51 -35
  167. data/test/roku_builder/test_config_parser.rb +76 -154
  168. data/test/roku_builder/test_config_validator.rb +18 -1
  169. data/test/roku_builder/test_files/{loader_test/manifest → config_parser_test/test.pkg} +0 -0
  170. data/test/roku_builder/test_files/config_test/config.json +3 -0
  171. data/test/roku_builder/test_files/controller_commands_test/manifest_template +7 -0
  172. data/test/roku_builder/test_files/core_test/manifest_template +7 -0
  173. data/test/roku_builder/test_files/core_test/test.pkg +0 -0
  174. data/test/roku_builder/test_files/inspector_test/manifest +6 -0
  175. data/test/roku_builder/test_files/inspector_test/test.pkg +0 -0
  176. data/test/roku_builder/test_files/linker_test/manifest +6 -0
  177. data/test/roku_builder/test_files/linker_test/test.pkg +0 -0
  178. data/test/roku_builder/test_files/loader_test/manifest_template +6 -0
  179. data/test/roku_builder/test_files/loader_test/test.pkg +0 -0
  180. data/test/roku_builder/test_files/loader_test/test.zip +0 -0
  181. data/test/roku_builder/test_files/manifest_test/manifest_comments +6 -0
  182. data/test/roku_builder/test_files/manifest_test/manifest_template +7 -0
  183. data/test/roku_builder/test_files/manifest_test/test.zip +0 -0
  184. data/test/roku_builder/test_files/packager_test/manifest +6 -0
  185. data/test/roku_builder/test_files/packager_test/scripter_test/manifest +6 -0
  186. data/test/roku_builder/test_files/packager_test/test.pkg +0 -0
  187. data/test/roku_builder/test_files/roku_builder_test/config.json +32 -0
  188. data/test/roku_builder/test_files/scripter_test/manifest +6 -0
  189. data/test/roku_builder/test_files/scripter_test/test.pkg +0 -0
  190. data/test/roku_builder/test_files/stager_test/test.pkg +0 -0
  191. data/test/roku_builder/test_files/tester_test/manifest +6 -0
  192. data/test/roku_builder/test_files/tester_test/test.pkg +0 -0
  193. data/test/roku_builder/test_helper.rb +44 -11
  194. data/test/roku_builder/test_logger.rb +1 -0
  195. data/test/roku_builder/test_manifest.rb +99 -0
  196. data/test/roku_builder/test_options.rb +106 -77
  197. data/test/roku_builder/test_options_plugins.rb +111 -0
  198. data/test/roku_builder/test_plugin.rb +48 -0
  199. data/test/roku_builder/test_roku_builder.rb +239 -0
  200. data/test/roku_builder/test_stager.rb +49 -101
  201. data/test/roku_builder/test_util.rb +19 -4
  202. metadata +241 -47
  203. data/lib/roku_builder/controller.rb +0 -98
  204. data/lib/roku_builder/controller_commands.rb +0 -224
  205. data/lib/roku_builder/error_handler.rb +0 -142
  206. data/lib/roku_builder/inspector.rb +0 -82
  207. data/lib/roku_builder/keyer.rb +0 -106
  208. data/lib/roku_builder/loader.rb +0 -131
  209. data/lib/roku_builder/manifest_manager.rb +0 -126
  210. data/lib/roku_builder/packager.rb +0 -43
  211. data/lib/roku_builder/profiler.rb +0 -96
  212. data/lib/roku_builder/scripter.rb +0 -39
  213. data/test/roku_builder/test_controller.rb +0 -70
  214. data/test/roku_builder/test_controller_commands.rb +0 -465
  215. data/test/roku_builder/test_error_handler.rb +0 -90
  216. data/test/roku_builder/test_inspector.rb +0 -298
  217. data/test/roku_builder/test_keyer.rb +0 -176
  218. data/test/roku_builder/test_linker.rb +0 -110
  219. data/test/roku_builder/test_loader.rb +0 -337
  220. data/test/roku_builder/test_manifest_manager.rb +0 -103
  221. data/test/roku_builder/test_monitor.rb +0 -137
  222. data/test/roku_builder/test_navigator.rb +0 -280
  223. data/test/roku_builder/test_packager.rb +0 -127
  224. data/test/roku_builder/test_profiler.rb +0 -35
  225. data/test/roku_builder/test_scripter.rb +0 -102
  226. data/test/roku_builder/test_tester.rb +0 -130
@@ -0,0 +1,8 @@
1
+ # ********** Copyright 2016 Viacom, Inc. Apache 2.0 **********
2
+
3
+ class ::Hash
4
+ def deep_merge(second)
5
+ merger = proc { |_key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
6
+ self.merge(second, &merger)
7
+ end
8
+ end
@@ -0,0 +1,121 @@
1
+ # ********** Copyright Viacom, Inc. Apache 2.0 **********
2
+
3
+ module RokuBuilder
4
+ class Manifest
5
+
6
+ def self.generate(config:, attributes:)
7
+ FileUtils.touch(File.join(config.parsed[:root_dir], "manifest"))
8
+ manifest = new(config: config)
9
+ manifest.update(attributes: default_params.merge(attributes))
10
+ manifest
11
+ end
12
+
13
+ def initialize(config:)
14
+ @config = config
15
+ @attributes = {}
16
+ check_for_manifest
17
+ read
18
+ end
19
+
20
+ def update(attributes:)
21
+ update_attributes(attributes)
22
+ write_file
23
+ end
24
+
25
+ def increment_build_version
26
+ build_version_parts = @attributes[:build_version].split(".")
27
+ if build_version_parts.length == 2
28
+ build_version_parts[0] = Time.now.strftime("%m%d%y")
29
+ build_version_parts[1] = build_version_parts[1].to_i + 1
30
+ @attributes[:build_version] = build_version_parts.join(".")
31
+ else
32
+ @attributes[:build_version] = build_version_parts[0].to_i + 1
33
+ end
34
+ write_file
35
+ end
36
+
37
+ def method_missing(method)
38
+ @attributes[method]
39
+ end
40
+
41
+ private
42
+
43
+ def read
44
+ process_folder = -> (path){
45
+ File.open(path, 'r') do |file|
46
+ read_attributes(file)
47
+ end
48
+ }
49
+ process_zip = -> (entry){
50
+ entry.get_input_stream do |file|
51
+ read_attributes(file)
52
+ end
53
+ }
54
+ process_manifest(process_folder, process_zip)
55
+ end
56
+
57
+ def read_attributes(file)
58
+ file.each_line do |line|
59
+ key, value = line.split("=")
60
+ key = key.chomp.to_sym
61
+ value.chomp! if value
62
+ @attributes[key] = value
63
+ end
64
+ end
65
+
66
+ def check_for_manifest
67
+ process_folder = -> (path) {
68
+ raise ManifestError, "Missing Manifest: #{path}" unless File.exist?(path)
69
+ }
70
+ process_zip = -> (entry) {
71
+ raise ManifestError, "Missing Manifest in #{root_dir}" unless entry
72
+ }
73
+ process_manifest(process_folder, process_zip)
74
+ end
75
+
76
+ def process_manifest(process_folder, process_zip)
77
+ root_dir = @config.root_dir
78
+ if File.directory?(root_dir)
79
+ path = File.join(root_dir, "manifest")
80
+ process_folder.call(path)
81
+ elsif File.extname(root_dir) == ".zip"
82
+ Zip::File.open(root_dir) do |zip_file|
83
+ entry = zip_file.glob("manifest").first
84
+ process_zip.call(entry)
85
+ end
86
+ end
87
+ end
88
+
89
+ def update_attributes(attributes)
90
+ @attributes.merge!(attributes)
91
+ end
92
+
93
+ def write_file
94
+ root_dir = @config.parsed[:root_dir]
95
+ raise ManifestError, "Cannot Update zipped manifest" if File.extname(root_dir) == ".zip"
96
+ path = File.join(root_dir, "manifest")
97
+ File.open(path, "w") do |file|
98
+ @attributes.each_pair do |key,value|
99
+ if value
100
+ file.puts "#{key}=#{value}"
101
+ else
102
+ file.puts key
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ def self.default_params
109
+ {
110
+ title: "Default Title",
111
+ major_version: 1,
112
+ minor_version: 0,
113
+ build_version: "010101.0001",
114
+ mm_icon_focus_fhd: "<insert fhd focus icon url>",
115
+ mm_icon_focus_hd: "<insert hd focus icon url>",
116
+ mm_icon_focus_sd: "<insert sd focus icon url>"
117
+ }
118
+ end
119
+ end
120
+ end
121
+
@@ -2,10 +2,17 @@
2
2
 
3
3
  module RokuBuilder
4
4
  class Options < Hash
5
- def initialize(options:)
6
- merge!(options)
5
+ def initialize(options: nil)
7
6
  @logger = Logger.instance
8
- validate
7
+ setup_plugin_commands
8
+ options ||= parse
9
+ merge!(options)
10
+ end
11
+
12
+ def validate
13
+ validate_commands
14
+ validate_sources
15
+ validate_deprivated
9
16
  end
10
17
 
11
18
  def command
@@ -17,7 +24,7 @@ module RokuBuilder
17
24
  end
18
25
 
19
26
  def source_command?
20
- (source_commands & keys).count > 0
27
+ source_commands.include?(command)
21
28
  end
22
29
 
23
30
  def device_command?
@@ -30,11 +37,57 @@ module RokuBuilder
30
37
 
31
38
  private
32
39
 
33
- def validate
34
- validate_commands
35
- validate_sources
36
- validate_combinations
37
- validate_deprivated
40
+ def setup_plugin_commands
41
+ RokuBuilder.plugins.each do |plugin|
42
+ plugin.commands.each do |command, attributes|
43
+ commands << command
44
+ [:device, :source, :exclude].each do |type|
45
+ if attributes[type]
46
+ send("#{type}_commands".to_sym) << command
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ def parse
54
+ options = {}
55
+ options[:config] = '~/.roku_config.json'
56
+ options[:update_manifest] = false
57
+ parser = OptionParser.new
58
+ parser.banner = "Usage: roku <command> [options]"
59
+ add_plugin_options(parser: parser, options:options)
60
+ validate_parser(parser: parser)
61
+ parser.parse!
62
+ options
63
+ end
64
+
65
+ def add_plugin_options(parser:, options:)
66
+ RokuBuilder.plugins.each do |plugin|
67
+ parser.separator ""
68
+ parser.separator "Options for #{plugin}:"
69
+ plugin.parse_options(parser: parser, options: options)
70
+ end
71
+ end
72
+
73
+ def validate_parser(parser:)
74
+ short = []
75
+ long = []
76
+ stack = parser.instance_variable_get(:@stack)
77
+ stack.each do |optionsList|
78
+ optionsList.each_option do |option|
79
+ if option.respond_to?(:short)
80
+ if short.include?(option.short.first)
81
+ raise ImplementationError, "Duplicate short option defined: #{option.short.first}"
82
+ end
83
+ short.push(option.short.first) if option.short.first
84
+ if long.include?(option.long.first)
85
+ raise ImplementationError, "Duplicate long option defined: #{option.long.first}"
86
+ end
87
+ long.push(option.long.first) if option.long.first
88
+ end
89
+ end
90
+ end
38
91
  end
39
92
 
40
93
  def validate_commands
@@ -51,16 +104,6 @@ module RokuBuilder
51
104
  end
52
105
  end
53
106
 
54
- def validate_combinations
55
- all_sources = keys & sources
56
- if all_sources.include?(:current) and not (self[:build] or self[:sideload])
57
- raise InvalidOptions, "Current source onle works for build or sideload"
58
- end
59
- if self[:in] and not self[:sideload]
60
- raise InvalidOptions, "In source only works for sideloading"
61
- end
62
- end
63
-
64
107
  def validate_deprivated
65
108
  depricated = keys & depricated_options.keys
66
109
  if depricated.count > 0
@@ -73,41 +116,37 @@ module RokuBuilder
73
116
  # List of command options
74
117
  # @return [Array<Symbol>] List of command symbols that can be used in the options hash
75
118
  def commands
76
- [:sideload, :package, :test, :deeplink,:configure, :validate, :delete,
77
- :navigate, :navigator, :text, :build, :monitor, :update, :screencapture,
78
- :key, :genkey, :screen, :screens, :applist, :print, :profile, :dostage,
79
- :dounstage]
119
+ @commands ||= []
80
120
  end
81
121
 
82
122
  # List of depricated options
83
123
  # @return [Hash] Hash of depricated options and the warning message for each
84
124
  def depricated_options
85
- {deeplink_depricated: "-L and --deeplink are depricated. Use -o or --deeplink-options." }
125
+ @depricated_options ||= {}
86
126
  end
87
127
 
88
128
  # List of source options
89
129
  # @return [Array<Symbol>] List of source symbols that can be used in the options hash
90
130
  def sources
91
- [:ref, :set_stage, :working, :current, :in]
131
+ [:ref, :stage, :working, :current, :in]
92
132
  end
93
133
 
94
134
  # List of commands requiring a source option
95
135
  # @return [Array<Symbol>] List of command symbols that require a source in the options hash
96
136
  def source_commands
97
- [:sideload, :package, :test, :build, :key, :update, :print]
137
+ @source_commands ||= []
98
138
  end
99
139
 
100
140
  # List of commands the activate the exclude files
101
141
  # @return [Array<Symbol] List of commands the will activate the exclude files lists
102
142
  def exclude_commands
103
- [:build, :package]
143
+ @exclude_commands ||= []
104
144
  end
105
145
 
106
146
  # List of commands that require a device
107
147
  # @return [Array<Symbol>] List of commands that require a device
108
148
  def device_commands
109
- [:sideload, :package, :test, :deeplink, :delete, :navigate, :navigator,
110
- :text, :monitor, :screencapture, :applist, :profile, :key, :genkey ]
149
+ @device_commands ||= []
111
150
  end
112
151
  end
113
152
  end
@@ -0,0 +1,30 @@
1
+ # ********** Copyright Viacom, Inc. Apache 2.0 **********
2
+
3
+ module RokuBuilder
4
+
5
+ # Super class for modules
6
+ # This class defines a common initializer and allows subclasses
7
+ # to define their own secondary initializer
8
+ module Plugin
9
+
10
+ def commands
11
+ raise ImplementationError, "commands method not implemented in #{self}"
12
+ #[
13
+ # {
14
+ # name: :command_name,
15
+ # device: true || false,
16
+ # source: true || false,
17
+ # exclude: true || false
18
+ # }
19
+ #]
20
+ end
21
+
22
+ def parse_options(option_parser:, options:)
23
+ raise ImplementationError, "parse_options method not implemented"
24
+ end
25
+
26
+ def dependencies
27
+ []
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,117 @@
1
+ # ********** Copyright Viacom, Inc. Apache 2.0 **********
2
+
3
+ module RokuBuilder
4
+
5
+ class Core
6
+ extend Plugin
7
+
8
+ def self.commands
9
+ {
10
+ configure: {},
11
+ validate: {},
12
+ increment: {source: true, stage: true},
13
+ dostage: {source: true},
14
+ dounstage: {source: true}
15
+ }
16
+ end
17
+
18
+ def self.parse_options(parser:, options:)
19
+ parser.separator "Commands:"
20
+ parser.on("--configure", "Copy base configuration file to the --config location. Default: '~/.roku_config.json'") do
21
+ options[:configure] = true
22
+ end
23
+ parser.on("--validate", "Validate configuration") do
24
+ options[:validate] = true
25
+ end
26
+ parser.on("-u", "--update-manifest", "Increment manifest build version") do
27
+ options[:increment] = true
28
+ end
29
+ parser.on("--do-stage", "Run the stager. Used for scripting. Always run --do-unstage after") do
30
+ options[:dostage] = true
31
+ end
32
+ parser.on("--do-unstage", "Run the unstager. Used for scripting. Always run --do-script first") do
33
+ options[:dounstage] = true
34
+ end
35
+ parser.separator ""
36
+ parser.separator "Config Options:"
37
+ parser.on("-e", "--edit PARAMS", "Edit config params when configuring. (eg. a:b, c:d,e:f)") do |p|
38
+ options[:edit_params] = p
39
+ end
40
+ parser.on("--config CONFIG", "Set a custom config file. Default: '~/.roku_config.json'") do |c|
41
+ options[:config] = c
42
+ end
43
+ parser.separator ""
44
+ parser.separator "Source Options:"
45
+ parser.on("-r", "--ref REF", "Git referance to use for sideloading") do |r|
46
+ options[:ref] = r
47
+ end
48
+ parser.on("-w", "--working", "Use working directory to sideload or test") do
49
+ options[:working] = true
50
+ end
51
+ parser.on("-c", "--current", "Use current directory to sideload or test. Overrides any project config") do
52
+ options[:current] = true
53
+ end
54
+ parser.on("-s", "--stage STAGE", "Set the stage to use. Default: 'production'") do |b|
55
+ options[:stage] = b
56
+ end
57
+ parser.on("-P", "--project ID", "Use a different project") do |p|
58
+ options[:project] = p
59
+ end
60
+ parser.separator ""
61
+ parser.separator "Other Options:"
62
+ parser.on("-O", "--out PATH", "Output file/folder. If PATH ends in .pkg/.zip/.jpg, file is assumed, otherwise folder is assumed") do |o|
63
+ options[:out] = o
64
+ end
65
+ parser.on("-I", "--in PATH", "Input file for sideloading") do |i|
66
+ options[:in] = i
67
+ end
68
+ parser.on("-D", "--device ID", "Use a different device corresponding to the given ID") do |d|
69
+ options[:device] = d
70
+ options[:device_given] = true
71
+ end
72
+ parser.on("-V", "--verbose", "Print Info message") do
73
+ options[:verbose] = true
74
+ end
75
+ parser.on("--debug", "Print Debug messages") do
76
+ options[:debug] = true
77
+ end
78
+ parser.on("-h", "--help", "Show this message") do
79
+ puts parser
80
+ exit
81
+ end
82
+ parser.on("-v", "--version", "Show version") do
83
+ puts RokuBuilder::VERSION
84
+ exit
85
+ end
86
+ end
87
+
88
+ def initialize(config:)
89
+ @config = config
90
+ end
91
+
92
+ def configure(options:)
93
+ # Stub command
94
+ # Handled in the config class
95
+ Logger.instance.unknown "Configured"
96
+ end
97
+ def validate(options:)
98
+ # Stub command
99
+ # Handled in the config class
100
+ Logger.instance.unknown "Config Validated"
101
+ end
102
+ def increment(options:)
103
+ manifest = Manifest.new(config: @config)
104
+ old = manifest.build_version
105
+ manifest.increment_build_version
106
+ new = manifest.build_version
107
+ Logger.instance.info "Update build version from:\n#{old}\nto:\n#{new}"
108
+ end
109
+ def dostage(options:)
110
+ Stager.new(config: @config, options: options).stage
111
+ end
112
+ def dounstage(options:)
113
+ Stager.new(config: @config, options: options).unstage
114
+ end
115
+ end
116
+ RokuBuilder.register_plugin(Core)
117
+ end
@@ -0,0 +1,104 @@
1
+ # ********** Copyright Viacom, Inc. Apache 2.0 **********
2
+
3
+ module RokuBuilder
4
+
5
+ # Collects information on a package for submission
6
+ class Inspector < Util
7
+ extend Plugin
8
+
9
+ def self.commands
10
+ {
11
+ inspect: {device: true, source: true},
12
+ screencapture: {device: true}
13
+ }
14
+ end
15
+
16
+ def self.parse_options(parser:, options:)
17
+ parser.separator "Commands:"
18
+ parser.on("--inspect", "Print out information about a packaged app") do
19
+ options[:inspect] = true
20
+ end
21
+ parser.on("-S", "--screencapture", "Save a screencapture to the output file/folder") do
22
+ options[:screencapture] = true
23
+ end
24
+ parser.separator "Options:"
25
+ parser.on("--password PASSWORD", "Password used for inspect") do |p|
26
+ options[:password] = p
27
+ end
28
+ end
29
+
30
+ # Inspects the given pkg
31
+ def inspect(options:)
32
+ pkg = File.join(@config.in[:folder], @config.in[:file])
33
+ pkg = pkg+".pkg" unless pkg.end_with?(".pkg")
34
+ # upload new key with password
35
+ path = "/plugin_inspect"
36
+ conn = multipart_connection
37
+ payload = {
38
+ mysubmit: "Inspect",
39
+ passwd: options[:password],
40
+ archive: Faraday::UploadIO.new(pkg, 'application/octet-stream')
41
+ }
42
+ response = conn.post path, payload
43
+
44
+ app_name = /App Name:\s*<\/td>\s*<td>\s*<font[^>]*>([^<]*)<\/font>\s*<\/td>/.match(response.body)
45
+ dev_id = nil
46
+ creation_date = nil
47
+ dev_zip = nil
48
+ if app_name
49
+ app_name = app_name[1]
50
+ dev_id = /Dev ID:\s*<\/td>\s*<td>\s*<font[^>]*>([^<]*)<\/font>\s*<\/td>/.match(response.body)[1]
51
+ creation_date = /new Date\(([^)]*)\)/.match(response.body.delete("\n"))[1]
52
+ dev_zip = /dev.zip:\s*<\/td>\s*<td>\s*<font[^>]*>([^<]*)<\/font>\s*<\/td>/.match(response.body)[1]
53
+ else
54
+ app_name = /App Name:[^<]*<div[^>]*>([^<]*)<\/div>/.match(response.body)[1]
55
+ dev_id = /Dev ID:[^<]*<div[^>]*><font[^>]*>([^<]*)<\/font><\/div>/.match(response.body)[1]
56
+ creation_date = /new Date\(([^\/]*)\)/.match(response.body.delete("\n"))[1]
57
+ dev_zip = /dev.zip:[^<]*<div[^>]*><font[^>]*>([^<]*)<\/font><\/div>/.match(response.body)[1]
58
+ end
59
+
60
+ info = {app_name: app_name, dev_id: dev_id, creation_date: Time.at(creation_date.to_i).to_s, dev_zip: dev_zip}
61
+
62
+ inspect_logger = ::Logger.new(STDOUT)
63
+ inspect_logger.formatter = proc {|_severity, _datetime, _progname, msg|
64
+ "%s\n\r" % [msg]
65
+ }
66
+ inspect_logger.unknown "=============================================================="
67
+ inspect_logger.unknown "App Name: #{info[:app_name]}"
68
+ inspect_logger.unknown "Dev ID: #{info[:dev_id]}"
69
+ inspect_logger.unknown "Creation Date: #{info[:creation_date]}"
70
+ inspect_logger.unknown "dev.zip: #{info[:dev_zip]}"
71
+ inspect_logger.unknown "=============================================================="
72
+
73
+ end
74
+
75
+ # Capture a screencapture for the currently sideloaded app
76
+ # @return [Boolean] Success
77
+ def screencapture(options:)
78
+ out = @config.out
79
+ payload = {
80
+ mysubmit: "Screenshot",
81
+ passwd: @dev_password,
82
+ archive: Faraday::UploadIO.new(File::NULL, 'application/octet-stream')
83
+ }
84
+ response = multipart_connection.post "/plugin_inspect", payload
85
+
86
+ path = /<img src="([^"]*)">/.match(response.body)
87
+ raise ExecutionError, "Failed to capture screen" unless path
88
+ path = path[1]
89
+
90
+ unless out[:file]
91
+ out[:file] = /time=([^"]*)">/.match(response.body)
92
+ out[:file] = "dev_#{out[:file][1]}.jpg" if out[:file]
93
+ end
94
+
95
+ response = simple_connection.get path
96
+
97
+ File.open(File.join(out[:folder], out[:file]), "w") do |io|
98
+ io.write(response.body)
99
+ end
100
+ @logger.info "Screen captured to #{File.join(out[:folder], out[:file])}"
101
+ end
102
+ end
103
+ RokuBuilder.register_plugin(Inspector)
104
+ end