openc3 5.14.2 → 5.15.1

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.

Potentially problematic release.


This version of openc3 might be problematic. Click here for more details.

Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/bin/openc3cli +1 -1
  3. data/data/config/_id_items.yaml +2 -3
  4. data/data/config/telemetry_modifiers.yaml +0 -1
  5. data/lib/openc3/accessors/accessor.rb +3 -3
  6. data/lib/openc3/accessors/http_accessor.rb +1 -1
  7. data/lib/openc3/api/cmd_api.rb +50 -7
  8. data/lib/openc3/api/tlm_api.rb +16 -5
  9. data/lib/openc3/logs/buffered_packet_log_writer.rb +5 -0
  10. data/lib/openc3/logs/packet_log_reader.rb +8 -9
  11. data/lib/openc3/microservices/interface_microservice.rb +29 -18
  12. data/lib/openc3/microservices/trigger_group_microservice.rb +9 -9
  13. data/lib/openc3/models/auth_model.rb +5 -7
  14. data/lib/openc3/models/cvt_model.rb +9 -4
  15. data/lib/openc3/models/gem_model.rb +7 -5
  16. data/lib/openc3/models/metric_model.rb +8 -0
  17. data/lib/openc3/models/model.rb +21 -6
  18. data/lib/openc3/models/plugin_model.rb +8 -2
  19. data/lib/openc3/models/python_package_model.rb +3 -0
  20. data/lib/openc3/models/scope_model.rb +2 -2
  21. data/lib/openc3/models/target_model.rb +21 -28
  22. data/lib/openc3/models/tool_model.rb +2 -2
  23. data/lib/openc3/packets/json_packet.rb +5 -3
  24. data/lib/openc3/script/commands.rb +2 -2
  25. data/lib/openc3/script/storage.rb +28 -12
  26. data/lib/openc3/script/suite_results.rb +9 -9
  27. data/lib/openc3/system/system.rb +4 -5
  28. data/lib/openc3/top_level.rb +32 -23
  29. data/lib/openc3/topics/command_decom_topic.rb +2 -1
  30. data/lib/openc3/topics/command_topic.rb +2 -1
  31. data/lib/openc3/topics/telemetry_topic.rb +7 -2
  32. data/lib/openc3/utilities/authorization.rb +1 -1
  33. data/lib/openc3/utilities/aws_bucket.rb +21 -15
  34. data/lib/openc3/utilities/bucket.rb +1 -1
  35. data/lib/openc3/utilities/logger.rb +3 -3
  36. data/lib/openc3/utilities/process_manager.rb +15 -9
  37. data/lib/openc3/utilities/store_autoload.rb +33 -2
  38. data/lib/openc3/utilities/store_queued.rb +23 -24
  39. data/lib/openc3/version.rb +6 -6
  40. data/templates/tool_angular/package.json +2 -2
  41. data/templates/tool_svelte/package.json +1 -1
  42. data/templates/tool_vue/package.json +2 -2
  43. data/templates/widget/package.json +2 -2
  44. metadata +16 -7
  45. data/templates/tool_angular/yarn.lock +0 -8155
  46. data/templates/tool_react/yarn.lock +0 -7201
  47. data/templates/tool_svelte/yarn.lock +0 -5519
  48. data/templates/tool_vue/yarn.lock +0 -9455
  49. data/templates/widget/yarn.lock +0 -9338
@@ -21,6 +21,7 @@
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3/utilities/store'
24
+ require 'openc3/utilities/store_queued'
24
25
  require 'openc3/config/config_parser'
25
26
 
26
27
  module OpenC3
@@ -34,6 +35,10 @@ module OpenC3
34
35
  Store
35
36
  end
36
37
 
38
+ def self.store_queued
39
+ StoreQueued
40
+ end
41
+
37
42
  # NOTE: The following three methods must be reimplemented by Model subclasses
38
43
  # without primary_key to support other class methods.
39
44
 
