openc3 5.0.6

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 (307) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +18 -0
  3. data/Guardfile +35 -0
  4. data/LICENSE.txt +727 -0
  5. data/README.md +37 -0
  6. data/Rakefile +131 -0
  7. data/bin/cstol_converter +1178 -0
  8. data/bin/openc3cli +531 -0
  9. data/bin/rubysloc +139 -0
  10. data/data/config/_array_params.yaml +23 -0
  11. data/data/config/_id_items.yaml +24 -0
  12. data/data/config/_id_params.yaml +58 -0
  13. data/data/config/_interfaces.yaml +214 -0
  14. data/data/config/_interfaces.yaml.err +1017 -0
  15. data/data/config/_items.yaml +20 -0
  16. data/data/config/_params.yaml +60 -0
  17. data/data/config/cmd_tlm_server.yaml +136 -0
  18. data/data/config/command.yaml +44 -0
  19. data/data/config/command_modifiers.yaml +160 -0
  20. data/data/config/command_telemetry.yaml +3 -0
  21. data/data/config/interface_modifiers.yaml +104 -0
  22. data/data/config/item_modifiers.yaml +221 -0
  23. data/data/config/microservice.yaml +78 -0
  24. data/data/config/param_item_modifiers.yaml +52 -0
  25. data/data/config/parameter_modifiers.yaml +200 -0
  26. data/data/config/plugins.yaml +80 -0
  27. data/data/config/protocols.yaml +290 -0
  28. data/data/config/screen.yaml +147 -0
  29. data/data/config/table_manager.yaml +89 -0
  30. data/data/config/table_parameter_modifiers.yaml +9 -0
  31. data/data/config/target.yaml +142 -0
  32. data/data/config/target_config.yaml +94 -0
  33. data/data/config/telemetry.yaml +87 -0
  34. data/data/config/telemetry_modifiers.yaml +159 -0
  35. data/data/config/tool.yaml +63 -0
  36. data/data/config/unknown.yaml +3 -0
  37. data/data/config/widgets.yaml +1505 -0
  38. data/ext/mkrf_conf.rb +49 -0
  39. data/ext/openc3/ext/array/array.c +122 -0
  40. data/ext/openc3/ext/array/extconf.rb +13 -0
  41. data/ext/openc3/ext/buffered_file/buffered_file.c +198 -0
  42. data/ext/openc3/ext/buffered_file/extconf.rb +13 -0
  43. data/ext/openc3/ext/config_parser/config_parser.c +280 -0
  44. data/ext/openc3/ext/config_parser/extconf.rb +13 -0
  45. data/ext/openc3/ext/crc/crc.c +351 -0
  46. data/ext/openc3/ext/crc/extconf.rb +13 -0
  47. data/ext/openc3/ext/openc3_io/extconf.rb +13 -0
  48. data/ext/openc3/ext/openc3_io/openc3_io.c +158 -0
  49. data/ext/openc3/ext/packet/extconf.rb +13 -0
  50. data/ext/openc3/ext/packet/packet.c +318 -0
  51. data/ext/openc3/ext/platform/extconf.rb +13 -0
  52. data/ext/openc3/ext/platform/platform.c +134 -0
  53. data/ext/openc3/ext/polynomial_conversion/extconf.rb +13 -0
  54. data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +79 -0
  55. data/ext/openc3/ext/string/extconf.rb +13 -0
  56. data/ext/openc3/ext/string/string.c +63 -0
  57. data/ext/openc3/ext/structure/structure.c +1719 -0
  58. data/ext/openc3/ext/tabbed_plots_config/extconf.rb +13 -0
  59. data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +62 -0
  60. data/ext/openc3/ext/telemetry/extconf.rb +13 -0
  61. data/ext/openc3/ext/telemetry/telemetry.c +336 -0
  62. data/lib/cosmos.rb +20 -0
  63. data/lib/cosmosc2.rb +20 -0
  64. data/lib/openc3/api/api.rb +39 -0
  65. data/lib/openc3/api/authorized_api.rb +30 -0
  66. data/lib/openc3/api/cmd_api.rb +451 -0
  67. data/lib/openc3/api/config_api.rb +58 -0
  68. data/lib/openc3/api/interface_api.rb +117 -0
  69. data/lib/openc3/api/limits_api.rb +375 -0
  70. data/lib/openc3/api/router_api.rb +117 -0
  71. data/lib/openc3/api/settings_api.rb +70 -0
  72. data/lib/openc3/api/target_api.rb +78 -0
  73. data/lib/openc3/api/tlm_api.rb +455 -0
  74. data/lib/openc3/bridge/bridge.rb +54 -0
  75. data/lib/openc3/bridge/bridge_config.rb +167 -0
  76. data/lib/openc3/bridge/bridge_interface_thread.rb +42 -0
  77. data/lib/openc3/bridge/bridge_router_thread.rb +42 -0
  78. data/lib/openc3/ccsds/ccsds_packet.rb +68 -0
  79. data/lib/openc3/ccsds/ccsds_parser.rb +148 -0
  80. data/lib/openc3/config/config_parser.rb +549 -0
  81. data/lib/openc3/config/meta_config_parser.rb +74 -0
  82. data/lib/openc3/conversions/conversion.rb +70 -0
  83. data/lib/openc3/conversions/generic_conversion.rb +83 -0
  84. data/lib/openc3/conversions/packet_time_formatted_conversion.rb +43 -0
  85. data/lib/openc3/conversions/packet_time_seconds_conversion.rb +43 -0
  86. data/lib/openc3/conversions/polynomial_conversion.rb +87 -0
  87. data/lib/openc3/conversions/processor_conversion.rb +70 -0
  88. data/lib/openc3/conversions/received_count_conversion.rb +38 -0
  89. data/lib/openc3/conversions/received_time_formatted_conversion.rb +42 -0
  90. data/lib/openc3/conversions/received_time_seconds_conversion.rb +42 -0
  91. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +171 -0
  92. data/lib/openc3/conversions/unix_time_conversion.rb +68 -0
  93. data/lib/openc3/conversions/unix_time_formatted_conversion.rb +49 -0
  94. data/lib/openc3/conversions/unix_time_seconds_conversion.rb +49 -0
  95. data/lib/openc3/conversions.rb +34 -0
  96. data/lib/openc3/core_ext/array.rb +416 -0
  97. data/lib/openc3/core_ext/binding.rb +29 -0
  98. data/lib/openc3/core_ext/class.rb +72 -0
  99. data/lib/openc3/core_ext/exception.rb +61 -0
  100. data/lib/openc3/core_ext/file.rb +83 -0
  101. data/lib/openc3/core_ext/hash.rb +37 -0
  102. data/lib/openc3/core_ext/io.rb +134 -0
  103. data/lib/openc3/core_ext/kernel.rb +42 -0
  104. data/lib/openc3/core_ext/math.rb +128 -0
  105. data/lib/openc3/core_ext/matrix.rb +156 -0
  106. data/lib/openc3/core_ext/objectspace.rb +36 -0
  107. data/lib/openc3/core_ext/openc3_io.rb +57 -0
  108. data/lib/openc3/core_ext/range.rb +27 -0
  109. data/lib/openc3/core_ext/socket.rb +38 -0
  110. data/lib/openc3/core_ext/string.rb +389 -0
  111. data/lib/openc3/core_ext/stringio.rb +33 -0
  112. data/lib/openc3/core_ext/time.rb +508 -0
  113. data/lib/openc3/core_ext.rb +36 -0
  114. data/lib/openc3/interfaces/interface.rb +498 -0
  115. data/lib/openc3/interfaces/linc_interface.rb +475 -0
  116. data/lib/openc3/interfaces/protocols/burst_protocol.rb +192 -0
  117. data/lib/openc3/interfaces/protocols/crc_protocol.rb +193 -0
  118. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +155 -0
  119. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +56 -0
  120. data/lib/openc3/interfaces/protocols/length_protocol.rb +165 -0
  121. data/lib/openc3/interfaces/protocols/override_protocol.rb +60 -0
  122. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +206 -0
  123. data/lib/openc3/interfaces/protocols/protocol.rb +82 -0
  124. data/lib/openc3/interfaces/protocols/template_protocol.rb +261 -0
  125. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +93 -0
  126. data/lib/openc3/interfaces/serial_interface.rb +94 -0
  127. data/lib/openc3/interfaces/simulated_target_interface.rb +168 -0
  128. data/lib/openc3/interfaces/stream_interface.rb +81 -0
  129. data/lib/openc3/interfaces/tcpip_client_interface.rb +69 -0
  130. data/lib/openc3/interfaces/tcpip_server_interface.rb +629 -0
  131. data/lib/openc3/interfaces/udp_interface.rb +169 -0
  132. data/lib/openc3/interfaces.rb +44 -0
  133. data/lib/openc3/io/buffered_file.rb +109 -0
  134. data/lib/openc3/io/io_multiplexer.rb +80 -0
  135. data/lib/openc3/io/json_api_object.rb +208 -0
  136. data/lib/openc3/io/json_drb.rb +335 -0
  137. data/lib/openc3/io/json_drb_object.rb +114 -0
  138. data/lib/openc3/io/json_drb_rack.rb +84 -0
  139. data/lib/openc3/io/json_rpc.rb +420 -0
  140. data/lib/openc3/io/openc3_snmp.rb +58 -0
  141. data/lib/openc3/io/posix_serial_driver.rb +156 -0
  142. data/lib/openc3/io/raw_logger.rb +167 -0
  143. data/lib/openc3/io/raw_logger_pair.rb +77 -0
  144. data/lib/openc3/io/serial_driver.rb +105 -0
  145. data/lib/openc3/io/stderr.rb +43 -0
  146. data/lib/openc3/io/stdout.rb +43 -0
  147. data/lib/openc3/io/udp_sockets.rb +194 -0
  148. data/lib/openc3/io/win32_serial_driver.rb +196 -0
  149. data/lib/openc3/logs/log_writer.rb +302 -0
  150. data/lib/openc3/logs/packet_log_constants.rb +62 -0
  151. data/lib/openc3/logs/packet_log_reader.rb +345 -0
  152. data/lib/openc3/logs/packet_log_writer.rb +299 -0
  153. data/lib/openc3/logs/text_log_writer.rb +68 -0
  154. data/lib/openc3/logs.rb +25 -0
  155. data/lib/openc3/microservices/cleanup_microservice.rb +68 -0
  156. data/lib/openc3/microservices/decom_microservice.rb +136 -0
  157. data/lib/openc3/microservices/interface_microservice.rb +532 -0
  158. data/lib/openc3/microservices/log_microservice.rb +108 -0
  159. data/lib/openc3/microservices/microservice.rb +204 -0
  160. data/lib/openc3/microservices/plugin_microservice.rb +43 -0
  161. data/lib/openc3/microservices/reaction_microservice.rb +541 -0
  162. data/lib/openc3/microservices/reducer_microservice.rb +313 -0
  163. data/lib/openc3/microservices/router_microservice.rb +44 -0
  164. data/lib/openc3/microservices/text_log_microservice.rb +84 -0
  165. data/lib/openc3/microservices/timeline_microservice.rb +363 -0
  166. data/lib/openc3/microservices/trigger_group_microservice.rb +638 -0
  167. data/lib/openc3/models/activity_model.rb +319 -0
  168. data/lib/openc3/models/auth_model.rb +65 -0
  169. data/lib/openc3/models/cvt_model.rb +185 -0
  170. data/lib/openc3/models/environment_model.rb +58 -0
  171. data/lib/openc3/models/gem_model.rb +137 -0
  172. data/lib/openc3/models/info_model.rb +31 -0
  173. data/lib/openc3/models/interface_model.rb +281 -0
  174. data/lib/openc3/models/interface_status_model.rb +117 -0
  175. data/lib/openc3/models/metadata_model.rb +139 -0
  176. data/lib/openc3/models/metric_model.rb +59 -0
  177. data/lib/openc3/models/microservice_model.rb +206 -0
  178. data/lib/openc3/models/microservice_status_model.rb +74 -0
  179. data/lib/openc3/models/model.rb +204 -0
  180. data/lib/openc3/models/note_model.rb +122 -0
  181. data/lib/openc3/models/notification_model.rb +40 -0
  182. data/lib/openc3/models/ping_model.rb +35 -0
  183. data/lib/openc3/models/plugin_model.rb +292 -0
  184. data/lib/openc3/models/process_status_model.rb +76 -0
  185. data/lib/openc3/models/reaction_model.rb +322 -0
  186. data/lib/openc3/models/reducer_model.rb +65 -0
  187. data/lib/openc3/models/router_model.rb +35 -0
  188. data/lib/openc3/models/router_status_model.rb +27 -0
  189. data/lib/openc3/models/scope_model.rb +153 -0
  190. data/lib/openc3/models/settings_model.rb +55 -0
  191. data/lib/openc3/models/sorted_model.rb +167 -0
  192. data/lib/openc3/models/target_model.rb +759 -0
  193. data/lib/openc3/models/timeline_model.rb +154 -0
  194. data/lib/openc3/models/tool_config_model.rb +38 -0
  195. data/lib/openc3/models/tool_model.rb +262 -0
  196. data/lib/openc3/models/trigger_group_model.rb +186 -0
  197. data/lib/openc3/models/trigger_model.rb +330 -0
  198. data/lib/openc3/models/widget_model.rb +138 -0
  199. data/lib/openc3/operators/microservice_operator.rb +128 -0
  200. data/lib/openc3/operators/operator.rb +277 -0
  201. data/lib/openc3/packets/binary_accessor.rb +1207 -0
  202. data/lib/openc3/packets/commands.rb +373 -0
  203. data/lib/openc3/packets/json_packet.rb +134 -0
  204. data/lib/openc3/packets/limits.rb +271 -0
  205. data/lib/openc3/packets/limits_response.rb +53 -0
  206. data/lib/openc3/packets/packet.rb +1168 -0
  207. data/lib/openc3/packets/packet_config.rb +625 -0
  208. data/lib/openc3/packets/packet_item.rb +586 -0
  209. data/lib/openc3/packets/packet_item_limits.rb +162 -0
  210. data/lib/openc3/packets/parsers/format_string_parser.rb +65 -0
  211. data/lib/openc3/packets/parsers/limits_parser.rb +159 -0
  212. data/lib/openc3/packets/parsers/limits_response_parser.rb +61 -0
  213. data/lib/openc3/packets/parsers/packet_item_parser.rb +272 -0
  214. data/lib/openc3/packets/parsers/packet_parser.rb +134 -0
  215. data/lib/openc3/packets/parsers/processor_parser.rb +73 -0
  216. data/lib/openc3/packets/parsers/state_parser.rb +127 -0
  217. data/lib/openc3/packets/parsers/xtce_converter.rb +442 -0
  218. data/lib/openc3/packets/parsers/xtce_parser.rb +722 -0
  219. data/lib/openc3/packets/structure.rb +553 -0
  220. data/lib/openc3/packets/structure_item.rb +365 -0
  221. data/lib/openc3/packets/telemetry.rb +487 -0
  222. data/lib/openc3/processors/processor.rb +86 -0
  223. data/lib/openc3/processors/statistics_processor.rb +82 -0
  224. data/lib/openc3/processors/watermark_processor.rb +58 -0
  225. data/lib/openc3/processors.rb +24 -0
  226. data/lib/openc3/script/api_shared.rb +828 -0
  227. data/lib/openc3/script/calendar.rb +89 -0
  228. data/lib/openc3/script/commands.rb +227 -0
  229. data/lib/openc3/script/exceptions.rb +29 -0
  230. data/lib/openc3/script/extract.rb +161 -0
  231. data/lib/openc3/script/limits.rb +60 -0
  232. data/lib/openc3/script/script.rb +299 -0
  233. data/lib/openc3/script/script_runner.rb +238 -0
  234. data/lib/openc3/script/storage.rb +146 -0
  235. data/lib/openc3/script/suite.rb +542 -0
  236. data/lib/openc3/script/suite_results.rb +196 -0
  237. data/lib/openc3/script/suite_runner.rb +217 -0
  238. data/lib/openc3/script.rb +21 -0
  239. data/lib/openc3/streams/serial_stream.rb +167 -0
  240. data/lib/openc3/streams/stream.rb +63 -0
  241. data/lib/openc3/streams/tcpip_client_stream.rb +116 -0
  242. data/lib/openc3/streams/tcpip_socket_stream.rb +195 -0
  243. data/lib/openc3/system/system.rb +127 -0
  244. data/lib/openc3/system/system_config.rb +411 -0
  245. data/lib/openc3/system/target.rb +269 -0
  246. data/lib/openc3/system.rb +24 -0
  247. data/lib/openc3/tools/cmd_tlm_server/api.rb +20 -0
  248. data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +320 -0
  249. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +294 -0
  250. data/lib/openc3/tools/table_manager/table.rb +77 -0
  251. data/lib/openc3/tools/table_manager/table_config.rb +273 -0
  252. data/lib/openc3/tools/table_manager/table_item.rb +90 -0
  253. data/lib/openc3/tools/table_manager/table_item_parser.rb +66 -0
  254. data/lib/openc3/tools/table_manager/table_manager_core.rb +333 -0
  255. data/lib/openc3/tools/table_manager/table_parser.rb +93 -0
  256. data/lib/openc3/tools/test_runner/test.rb +67 -0
  257. data/lib/openc3/top_level.rb +595 -0
  258. data/lib/openc3/topics/autonomic_topic.rb +52 -0
  259. data/lib/openc3/topics/calendar_topic.rb +44 -0
  260. data/lib/openc3/topics/command_decom_topic.rb +76 -0
  261. data/lib/openc3/topics/command_topic.rb +83 -0
  262. data/lib/openc3/topics/config_topic.rb +68 -0
  263. data/lib/openc3/topics/interface_topic.rb +73 -0
  264. data/lib/openc3/topics/limits_event_topic.rb +109 -0
  265. data/lib/openc3/topics/notifications_topic.rb +28 -0
  266. data/lib/openc3/topics/router_topic.rb +85 -0
  267. data/lib/openc3/topics/telemetry_decom_topic.rb +54 -0
  268. data/lib/openc3/topics/telemetry_topic.rb +36 -0
  269. data/lib/openc3/topics/timeline_topic.rb +45 -0
  270. data/lib/openc3/topics/topic.rb +53 -0
  271. data/lib/openc3/utilities/authentication.rb +141 -0
  272. data/lib/openc3/utilities/authorization.rb +51 -0
  273. data/lib/openc3/utilities/crc.rb +278 -0
  274. data/lib/openc3/utilities/csv.rb +153 -0
  275. data/lib/openc3/utilities/logger.rb +187 -0
  276. data/lib/openc3/utilities/message_log.rb +91 -0
  277. data/lib/openc3/utilities/metric.rb +141 -0
  278. data/lib/openc3/utilities/process_manager.rb +139 -0
  279. data/lib/openc3/utilities/quaternion.rb +257 -0
  280. data/lib/openc3/utilities/ruby_lex_utils.rb +568 -0
  281. data/lib/openc3/utilities/s3.rb +202 -0
  282. data/lib/openc3/utilities/s3_autoload.rb +9 -0
  283. data/lib/openc3/utilities/s3_file_cache.rb +274 -0
  284. data/lib/openc3/utilities/simulated_target.rb +117 -0
  285. data/lib/openc3/utilities/sleeper.rb +51 -0
  286. data/lib/openc3/utilities/store.rb +23 -0
  287. data/lib/openc3/utilities/store_autoload.rb +237 -0
  288. data/lib/openc3/utilities/zip.rb +21 -0
  289. data/lib/openc3/utilities.rb +35 -0
  290. data/lib/openc3/version.rb +14 -0
  291. data/lib/openc3/win32/excel.rb +132 -0
  292. data/lib/openc3/win32/win32.rb +402 -0
  293. data/lib/openc3/win32/win32_main.rb +333 -0
  294. data/lib/openc3.rb +49 -0
  295. data/tasks/gemfile_stats.rake +113 -0
  296. data/tasks/spec.rake +30 -0
  297. data/templates/plugin-template/README.md +15 -0
  298. data/templates/plugin-template/Rakefile +12 -0
  299. data/templates/plugin-template/plugin.gemspec +23 -0
  300. data/templates/plugin-template/plugin.txt +9 -0
  301. data/templates/plugin-template/targets/TARGET/cmd_tlm/cmd.txt +8 -0
  302. data/templates/plugin-template/targets/TARGET/cmd_tlm/tlm.txt +8 -0
  303. data/templates/plugin-template/targets/TARGET/lib/target.rb +10 -0
  304. data/templates/plugin-template/targets/TARGET/procedures/procedure.rb +3 -0
  305. data/templates/plugin-template/targets/TARGET/screens/status.txt +9 -0
  306. data/templates/plugin-template/targets/TARGET/target.txt +5 -0
  307. metadata +849 -0