@@ -75,10 +80,10 @@ module OpenC3
75
80
  end
76
81
 
77
82
  # Sets (updates) the redis hash of this model
78
- def self.set(json, scope:)
83
+ def self.set(json, scope:, queued: false)
79
84
  json[:scope] = scope
80
85
  json.transform_keys!(&:to_sym)
81
- self.new(**json).create(force: true)
86
+ self.new(**json).create(force: true, queued: queued)
82
87
  end
83
88
 
84
89
  # @return [Model] Model generated from the passed JSON
@@ -134,7 +139,7 @@ module OpenC3
134
139
 
135
140
  # Update the Redis hash at primary_key and set the field "name"
136
141
  # to the JSON generated via calling as_json
137
- def create(update: false, force: false)
142
+ def create(update: false, force: false, queued: false)
138
143
  unless force
139
144
  existing = self.class.store.hget(@primary_key, @name)
140
145
  if existing
@@ -144,12 +149,18 @@ module OpenC3
144
149
  end
145
150
  end
146
151
  @updated_at = Time.now.to_nsec_from_epoch
147
- self.class.store.hset(@primary_key, @name, JSON.generate(self.as_json(:allow_nan => true), :allow_nan => true))
152
+
153
+ if queued
154
+ write_store = self.class.store_queued
155
+ else
156
+ write_store = self.class.store
157
+ end
158
+ write_store.hset(@primary_key, @name, JSON.generate(self.as_json(:allow_nan => true), :allow_nan => true))
148
159
  end
149
160
 
150
161
  # Alias for create(update: true)
151
- def update
152
- create(update: true)
162
+ def update(force: false, queued: false)
163
+ create(update: true, force: force, queued: queued)
153
164
  end
154
165
 
155
166
  # Deploy the model into the OpenC3 system. Subclasses must implement this
@@ -206,5 +217,9 @@ module OpenC3
206
217
  def self.store
207
218
  EphemeralStore
208
219
  end
220
+
221
+ def self.store_queued
222
+ EphemeralStoreQueued
223
+ end
209
224
  end
210
225
  end
@@ -183,12 +183,18 @@ module OpenC3
183
183
  if File.exist?(File.join(gem_path, 'requirements.txt'))
184
184
  begin
185
185
  pypi_url = get_setting('pypi_url', scope: scope)
186
+ if pypi_url
187
+ pypi_url += '/simple'
188
+ end
186
189
  rescue => e
187
190
  Logger.error("Failed to retrieve pypi_url: #{e.formatted}")
188
191
  ensure
189
192
  if pypi_url.nil?
190
193
  # If Redis isn't running try the ENV, then simply pypi.org/simple
191
194
  pypi_url = ENV['PYPI_URL']
195
+ if pypi_url
196
+ pypi_url += '/simple'
197
+ end
192
198
  pypi_url ||= 'https://pypi.org/simple'
193
199
  end
194
200
  end
@@ -288,9 +294,9 @@ module OpenC3
288
294
  @needs_dependencies = ConfigParser.handle_true_false(needs_dependencies)
289
295
  end
290
296
 
291
- def create(update: false, force: false)
297
+ def create(update: false, force: false, queued: false)
292
298
  @name = @name + "__#{Time.now.utc.strftime("%Y%m%d%H%M%S")}" if not update and not @name.index("__")
293
- super(update: update, force: force)
299
+ super(update: update, force: force, queued: queued)
294
300
  end
295
301
 
296
302
  def as_json(*a)
@@ -74,6 +74,9 @@ module OpenC3
74
74
  rescue
75
75
  # If Redis isn't running try the ENV, then simply pypi.org/simple
76
76
  pypi_url = ENV['PYPI_URL']
77
+ if pypi_url
78
+ pypi_url += '/simple'
79
+ end
77
80
  pypi_url ||= 'https://pypi.org/simple'
78
81
  end
79
82
  Logger.info "Installing python package: #{name_or_path}"
@@ -95,11 +95,11 @@ module OpenC3
95
95
  @children = []
96
96
  end
97
97
 
98
- def create(update: false, force: false)
98
+ def create(update: false, force: false, queued: false)
99
99
  # Ensure there are no "." in the scope name - prevents gems accidently becoming scope names
100
100
  raise "Invalid scope name: #{@name}" if @name !~ /^[a-zA-Z0-9_-]+$/
101
101
  @name = @name.upcase
102
- super(update: update, force: force)
102
+ super(update: update, force: force, queued: queued)
103
103
  end
104
104
 
105
105
  def destroy
@@ -97,7 +97,7 @@ module OpenC3
97
97
  # All targets with indication of modified targets
98
98
  def self.all_modified(scope:)
99
99
  targets = self.all(scope: scope)
100
- targets.each { |target_name, target| target['modified'] = false }
100
+ targets.each { |_target_name, target| target['modified'] = false }
101
101
 
102
102
  if ENV['OPENC3_LOCAL_MODE']
103
103
  modified_targets = OpenC3::LocalMode.modified_targets(scope: scope)
@@ -191,13 +191,6 @@ module OpenC3
191
191
  return result
192
192
  end
193
193
 
194
- # @return [Array] Array of all the packet names
195
- def self.packet_names(target_name, type: :TLM, scope:)
196
- raise "Unknown type #{type} for #{target_name}" unless VALID_TYPES.include?(type)
197
- # If the key doesn't exist or if there are no packets we return empty array
198
- Store.hkeys("#{scope}__openc3#{type.to_s.downcase}__#{target_name}").sort
199
- end
200
-
201
194
  # @return [Hash] Packet hash or raises an exception
202
195
  def self.packet(target_name, packet_name, type: :TLM, scope:)
203
196
  raise "Unknown type #{type} for #{target_name} #{packet_name}" unless VALID_TYPES.include?(type)
@@ -216,7 +209,7 @@ module OpenC3
216
209
 
217
210
  result = []
218
211
  packets = Store.hgetall("#{scope}__openc3#{type.to_s.downcase}__#{target_name}")
219
- packets.sort.each do |packet_name, packet_json|
212
+ packets.sort.each do |_packet_name, packet_json|
220
213
  result << JSON.parse(packet_json, :allow_nan => true, :create_additions => true)
221
214
  end
222
215
  result
@@ -232,9 +225,9 @@ module OpenC3
232
225
 
233
226
  begin
234
227
  Store.hset("#{scope}__openc3#{type.to_s.downcase}__#{target_name}", packet_name, JSON.generate(packet.as_json(:allow_nan => true)))
235
- rescue JSON::GeneratorError => err
228
+ rescue JSON::GeneratorError => e
236
229
  Logger.error("Invalid text present in #{target_name} #{packet_name} #{type.to_s.downcase} packet")
237
- raise err
230
+ raise e
238
231
  end
239
232
  end
240
233
 
@@ -403,7 +396,7 @@ module OpenC3
403
396
  @children = []
404
397
  end
405
398
 