data/bin/openc3cli ADDED
@@ -0,0 +1,531 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: ascii-8bit
3
+
4
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
5
+ # All Rights Reserved.
6
+ #
7
+ # This program is free software; you can modify and/or redistribute it
8
+ # under the terms of the GNU Affero General Public License
9
+ # as published by the Free Software Foundation; version 3 with
10
+ # attribution addendums as found in the LICENSE.txt
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Affero General Public License for more details.
16
+
17
+ # Modified by OpenC3, Inc.
18
+ # All changes Copyright 2022, OpenC3, Inc.
19
+ # All Rights Reserved
20
+
21
+ # This file will handle OpenC3 tasks such as instantiating a new project
22
+
23
+ require 'openc3'
24
+ require 'openc3/utilities/s3'
25
+ require 'openc3/models/scope_model'
26
+ require 'openc3/models/plugin_model'
27
+ require 'openc3/packets/packet_config'
28
+ require 'openc3/bridge/bridge'
29
+ require 'ostruct'
30
+ require 'optparse'
31
+ require 'openc3/utilities/zip'
32
+ require 'fileutils'
33
+ require 'find'
34
+ require 'json'
35
+ require 'redis'
36
+ require 'psych'
37
+ require 'erb'
38
+
39
+ $redis_url = "redis://#{ENV['OPENC3_REDIS_HOSTNAME']}:#{ENV['OPENC3_REDIS_PORT']}"
40
+
41
+ # Build the OpenStruct and OptionParser here as constants so we can use in methods
42
+ MIGRATE_OPTIONS = OpenStruct.new
43
+ MIGRATE_OPTIONS.all = false
44
+ MIGRATE_PARSER = OptionParser.new do |op|
45
+ op.banner = "cli migrate PLUGIN [TGT1...] # Create a OpenC3 plugin from existing COSMOS 4 targets"
46
+ op.on("-a", "--all", " Move all COSMOS 4 targets into a single OpenC3 plugin") do
47
+ MIGRATE_OPTIONS.all = true
48
+ end
49
+ end
50
+ ERROR_CODE = 1
51
+
52
+ # Prints the usage text for the openc3cli executable
53
+ def print_usage
54
+ puts "Usage:"
55
+ puts " cli help # Displays this information"
56
+ puts " cli rake # Runs rake in the local directory"
57
+ puts " cli validate /PATH/FILENAME.gem SCOPE variables.txt # Validate a OpenC3 plugin gem file"
58
+ puts " cli load /PATH/FILENAME.gem SCOPE variables.txt # Loads a OpenC3 plugin gem file"
59
+ puts " cli generate plugin PLUGIN_NAME # Generate a OpenC3 plugin"
60
+ puts " #{MIGRATE_PARSER}"
61
+ puts " cli bridge CONFIG_FILENAME # Run OpenC3 host bridge"
62
+ puts " cli bridgesetup CONFIG_FILENAME # Create a default config file"
63
+ puts " cli geminstall GEMFILENAME # Install loaded gem to /gems"
64
+ puts " cli rubysloc # Counts Ruby SLOC recursively. Run with --help for more info."
65
+ puts " cli xtce_converter # Convert to and from the XTCE format. Run with --help for more info."
66
+ puts " cli cstol_converter # Converts CSTOL files (.prc) to OpenC3. Run with --help for more info."
67
+ puts ""
68
+ end
69
+
70
+ def generate(args)
71
+ case args[0]
72
+ when 'plugin'
73
+ if args.length != 2
74
+ abort("Usage: cli generate plugin <NAME>")
75
+ end
76
+ if args[1] =~ /\s/
77
+ abort("Plugin names can not have spaces!")
78
+ end
79
+
80
+ plugin = args[1].downcase.gsub(/_+|-+/, '-')
81
+ plugin_name = "openc3-#{plugin}"
82
+ if File.exist?(plugin_name)
83
+ abort("Plugin #{plugin_name} already exists!")
84
+ end
85
+ FileUtils.mkdir(plugin_name)
86
+ Dir.chdir(plugin_name) # Change to the plugin path to make copying easier
87
+
88
+ # Grab the plugin template
89
+ template_dir = "#{File.dirname(__FILE__)}/../templates/plugin-template"
90
+ target_name = plugin.upcase.gsub('-', '_')
91
+ target_lib_filename = "#{target_name.downcase}.rb"
92
+ target_class = target_lib_filename.filename_to_class_name
93
+ target_object = target_name.downcase
94
+ b = binding
95
+
96
+ Dir.glob("#{template_dir}/**/*").each do |file|
97
+ base_name = file.sub("#{template_dir}/", '')
98
+ # Rename the template TARGET to our actual target named after the plugin
99
+ base_name.sub!("targets/TARGET", "targets/#{target_name}")
100
+ if File.directory?(file)
101
+ FileUtils.mkdir(base_name)
102
+ next
103
+ end
104
+ base_name.sub!("target.rb", target_lib_filename)
105
+ base_name.sub!("plugin.gemspec", "#{plugin_name}.gemspec")
106
+ output = ERB.new(File.read(file), trim_mode: "-").result(b)
107
+ File.open(base_name, 'w') do |file|
108
+ file.write output
109
+ end
110
+ end
111
+
112
+ puts "Plugin #{plugin_name} successfully generated!\n"
113
+ return target_name # This makes the migrate method easier
114
+ else # Unknown generator
115
+ abort("Unknown generator #{args[0]}")
116
+ end
117
+ end
118
+
119
+ def migrate(args)
120
+ MIGRATE_PARSER.parse!(args)
121
+ abort(MIGRATE_PARSER.to_s) if args.length == 0
122
+ if MIGRATE_OPTIONS.all and args.length > 1
123
+ puts "Only specify the plugin name when using --all"
124
+ abort(MIGRATE_PARSER.to_s)
125
+ end
126
+ if !MIGRATE_OPTIONS.all and args.length < 2
127
+ puts "Specify the individual target names when not using --all"
128
+ abort(MIGRATE_PARSER.to_s)
129
+ end
130
+ if Dir.glob("config/targets/**/*").empty?
131
+ puts "No targets found in config/targets/*"
132
+ puts "Migrate must be run within an existing COSMOS configuration"
133
+ abort(MIGRATE_PARSER.to_s)
134
+ end
135
+
136
+ ###############################################################
137
+ # Create the framework for the plugin
138
+ # NOTE: generate does a chdir to be inside the plugin directory
139
+ ###############################################################
140
+ plugin = args.shift
141
+ target_name = generate(['plugin', plugin])
142
+ # Delete target contents from the plugin framework (but keep directory)
143
+ FileUtils.rm_rf Dir.glob("targets/#{target_name}/*")
144
+
145
+ if MIGRATE_OPTIONS.all
146
+ # Grab all target directories to match the command line input
147
+ args = Dir.glob("../config/targets/*").map { |path| File.basename(path) }
148
+ else
149
+ # Ensure targets passed in on command line actually exist
150
+ args.each do |target|
151
+ path = File.join('..', 'config', 'targets', target)
152
+ unless File.exist?(path)
153
+ puts "Target #{path} does not exist!"
154
+ abort(MIGRATE_PARSER.to_s)
155
+ end
156
+ end
157
+ end
158
+
159
+ # Overwrite plugin.txt with specified targets
160
+ plugin = File.open('plugin.txt', 'w')
161
+ plugin.puts "TARGET #{target_name}"
162
+
163
+ args.each do |target|
164
+ puts "Migrating target #{target}"
165
+ FileUtils.cp_r "../config/targets/#{target}", 'targets'
166
+ plugin.puts "TARGET #{target}"
167
+ end
168
+ plugin.puts ""
169
+
170
+ puts "Migrating /lib & /procedures to #{target_name}"
171
+ FileUtils.cp_r '../lib', "targets/#{target_name}"
172
+ FileUtils.cp_r '../procedures', "targets/#{target_name}"
173
+
174
+ # Migrate cmd_tlm_server.txt info to plugin.txt
175
+ Dir.glob('targets/**/cmd_tlm_server*.txt') do |file|
176
+ File.open(file) do |file|
177
+ file.each do |line|
178
+ next if line =~ /^\s*#/ # Ignore comments
179
+ next if line.strip.empty? # Ignore empty lines
180
+
181
+ # Convert TARGET to MAP_TARGET
182
+ line.gsub!(/TARGET (\S+)/, 'MAP_TARGET \1')
183
+ plugin.puts line
184
+ end
185
+ end
186
+ plugin.puts ''
187
+ end
188
+ plugin.close
189
+ puts "Plugin complete: #{File.expand_path('.')}" # Remember we're inside the plugin dir
190
+ end
191
+
192
+ def xtce_converter(args)
193
+ options = {}
194
+ option_parser = OptionParser.new do |option_parser|
195
+ option_parser.banner = "Usage: xtce_converter [options] --import input_xtce_filename --output output_dir\n"+
196
+ " xtce_converter [options] --plugin /PATH/FILENAME.gem --output output_dir --variables variables.txt"
197
+ option_parser.separator("")
198
+ option_parser.on("-h", "--help", "Show this message") do
199
+ puts option_parser
200
+ exit
201
+ end
202
+ option_parser.on("-i VALUE", "--import VALUE", "Import the specified .xtce file") do |arg|
203
+ options[:import] = arg
204
+ end
205
+ option_parser.on("-o", "--output DIRECTORY", "Create files in the directory") do |arg|
206
+ options[:output] = arg
207
+ end
208
+ option_parser.on("-p", "--plugin PLUGIN", "Export .xtce file(s) from the plugin") do |arg|
209
+ options[:plugin] = arg
210
+ end
211
+ option_parser.on("-v", "--variables", "Optional variables file to pass to the plugin") do |arg|
212
+ options[:variables] = arg
213
+ end
214
+ end
215
+
216
+ begin
217
+ option_parser.parse!(args)
218
+ rescue => err
219
+ abort(option_parser.to_s)
220
+ end
221
+
222
+ if options[:import] && options[:plugin]
223
+ puts "xtce_converter options --import and --plugin are mutually exclusive"
224
+ abort(option_parser.to_s)
225
+ end
226
+
227
+ ENV['OPENC3_NO_STORE'] = '1' # it can be anything
228
+ OpenC3::Logger.stdout = false
229
+ OpenC3::Logger.level = OpenC3::Logger::DEBUG
230
+
231
+ if options[:import] && options[:output]
232
+ packet_config = OpenC3::PacketConfig.new
233
+ puts "Processing #{options[:import]}..."
234
+ packet_config.process_file(options[:import], nil)
235
+ puts "Writing OpenC3 config files to #{options[:output]}/"
236
+ packet_config.to_config(options[:output])
237
+ exit(0)
238
+ elsif options[:plugin] && options[:output]
239
+ begin
240
+ variables = nil
241
+ variables = JSON.parse(File.read(options[:variables]), :allow_nan => true, :create_additions => true) if options[:variables]
242
+ puts "Installing #{File.basename(options[:plugin])}"
243
+ plugin_hash = OpenC3::PluginModel.install_phase1(options[:plugin], variables, scope: 'DEFAULT', validate_only: true)
244
+ plugin_hash['variables']['xtce_output'] = options[:output]
245
+ OpenC3::PluginModel.install_phase2(plugin_hash['name'], plugin_hash['variables'], scope: 'DEFAULT', validate_only: true,
246
+ gem_file_path: options[:plugin])
247
+ result = 0 # bash and Windows consider 0 success
248
+ rescue => e
249
+ puts "Error: #{e.message}"
250
+ result = ERROR_CODE
251
+ ensure
252
+ name = Psych.safe_load(`gem spec #{options[:plugin]} name`).to_s
253
+ version = Psych.safe_load(`gem spec #{options[:plugin]} version`, permitted_classes: [Gem::Version]).to_s
254
+ Gem::Uninstaller.new(name, {:version => version, :force => true}).uninstall
255
+ exit(result)
256
+ end
257
+ else
258
+ abort(option_parser.to_s)
259
+ end
260
+ end
261
+
262
+ # A helper method to make the zip writing recursion work
263
+ def write_zip_entries(base_dir, entries, zip_path, io)
264
+ io.add(zip_path, base_dir) # Add the directory whether it has entries or not
265
+ entries.each do |e|
266
+ zip_file_path = File.join(zip_path, e)
267
+ disk_file_path = File.join(base_dir, e)
268
+ if File.directory? disk_file_path
269
+ recursively_deflate_directory(disk_file_path, io, zip_file_path)
270
+ else
271
+ put_into_archive(disk_file_path, io, zip_file_path)
272
+ end
273
+ end
274
+ end
275
+
276
+ def recursively_deflate_directory(disk_file_path, io, zip_file_path)
277
+ io.add(zip_file_path, disk_file_path)
278
+ write_zip_entries(disk_file_path, entries, zip_file_path, io)
279
+ end
280
+
281
+ def put_into_archive(disk_file_path, io, zip_file_path)
282
+ io.get_output_stream(zip_file_path) do |f|
283
+ data = nil
284
+ File.open(disk_file_path, 'rb') { |file| data = file.read }
285
+ f.write(data)
286
+ end
287
+ end
288
+
289
+ def validate_plugin(plugin_file_path, scope:, variables_file: nil)
290
+ ENV['OpenC3_NO_STORE'] = '1' # it can be anything
291
+ OpenC3::Logger.stdout = false
292
+ OpenC3::Logger.level = OpenC3::Logger::DEBUG
293
+ scope ||= 'DEFAULT'
294
+ variables = nil
295
+ variables = JSON.parse(File.read(variables_file), :allow_nan => true, :create_additions => true) if variables_file
296
+ puts "Installing #{File.basename(plugin_file_path)}"
297
+ plugin_hash = OpenC3::PluginModel.install_phase1(plugin_file_path, existing_variables: variables, scope: scope, validate_only: true)
298
+ OpenC3::PluginModel.install_phase2(plugin_hash, scope: scope, validate_only: true,
299
+ gem_file_path: plugin_file_path)
300
+ puts "Successfully validated #{File.basename(plugin_file_path)}"
301
+ result = 0 # bash and Windows consider 0 success
302
+ rescue => e
303
+ puts "Error: #{e.message}"
304
+ result = ERROR_CODE
305
+ ensure
306
+ begin
307
+ name = Psych.safe_load(`gem spec #{plugin_file_path} name`).to_s
308
+ version = Psych.safe_load(`gem spec #{plugin_file_path} version`, permitted_classes: [Gem::Version]).to_s
309
+ Gem::Uninstaller.new(name, {:version => version, :force => true}).uninstall
310
+ rescue => e
311
+ puts "Could not uninstall #{plugin_file_path} due to #{e.message}"
312
+ end
313
+ exit(result)
314
+ end
315
+
316
+ def update_plugin(plugin_file_path, plugin_name, variables: nil, plugin_txt_lines: nil, scope:)
317
+ new_gem = File.basename(plugin_file_path)
318
+ old_gem = plugin_name.split("__")[0]
319
+ puts "Updating existing plugin: #{plugin_name} with #{File.basename(plugin_file_path)}"
320
+ plugin_model = OpenC3::PluginModel.get_model(name: plugin_name, scope: scope)
321
+ begin
322
+ # Only update if something has changed
323
+ if (new_gem != old_gem) or (variables != plugin_model.variables) or (plugin_txt_lines != plugin_model.plugin_txt_lines)
324
+ variables = plugin_model.variables unless variables
325
+ plugin_model.destroy
326
+ plugin_hash = OpenC3::PluginModel.install_phase1(plugin_file_path, existing_variables: variables, existing_plugin_txt_lines: plugin_txt_lines, process_existing: true, scope: scope)
327
+ OpenC3::PluginModel.install_phase2(plugin_hash, scope: scope)
328
+ else
329
+ puts "No changes detected - Exiting without change"
330
+ end
331
+ rescue => error
332
+ puts error.formatted
333
+ plugin_model.restore if plugin_model.destroyed?
334
+ raise error
335
+ end
336
+ end
337
+
338
+ # Loads a plugin into the OpenC3 system
339
+ # This code is used from the command line and is the same code that gets called if you
340
+ # edit/upgrade or install a new plugin from the Admin interface
341
+ #
342
+ # Usage: cli load gemfile_path [scope] [plugin_hash_file_path]
343
+ #
344
+ # With just gemfile_path and/or scope: Will do nothing if any plugin
345
+ # with the same gem file already exists
346
+ #
347
+ # Otherwise will do what the plugin_hash_file says to do
348
+ # Plugin hash file must have the exact name of an existing plugin for upgrades and edits
349
+ # Otherwise, it will be assumed that the plugin is intentionally being installed for a second
350
+ # time
351
+ #
352
+ def load_plugin(plugin_file_path, scope:, plugin_hash_file: nil)
353
+ scope ||= 'DEFAULT'
354
+ # Only create the scope if it doesn't already exist
355
+ unless OpenC3::ScopeModel.names.include?(scope)
356
+ begin
357
+ scope_model = OpenC3::ScopeModel.new(name: scope, scope: scope)
358
+ scope_model.create
359
+ scope_model.deploy(".", {})
360
+ rescue => err
361
+ abort("Error creating scope: #{scope}: #{err.formatted}")
362
+ end
363
+ end
364
+
365
+ begin
366
+ if plugin_hash_file
367
+ # Admin Create / Edit / or Upgrade Plugin
368
+ OpenC3::PluginModel.install_phase1(plugin_file_path, scope: scope)
369
+ plugin_hash = JSON.parse(File.read(plugin_hash_file), :allow_nan => true, :create_additions => true)
370
+ else
371
+ # Init or Command Line openc3cli load with no plugin_hash_file
372
+ file_full_name = File.basename(plugin_file_path, ".gem")
373
+ file_gem_name = file_full_name.split('-')[0..-2].join('-')
374
+ found = false
375
+ plugin_names = OpenC3::PluginModel.names(scope: scope)
376
+ plugin_names.each do |plugin_name|
377
+ gem_name = plugin_name.split("__")[0]
378
+ full_name = File.basename(gem_name, ".gem")
379
+ gem_name = full_name.split('-')[0..-2].join('-')
380
+ if file_gem_name == gem_name
381
+ found = true
382
+ # Upgrade if version changed else do nothing
383
+ if file_full_name != full_name
384
+ update_plugin(plugin_file_path, plugin_name, scope: scope)
385
+ end
386
+ end
387
+ end
388
+ return if found
389
+
390
+ plugin_hash = OpenC3::PluginModel.install_phase1(plugin_file_path, scope: scope)
391
+ end
392
+
393
+ # Determine if plugin named in plugin_hash exists
394
+ existing_plugin_hash = OpenC3::PluginModel.get(name: plugin_hash['name'], scope: scope)
395
+
396
+ # Existing plugin hash will be present if plugin is being edited or upgraded
397
+ # If editing, gem name will match existing hash name
398
+ # If upgrading, gem name will not match the existing hash name
399
+
400
+ if existing_plugin_hash
401
+ # Upgrade or Edit
402
+ update_plugin(plugin_file_path, plugin_hash['name'], variables: plugin_hash['variables'], plugin_txt_lines: plugin_hash['plugin_txt_lines'], scope: scope)
403
+ else
404
+ # New Install
405
+ puts "Loading new plugin: #{plugin_file_path}\n#{plugin_hash}"
406
+ OpenC3::PluginModel.install_phase2(plugin_hash, scope: scope)
407
+ end
408
+ rescue => err
409
+ abort("Error installing plugin: #{scope}: #{plugin_file_path}: #{err.formatted}")
410
+ end
411
+ end
412
+
413
+ def unload_plugin(plugin_name, scope:)
414
+ scope ||= 'DEFAULT'
415
+ begin
416
+ OpenC3::PluginModel.new(name: plugin_name, scope: scope).destroy
417
+ OpenC3::Logger.info("PluginModel destroyed: #{plugin_name}", scope: scope)
418
+ rescue => err
419
+ abort("Error uninstalling plugin: #{scope}: #{plugin_name}: #{err.formatted}")
420
+ end
421
+ end
422
+
423
+ def gem_install(gem_filename)
424
+ OpenC3::GemModel.install(gem_filename)
425
+ end
426
+
427
+ def get_redis_keys
428
+ redis = Redis.new(url: $redis_url, username: ENV['OPENC3_REDIS_USERNAME'], password: ENV['OPENC3_REDIS_PASSWORD'])
429
+ puts "\n--- OpenC3 Redis database keys ---"
430
+ cursor = 0
431
+ keys = []
432
+ loop do
433
+ cursor, result = redis.scan(cursor)
434
+ keys.concat(result)
435
+ cursor = cursor.to_i # cursor is returned as a string
436
+ break if cursor == 0
437
+ end
438
+ keys.uniq!
439
+ keys.sort!
440
+ keys.select { |item| !item[/^tlm__/] }.each do |key|
441
+ puts "#{key}\n #{redis.hkeys(key)}"
442
+ rescue Redis::CommandError
443
+ begin
444
+ # CommandError is raised if you try to hkeys on a stream
445
+ puts "Stream: #{key}\n #{redis.xinfo(:stream, key)}"
446
+ rescue
447
+ puts "Unknown key '#{key}'"
448
+ end
449
+ end
450
+ puts "Packets Defs: #{keys.select { |item| item[/^tlm__/] }}"
451
+ end
452
+
453
+ if not ARGV[0].nil? # argument(s) given
454
+
455
+ # Handle each task
456
+ case ARGV[0].downcase
457
+
458
+ when 'rake'
459
+ puts `rake #{ARGV[1..-1].join(' ')}`
460
+
461
+ when 'validate'
462
+ validate_plugin(ARGV[1], scope: ARGV[2], variables_file: ARGV[3])
463
+
464
+ when 'load'
465
+ load_plugin(ARGV[1], scope: ARGV[2], plugin_hash_file: ARGV[3])
466
+
467
+ when 'unload'
468
+ unload_plugin(ARGV[1], scope: ARGV[2])
469
+
470
+ when 'geminstall'
471
+ gem_install(ARGV[1])
472
+
473
+ when 'generate'
474
+ generate(ARGV[1..-1])
475
+
476
+ when 'migrate'
477
+ migrate(ARGV[1..-1])
478
+
479
+ when 'rubysloc'
480
+ puts `ruby /openc3/bin/rubysloc #{ARGV[1..-1].join(' ')}`
481
+
482
+ when 'cstol_converter'
483
+ puts `ruby /openc3/bin/cstol_converter #{ARGV[1..-1].join(' ')}`
484
+
485
+ when 'xtce_converter'
486
+ xtce_converter(ARGV[1..-1])
487
+
488
+ when 'bridge'
489
+ ENV['OPENC3_NO_STORE'] = '1'
490
+ filename = ARGV[1]
491
+ filename = 'bridge.txt' unless filename
492
+ bridge = OpenC3::Bridge.new(filename)
493
+ begin
494
+ while true
495
+ sleep(1)
496
+ end
497
+ rescue Interrupt
498
+ exit(0)
499
+ end
500
+
501
+ when 'bridgesetup'
502
+ ENV['OPENC3_NO_STORE'] = '1'
503
+ filename = ARGV[1]
504
+ filename = 'bridge.txt' unless filename
505
+ unless File.exist?(filename)
506
+ OpenC3::BridgeConfig.generate_default(filename)
507
+ end
508
+
509
+ when 'help'
510
+ print_usage()
511
+
512
+ when 'redis'
513
+ case (ARGV[1])
514
+ when 'keys'
515
+ get_redis_keys()
516
+ when 'hget'
517
+ redis = Redis.new(url: $redis_url, username: ENV['OPENC3_REDIS_USERNAME'], password: ENV['OPENC3_REDIS_PASSWORD'])
518
+ puts JSON.parse(redis.hget(ARGV[2], ARGV[3]), :allow_nan => true, :create_additions => true)
519
+ else
520
+ puts "Unknown redis task: #{ARGV[1]}\n"
521
+ puts "Valid redis tasks: keys, hget"
522
+ end
523
+
524
+ else # Unknown task
525
+ print_usage()
526
+ abort("Unknown task: #{ARGV[0]}")
527
+ end
528
+
529
+ else # No arguments given
530
+ print_usage()
531
+ end
data/bin/rubysloc ADDED
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: ascii-8bit
3
+
4
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
5
+ # All Rights Reserved.
6
+ #
7
+ # This program is free software; you can modify and/or redistribute it
8
+ # under the terms of the GNU Affero General Public License
9
+ # as published by the Free Software Foundation; version 3 with
10
+ # attribution addendums as found in the LICENSE.txt
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Affero General Public License for more details.
16
+
17
+ # Modified by OpenC3, Inc.
18
+ # All changes Copyright 2022, OpenC3, Inc.
19
+ # All Rights Reserved
20
+
21
+ # This file provides a simple ruby sloc counter.
22
+ # Blank lines and comment lines are ignored. All other
23
+ # lines count as one line.
24
+
25
+ require 'ostruct'
26
+ require 'optparse'
27
+
28
+ options = OpenStruct.new
29
+ options.filename = nil
30
+ options.sort_column = nil
31
+
32
+ opts = OptionParser.new do |opts|
33
+ opts.banner = "Usage: rubysloc"
34
+ opts.separator ""
35
+ opts.separator "Recursively calculate SLOC for all ruby files (*.rb) sorted by filename"
36
+ opts.separator ""
37
+ opts.on("-h", "--help", "Show this message") do
38
+ puts opts
39
+ exit
40
+ end
41
+ opts.on("-i DIRECTORY/FILENAME", "--input DIRECTORY/FILENAME",
42
+ "Parse only the specified directory/filename (relative or absolute path)") do |arg|
43
+ options.filename = arg
44
+ end
45
+ opts.on("-s SORT", "--sort SORT", "Sort by the specified column. Must be one of LINES, COMMENTS, SLOC, or RATIO.") do |arg|
46
+ case arg
47
+ when 'LINES'
48
+ options.sort_column = 1
49
+ when 'COMMENTS'
50
+ options.sort_column = 2
51
+ when 'SLOC'
52
+ options.sort_column = 3
53
+ when 'RATIO'
54
+ options.sort_column = 4
55
+ else
56
+ puts opts
57
+ exit
58
+ end
59
+ end
60
+ end
61
+
62
+ begin
63
+ opts.parse!(ARGV)
64
+ rescue => err
65
+ puts err
66
+ puts opts
67
+ exit
68
+ end
69
+
70
+ files = []
71
+ if options.filename
72
+ options.filename = File.join(Dir.pwd, options.filename) unless File.exist?(options.filename)
73
+ if File.exist?(options.filename)
74
+ if File.directory?(options.filename)
75
+ # Dir only works with unix paths so swap backslashes
76
+ files = Dir[File.join(options.filename.gsub('\\', '/'), '**', '*.rb')]
77
+ else
78
+ files << options.filename
79
+ end
80
+ else
81
+ puts "File #{options.filename} not found."
82
+ puts opts
83
+ exit
84
+ end
85
+ else
86
+ files = Dir['**/*.rb']
87
+ end
88
+
89
+ # Build results over all found ruby files
90
+ longest_path = 1
91
+ results = []
92
+ files.each do |full_filename|
93
+ filename = File.basename(full_filename)
94
+ File.open(full_filename, 'r') do |file|
95
+ lines = 0
96
+ slocs = 0
97
+ comments = 0
98
+ file.each_line do |line|
99
+ lines += 1
100
+ split_line = line.split
101
+ if split_line[0].nil?
102
+ # Blank Line - Do Nothing
103
+ elsif split_line[0].to_s[0..0] == '#'
104
+ comments += 1
105
+ else
106
+ slocs += 1
107
+ end
108
+ end
109
+ results << [full_filename, lines, comments, slocs, comments.to_f / slocs.to_f]
110
+ longest_path = full_filename.length if full_filename.length > longest_path
111
+ end
112
+ end
113
+
114
+ results.sort_by! { |col| col[options.sort_column].finite? ? col[options.sort_column] : -1 } if options.sort_column
115
+
116
+ # Print results to STDOUT
117
+ total_files = 0
118
+ total_lines = 0
119
+ total_comments = 0
120
+ total_slocs = 0
121
+ total_ratio = 0
122
+
123
+ puts sprintf("|-%-#{longest_path}s-|----------|----------|----------|--------|", "-" * longest_path)
124
+ puts sprintf("| %-#{longest_path}s | Lines | Comments | SLOCs | Ratio |", "Filename")
125
+ puts sprintf("|-%-#{longest_path}s-|----------|----------|----------|--------|", "-" * longest_path)
126
+ results.each do |filename, lines, comments, slocs, ratio|
127
+ # filename = filename[0..32] if filename.length > 33
128
+ puts sprintf("| %-#{longest_path}s | %8d | %8d | %8d | %6.2f |",
129
+ filename, lines, comments, slocs, ratio)
130
+ total_files += 1
131
+ total_lines += lines
132
+ total_comments += comments
133
+ total_slocs += slocs
134
+ end
135
+ total_ratio = total_comments.to_f / total_slocs.to_f if total_slocs != 0
136
+ puts sprintf("|-%-#{longest_path}s-|----------|----------|----------|--------|", "-" * longest_path)
137
+ puts sprintf("| %-#{longest_path}s | %8d | %8d | %8d | %6.2f |",
138
+ "Totals - #{total_files} Files", total_lines, total_comments, total_slocs, total_ratio)
139
+ puts sprintf("|-%-#{longest_path}s-|----------|----------|----------|--------|", "-" * longest_path)
@@ -0,0 +1,23 @@
1
+ ---
2
+ - name: Item Bit Size
3
+ required: true
4
+ description: Bit size of each array item
5
+ values: \d+
6
+ - name: Item Data Type
7
+ required: true
8
+ description: Data Type of each array item
9
+ values: <%= %w(INT UINT FLOAT STRING BLOCK DERIVED) %>
10
+ - name: Array Bit Size
11
+ required: true
12
+ description: Total Bit Size of the Array. Zero or Negative values may be used
13
+ to indicate the array fills the packet up to the offset from the end of the
14
+ packet specified by this value.
15
+ values: '[-]?\d+'
16
+ - name: Description
17
+ required: false
18
+ description: Description which must be enclosed with quotes
19
+ values: "['\"].*['\"]"
20
+ - name: Endianness
21
+ required: false
22
+ description: Indicates if the data is to be sent in Big Endian or Little Endian format
23
+ values: <%= %w(BIG_ENDIAN LITTLE_ENDIAN) %>