406
- def as_json(*a)
399
+ def as_json(*_a)
407
400
  {
408
401
  'name' => @name,
409
402
  'folder_name' => @folder_name,
@@ -586,13 +579,13 @@ module OpenC3
586
579
  end
587
580
  end
588
581
  end
589
- rescue => error
582
+ rescue => e
590
583
  # ERB error parsing a screen is just a logger error because life can go on
591
584
  # With cmd/tlm or scripts this is a serious error and we raise
592
585
  if (filename.include?('/screens/'))
593
- Logger.error("ERB error parsing #{key} due to #{error.message}")
586
+ Logger.error("ERB error parsing #{key} due to #{e.message}")
594
587
  else
595
- raise "ERB error parsing #{key} due to #{error.message}"
588
+ raise "ERB error parsing #{key} due to #{e.message}"
596
589
  end
597
590
  end
598
591
  local_path = File.join(temp_dir, @name, target_folder_path)
@@ -667,8 +660,8 @@ module OpenC3
667
660
  @@item_map_cache[@name] = nil
668
661
 
669
662
  ConfigTopic.write({ kind: 'deleted', type: 'target', name: @name, plugin: @plugin }, scope: @scope)
670
- rescue Exception => error
671
- Logger.error("Error undeploying target model #{@name} in scope #{@scope} due to #{error}")
663
+ rescue Exception => e
664
+ Logger.error("Error undeploying target model #{@name} in scope #{@scope} due to #{e}")
672
665
  end
673
666
 
674
667
  ##################################################
@@ -702,8 +695,8 @@ module OpenC3
702
695
  return ERB.new(data.force_encoding("UTF-8").comment_erb(), trim_mode: "-").result(b)
703
696
  end
704
697
  end
705
- rescue => error
706
- raise "ERB error parsing: #{path}: #{error.formatted}"
698
+ rescue => e
699
+ raise "ERB error parsing: #{path}: #{e.formatted}"
707
700
  end
708
701
  end
709
702
 
@@ -763,9 +756,9 @@ module OpenC3
763
756
  Logger.info "Configuring tlm packet: #{target_name} #{packet_name}"
764
757
  begin
765
758
  Store.hset("#{@scope}__openc3tlm__#{target_name}", packet_name, JSON.generate(packet.as_json(:allow_nan => true)))
766
- rescue JSON::GeneratorError => err
759
+ rescue JSON::GeneratorError => e
767
760
  Logger.error("Invalid text present in #{target_name} #{packet_name} tlm packet")
768
- raise err
761
+ raise e
769
762
  end
770
763
  json_hash = Hash.new
771
764
  packet.sorted_items.each do |item|
@@ -783,9 +776,9 @@ module OpenC3
783
776
  Logger.info "Configuring cmd packet: #{target_name} #{packet_name}"
784
777
  begin
785
778
  Store.hset("#{@scope}__openc3cmd__#{target_name}", packet_name, JSON.generate(packet.as_json(:allow_nan => true)))
786
- rescue JSON::GeneratorError => err
779
+ rescue JSON::GeneratorError => e
787
780
  Logger.error("Invalid text present in #{target_name} #{packet_name} cmd packet")
788
- raise err
781
+ raise e
789
782
  end
790
783
  end
791
784
  end
@@ -795,9 +788,9 @@ module OpenC3
795
788
  system.limits.groups.each do |group, items|
796
789
  begin
797
790
  Store.hset("#{@scope}__limits_groups", group, JSON.generate(items))
798
- rescue JSON::GeneratorError => err
791
+ rescue JSON::GeneratorError => e
799
792
  Logger.error("Invalid text present in #{group} limits group")
800
- raise err
793
+ raise e
801
794
  end
802
795
  end
803
796
  end
@@ -1107,7 +1100,7 @@ module OpenC3
1107
1100
 
1108
1101
  # Figure out if there are individual packets assigned to this microservice
1109
1102
  target_microservices.sort! {|a, b| a.length <=> b.length}
1110
- target_microservices.each_with_index do |packet_names, index|
1103
+ target_microservices.each_with_index do |packet_names, _index|
1111
1104
  topics = []
1112
1105
  packet_names.each do |packet_name|
1113
1106
  topics << "#{topic_prefix}__#{packet_name}"
@@ -1146,7 +1139,7 @@ module OpenC3
1146
1139
  packet_topic_list = []
1147
1140
  decom_topic_list = []
1148
1141
  begin
1149
- system.commands.packets(@name).each do |packet_name, packet|
1142
+ system.commands.packets(@name).each do |packet_name, _packet|
1150
1143
  command_topic_list << "#{@scope}__COMMAND__{#{@name}}__#{packet_name}"
1151
1144
  decom_command_topic_list << "#{@scope}__DECOMCMD__{#{@name}}__#{packet_name}"
1152
1145
  end
@@ -1154,7 +1147,7 @@ module OpenC3
1154
1147
  # No command packets for this target
1155
1148
  end
1156
1149
  begin
1157
- system.telemetry.packets(@name).each do |packet_name, packet|
1150
+ system.telemetry.packets(@name).each do |packet_name, _packet|
1158
1151
  packet_topic_list << "#{@scope}__TELEMETRY__{#{@name}}__#{packet_name}"
1159
1152
  decom_topic_list << "#{@scope}__DECOM__{#{@name}}__#{packet_name}"
1160
1153
  end
@@ -157,7 +157,7 @@ module OpenC3
157
157
  @disable_erb = disable_erb
158
158
  end
159
159
 
160
- def create(update: false, force: false)
160
+ def create(update: false, force: false, queued: false)
161
161
  tools = self.class.all(scope: @scope)
162
162
 
163
163
  # Make sure a tool with this folder_name doesn't already exist
@@ -181,7 +181,7 @@ module OpenC3
181
181
  end
182
182
  end
183
183
 
184
- super(update: update, force: force)
184
+ super(update: update, force: force, queued: queued)
185
185
  end
186
186
 
187
187
  def as_json(*a)
@@ -67,7 +67,9 @@ module OpenC3
67
67
  def read(name, value_type = :CONVERTED, reduced_type = nil)
68
68
  value = nil
69
69
  array_index = nil
70
- if name[-1] == ']'
70
+ # Check for array index to handle array items but also make sure there
71
+ # isn't a REAL item that has brackets in the name
72
+ if name[-1] == ']' and !@json_hash.include?(name)
71
73
  open_bracket_index = name.index('[')
72
74
  if open_bracket_index
73
75
  array_index = name[(open_bracket_index + 1)..-2].to_i
@@ -212,12 +214,12 @@ module OpenC3
212
214
  else
213
215
  postfix = nil if value_type == :RAW
214
216
  end
215
- @json_hash.each do |key, value|
217
+ @json_hash.each do |key, _value|
216
218
  key_split = key.split("__")
217
219
  result[key_split[0]] = true if key_split[1] == postfix
218
220
  end
219
221
  else
220
- @json_hash.each { |key, value| result[key.split("__")[0]] = true }
222
+ @json_hash.each { |key, _value| result[key.split("__")[0]] = true }
221
223
  end
222
224
  return result.keys
223
225
  end
@@ -14,7 +14,7 @@
14
14
  # GNU Affero General Public License for more details.
15
15
 
16
16
  # Modified by OpenC3, Inc.
17
- # All changes Copyright 2022, OpenC3, Inc.
17
+ # All changes Copyright 2024, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
20
  # This file may also be used under the terms of a commercial license
@@ -96,7 +96,7 @@ module OpenC3
96
96
 
97
97
  # Get the command and validate the parameters
98
98
  command = $api_server.get_cmd(target_name, cmd_name, scope: scope)
99
- cmd_params.each do |param_name, param_value|
99
+ cmd_params.each do |param_name, _param_value|
100
100
  param = command['items'].find { |item| item['name'] == param_name }
101
101
  unless param
102
102
  raise "Packet item '#{target_name} #{cmd_name} #{param_name}' does not exist"
@@ -43,8 +43,8 @@ module OpenC3
43
43
  if response.nil? || response.status != 200
44
44
  raise "Failed to delete #{delete_path}"
45
45
  end
46
- rescue => error
47
- raise "Failed deleting #{path} due to #{error.message}"
46
+ rescue => e
47
+ raise "Failed deleting #{path} due to #{e.message}"
48
48
  end
49
49
  nil
50
50
  end
@@ -84,8 +84,8 @@ module OpenC3
84
84
  end
85
85
  end
86
86
  end
87
- rescue => error
88
- raise "Failed to write #{upload_path} due to #{error.message}"
87
+ rescue => e
88
+ raise "Failed to write #{upload_path} due to #{e.message}"
89
89
  end
90
90
  nil
91
91
  end
@@ -115,19 +115,33 @@ module OpenC3
115
115
  end
116
116
 
117
117
  return _get_storage_file("#{part}/#{path}", scope: scope)
118
- rescue => error
118
+ rescue => e
119
119
  if part == "targets_modified"
120
120
  part = "targets"
121
121
  redo
122
122
  else
123
- raise error
123
+ raise e
124
124
  end
125
125
  end
126
126
  break
127
127
  end
128
128
  end
129
129
 
130
- # download_file(path_or_file) is implemented by running_script to download a file
130
+ def get_download_url(path, scope: $openc3_scope)
131
+ targets = "targets_modified" # First try targets_modified
132
+ response = $api_server.request('get', "/openc3-api/storage/exists/#{scope}/#{targets}/#{path}", query: { bucket: 'OPENC3_CONFIG_BUCKET' }, scope: scope)
133
+ if response.status != 200
134
+ targets = "targets" # Next try targets
135
+ response = $api_server.request('get', "/openc3-api/storage/exists/#{scope}/#{targets}/#{path}", query: { bucket: 'OPENC3_CONFIG_BUCKET' }, scope: scope)
136
+ if response.status != 200
137
+ raise "File not found: #{path} in scope: #{scope}"
138
+ end
139
+ end
140
+ endpoint = "/openc3-api/storage/download/#{scope}/#{targets}/#{path}"
141
+ # external must be true because we're using this URL from the frontend
142
+ result = _get_presigned_request(endpoint, external: true, scope: scope)
143
+ return result['url']
144
+ end
131
145
 
132
146
  # These are helper methods ... should not be used directly
133
147
 
@@ -161,7 +175,9 @@ module OpenC3
161
175
  if $openc3_in_cluster
162
176
  case ENV['OPENC3_CLOUD']
163
177
  when 'local'
164
- URI.parse("http://openc3-minio:9000" + url)
178
+ bucket_url = ENV["OPENC3_BUCKET_URL"] || "openc3-minio:9000"
179
+ # TODO: Bucket schema for http vs https
180
+ URI.parse("http://#{bucket_url}#{url}")
165
181
  when 'aws'
166
182
  URI.parse("https://s3.#{ENV['AWS_REGION']}.amazonaws.com" + url)
167
183
  when 'gcp'
@@ -175,11 +191,11 @@ module OpenC3
175
191
  end
176
192
  end
177
193
 
178
- def _get_presigned_request(endpoint, scope: $openc3_scope)
179
- if $openc3_in_cluster
180
- response = $api_server.request('get', endpoint, query: { bucket: 'OPENC3_CONFIG_BUCKET', internal: true }, scope: scope)
181
- else
194
+ def _get_presigned_request(endpoint, external: nil, scope: $openc3_scope)
195
+ if external or !$openc3_in_cluster
182
196
  response = $api_server.request('get', endpoint, query: { bucket: 'OPENC3_CONFIG_BUCKET' }, scope: scope)
197
+ else
198
+ response = $api_server.request('get', endpoint, query: { bucket: 'OPENC3_CONFIG_BUCKET', internal: true }, scope: scope)
183
199
  end
184
200
  if response.nil? || response.status != 201
185
201
  raise "Failed to get presigned URL for #{endpoint}"
@@ -14,7 +14,7 @@
14
14
  # GNU Affero General Public License for more details.
15
15
 
16
16
  # Modified by OpenC3, Inc.
17
- # All changes Copyright 2022, OpenC3, Inc.
17
+ # All changes Copyright 2024, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
20
  # This file may also be used under the terms of a commercial license
@@ -22,7 +22,7 @@
22
22
 
23
23
  module OpenC3
24
24
  class SuiteResults
25
- attr_accessor :metadata
25
+ attr_accessor :metadata, :context
26
26
 
27
27
  def initialize
28
28
  @report = nil
@@ -41,13 +41,13 @@ module OpenC3
41
41
  @report = []
42
42
 
43
43
  if test_case
44
- # Executing a single test case
44
+ # Executing a script
45
45
  @context = "#{test_suite_class.name}:#{test_class.name}:#{test_case} #{test_type}"
46
46
  elsif test_class
47
- # Executing an entire test
47
+ # Executing a group
48
48
  @context = "#{test_suite_class.name}:#{test_class.name} #{test_type}"
49
49
  else
50
- # Executing a test suite
50
+ # Executing a suite
51
51
  @context = "#{test_suite_class.name} #{test_type}"
52
52
  end
53
53
 
@@ -75,7 +75,7 @@ module OpenC3
75
75
  line.chomp!
76
76
  line = line.inspect.remove_quotes
77
77
  end
78
- @report << ' ' + line.strip
78
+ @report << (' ' + line.strip)
79
79
  end
80
80
  end
81
81
  if result.exceptions
@@ -90,7 +90,7 @@ module OpenC3
90
90
  line.chomp!
91
91
  line = line.inspect.remove_quotes
92
92
  end
93
- @report << ' ' + line.strip
93
+ @report << (' ' + line.strip)
94
94
  end
95
95
  @report << '' if index != (result.exceptions.length - 1)
96
96
  end
@@ -172,11 +172,11 @@ module OpenC3
172
172
  end
173
173
 
174
174
  def write(string)
175
- @report << Time.now.sys.formatted + ': ' + string
175
+ @report << (Time.now.sys.formatted + ': ' + string)
176
176
  end
177
177
 
178
178
  def puts(string)
179
- @report << Time.now.sys.formatted + ': ' + string
179
+ @report << (Time.now.sys.formatted + ': ' + string)
180
180
  end
181
181
 
182
182
  # def collect_metadata(parent = nil)
@@ -14,7 +14,7 @@
14
14
  # GNU Affero General Public License for more details.
15
15
 
16
16
  # Modified by OpenC3, Inc.
17
- # All changes Copyright 2022, OpenC3, Inc.
17
+ # All changes Copyright 2024, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
20
  # This file may also be used under the terms of a commercial license
@@ -31,7 +31,6 @@ require 'openc3/system/target'
31
31
  require 'openc3/utilities/bucket'
32
32
  require 'openc3/utilities/zip'
33
33
  require 'openc3/topics/limits_event_topic'
34
- require 'thread'
35
34
  require 'fileutils'
36
35
 
37
36
  module OpenC3
@@ -109,7 +108,7 @@ module OpenC3
109
108
  # target.txt must be configured to either use all files in cmd_tlm folder (default)
110
109
  # or have a predetermined empty file like dynamic_tlm.txt
111
110
  bucket_path = "#{scope}/targets_modified/#{target_name}/cmd_tlm"
112
- dirs, files = bucket.list_files(bucket: ENV['OPENC3_CONFIG_BUCKET'], path: bucket_path)
111
+ _, files = bucket.list_files(bucket: ENV['OPENC3_CONFIG_BUCKET'], path: bucket_path)
113
112
  files.each do |file|
114
113
  bucket_key = File.join(bucket_path, file['name'])
115
114
  local_path = "#{base_dir}/targets/#{target_name}/cmd_tlm/#{file['name']}"
@@ -180,8 +179,8 @@ module OpenC3
180
179
  errors = [] # Store all errors processing the cmd_tlm files
181
180
  target.cmd_tlm_files.each do |cmd_tlm_file|
182
181
  @packet_config.process_file(cmd_tlm_file, target.name, target.language)
183
- rescue Exception => error
184
- errors << "Error processing #{cmd_tlm_file}:\n#{error.message}"
182
+ rescue Exception => e
183
+ errors << "Error processing #{cmd_tlm_file}:\n#{e.message}"
185
184
  end
186
185
  unless errors.empty?
187
186
  raise errors.join("\n")