cosmos 4.0.3-java → 4.1.0-java
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.
- checksums.yaml +4 -4
- data/.travis.yml +5 -5
- data/Manifest.txt +11 -1
- data/README.md +3 -2
- data/Rakefile +18 -4
- data/appveyor.yml +19 -0
- data/cosmos.gemspec +12 -3
- data/data/config/cmd_tlm_server.yaml +3 -0
- data/data/crc.txt +63 -60
- data/demo/config/targets/INST/cmd_tlm_server.txt +1 -0
- data/demo/config/targets/INST/cmd_tlm_server2.txt +7 -0
- data/demo/config/tools/cmd_sequence/cmd_sequence.txt +2 -0
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +8 -12
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +7 -9
- data/demo/lib/cmd_sequence_exporter.rb +52 -0
- data/demo/lib/example_background_task.rb +1 -0
- data/demo/procedures/replay_test.rb +32 -0
- data/ext/cosmos/ext/structure/structure.c +39 -3
- data/install/config/tools/cmd_tlm_server/cmd_tlm_server.txt +1 -0
- data/install/config/tools/launcher/launcher.txt +2 -0
- data/lib/cosmos/config/config_parser.rb +2 -0
- data/lib/cosmos/core_ext/io.rb +89 -60
- data/lib/cosmos/gui/qt.rb +5 -8
- data/lib/cosmos/gui/qt_tool.rb +8 -8
- data/lib/cosmos/gui/text/ruby_editor.rb +12 -12
- data/lib/cosmos/gui/utilities/script_module_gui.rb +9 -9
- data/lib/cosmos/gui/widgets/realtime_button_bar.rb +18 -17
- data/lib/cosmos/interfaces/protocols/fixed_protocol.rb +2 -2
- data/lib/cosmos/interfaces/protocols/template_protocol.rb +3 -0
- data/lib/cosmos/interfaces/udp_interface.rb +27 -14
- data/lib/cosmos/io/buffered_file.rb +0 -1
- data/lib/cosmos/io/json_drb.rb +134 -214
- data/lib/cosmos/io/json_drb_object.rb +22 -61
- data/lib/cosmos/io/json_drb_rack.rb +79 -0
- data/lib/cosmos/io/json_rpc.rb +27 -0
- data/lib/cosmos/io/udp_sockets.rb +102 -58
- data/lib/cosmos/packets/commands.rb +1 -1
- data/lib/cosmos/packets/structure.rb +1 -1
- data/lib/cosmos/packets/structure_item.rb +37 -5
- data/lib/cosmos/script/cmd_tlm_server.rb +76 -2
- data/lib/cosmos/script/replay.rb +60 -0
- data/lib/cosmos/script/script.rb +20 -2
- data/lib/cosmos/script/scripting.rb +9 -9
- data/lib/cosmos/script/tools.rb +14 -0
- data/lib/cosmos/system/system.rb +185 -92
- data/lib/cosmos/system/target.rb +1 -1
- data/lib/cosmos/tools/cmd_sequence/cmd_sequence.rb +44 -4
- data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +4 -0
- data/lib/cosmos/tools/cmd_sequence/sequence_list.rb +7 -0
- data/lib/cosmos/tools/cmd_tlm_server/api.rb +347 -20
- data/lib/cosmos/tools/cmd_tlm_server/background_tasks.rb +3 -0
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +329 -111
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +13 -0
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +261 -95
- data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +46 -35
- data/lib/cosmos/tools/cmd_tlm_server/gui/logging_tab.rb +18 -8
- data/lib/cosmos/tools/cmd_tlm_server/gui/packets_tab.rb +39 -28
- data/lib/cosmos/tools/cmd_tlm_server/gui/replay_tab.rb +242 -0
- data/lib/cosmos/tools/cmd_tlm_server/gui/status_tab.rb +24 -8
- data/lib/cosmos/tools/cmd_tlm_server/gui/targets_tab.rb +18 -6
- data/lib/cosmos/tools/cmd_tlm_server/limits_groups_background_task.rb +5 -4
- data/lib/cosmos/tools/cmd_tlm_server/replay_backend.rb +375 -0
- data/lib/cosmos/tools/cmd_tlm_server/routers.rb +10 -2
- data/lib/cosmos/tools/data_viewer/data_viewer.rb +40 -5
- data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +18 -20
- data/lib/cosmos/tools/launcher/launcher_config.rb +5 -16
- data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +65 -39
- data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +19 -0
- data/lib/cosmos/tools/replay/replay.rb +5 -505
- data/lib/cosmos/tools/script_runner/script_audit.rb +1 -0
- data/lib/cosmos/tools/script_runner/script_runner.rb +3 -4
- data/lib/cosmos/tools/script_runner/script_runner_config.rb +3 -4
- data/lib/cosmos/tools/script_runner/script_runner_frame.rb +44 -23
- data/lib/cosmos/tools/test_runner/results_writer.rb +4 -0
- data/lib/cosmos/tools/test_runner/test_runner.rb +0 -3
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +6 -2
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tool.rb +26 -1
- data/lib/cosmos/tools/tlm_viewer/screen.rb +24 -1
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +25 -0
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +24 -14
- data/lib/cosmos/top_level.rb +34 -24
- data/lib/cosmos/utilities/csv.rb +60 -8
- data/lib/cosmos/version.rb +5 -5
- data/spec/config/config_parser_spec.rb +10 -1
- data/spec/core_ext/socket_spec.rb +4 -2
- data/spec/gui/utilities/script_module_gui_spec.rb +102 -0
- data/spec/install/config/data/data.txt +1 -0
- data/spec/install/config/targets/INST/cmd_tlm/inst_cmds.txt +2 -0
- data/spec/interfaces/cmd_tlm_server_interface_spec.rb +1 -2
- data/spec/interfaces/protocols/template_protocol_spec.rb +72 -2
- data/spec/interfaces/serial_interface_spec.rb +1 -1
- data/spec/interfaces/udp_interface_spec.rb +14 -0
- data/spec/io/buffered_file_spec.rb +37 -0
- data/spec/io/json_drb_object_spec.rb +2 -15
- data/spec/io/json_drb_spec.rb +61 -121
- data/spec/io/udp_sockets_spec.rb +42 -2
- data/spec/packet_logs/packet_log_reader_spec.rb +5 -2
- data/spec/packets/binary_accessor_spec.rb +1 -1
- data/spec/packets/packet_item_spec.rb +1 -1
- data/spec/packets/structure_item_spec.rb +5 -6
- data/spec/script/cmd_tlm_server_spec.rb +39 -4
- data/spec/script/commands_disconnect_spec.rb +1 -1
- data/spec/script/commands_spec.rb +2 -1
- data/spec/script/scripting_spec.rb +18 -3
- data/spec/script/telemetry_spec.rb +5 -0
- data/spec/spec_helper.rb +43 -26
- data/spec/streams/tcpip_socket_stream_spec.rb +2 -2
- data/spec/system/system_spec.rb +11 -9
- data/spec/system/target_spec.rb +3 -0
- data/spec/tools/cmd_tlm_server/api_spec.rb +543 -29
- data/spec/tools/cmd_tlm_server/background_task_spec.rb +2 -2
- data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +31 -75
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +199 -66
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +85 -9
- data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +29 -127
- data/spec/tools/cmd_tlm_server/router_thread_spec.rb +10 -50
- data/spec/tools/launcher/launcher_config_spec.rb +1 -1
- data/spec/tools/table_manager/table_item_spec.rb +1 -1
- data/spec/tools/table_manager/tablemanager_core_spec.rb +4 -4
- data/spec/top_level/top_level_spec.rb +151 -3
- data/spec/utilities/csv_spec.rb +24 -5
- metadata +61 -9
- data/lib/cosmos/tools/replay/replay_server.rb +0 -91
|
@@ -19,7 +19,7 @@ module Cosmos
|
|
|
19
19
|
#
|
|
20
20
|
# This should not be confused with the Api module which implements the JSON
|
|
21
21
|
# API that is used by tools when accessing the Server. The Api module always
|
|
22
|
-
# provides Ruby primatives where the
|
|
22
|
+
# provides Ruby primatives where the PacketConfig class can return actual
|
|
23
23
|
# Packet or PacketItem objects. While there are some overlapping methods between
|
|
24
24
|
# the two, these are separate interfaces into the system.
|
|
25
25
|
class Commands
|
|
@@ -198,7 +198,7 @@ module Cosmos
|
|
|
198
198
|
# to re-sort. We also re-sort if the current item is less than the less
|
|
199
199
|
# item because we are inserting.
|
|
200
200
|
if last_item.bit_offset <= 0 or item.bit_offset <= 0 or item.bit_offset < last_item.bit_offset
|
|
201
|
-
@sorted_items = @sorted_items.sort
|
|
201
|
+
@sorted_items = @sorted_items.sort
|
|
202
202
|
end
|
|
203
203
|
else
|
|
204
204
|
@sorted_items << item
|
|
@@ -17,6 +17,8 @@ module Cosmos
|
|
|
17
17
|
class StructureItem
|
|
18
18
|
include Comparable
|
|
19
19
|
|
|
20
|
+
@@create_index = 0
|
|
21
|
+
|
|
20
22
|
# Valid data types adds :DERIVED to those defined by BinaryAccessor
|
|
21
23
|
DATA_TYPES = BinaryAccessor::DATA_TYPES << :DERIVED
|
|
22
24
|
|
|
@@ -81,6 +83,8 @@ module Cosmos
|
|
|
81
83
|
self.bit_size = bit_size
|
|
82
84
|
self.array_size = array_size
|
|
83
85
|
self.overflow = overflow
|
|
86
|
+
@create_index = @@create_index
|
|
87
|
+
@@create_index += 1
|
|
84
88
|
@structure_item_constructed = true
|
|
85
89
|
verify_overall()
|
|
86
90
|
end
|
|
@@ -190,6 +194,10 @@ module Cosmos
|
|
|
190
194
|
verify_overall() if @structure_item_constructed
|
|
191
195
|
end
|
|
192
196
|
|
|
197
|
+
def create_index
|
|
198
|
+
@create_index.to_i
|
|
199
|
+
end
|
|
200
|
+
|
|
193
201
|
if RUBY_ENGINE != 'ruby' or ENV['COSMOS_NO_EXT']
|
|
194
202
|
# Comparison Operator based on bit_offset. This means that StructureItems
|
|
195
203
|
# with different names or bit sizes are equal if they have the same bit
|
|
@@ -202,9 +210,17 @@ module Cosmos
|
|
|
202
210
|
if (@bit_offset == 0) && (other_bit_offset == 0)
|
|
203
211
|
# Both bit_offsets are 0 so sort by bit_size
|
|
204
212
|
# This allows derived items with bit_size of 0 to be listed first
|
|
205
|
-
# Compare based on bit size
|
|
213
|
+
# Compare based on bit size then create index
|
|
206
214
|
if @bit_size == other_bit_size
|
|
207
|
-
|
|
215
|
+
if @create_index
|
|
216
|
+
if @create_index <= other_item.create_index
|
|
217
|
+
return -1
|
|
218
|
+
else
|
|
219
|
+
return 1
|
|
220
|
+
end
|
|
221
|
+
else
|
|
222
|
+
return 0
|
|
223
|
+
end
|
|
208
224
|
elsif @bit_size < other_bit_size
|
|
209
225
|
return -1
|
|
210
226
|
else
|
|
@@ -216,8 +232,16 @@ module Cosmos
|
|
|
216
232
|
if ((@bit_offset >= 0) && (other_bit_offset >= 0)) || ((@bit_offset < 0) && (other_bit_offset < 0))
|
|
217
233
|
# Both Have Same Sign
|
|
218
234
|
if @bit_offset == other_bit_offset
|
|
219
|
-
|
|
220
|
-
|
|
235
|
+
if @create_index
|
|
236
|
+
if @create_index <= other_item.create_index
|
|
237
|
+
return -1
|
|
238
|
+
else
|
|
239
|
+
return 1
|
|
240
|
+
end
|
|
241
|
+
else
|
|
242
|
+
return 0
|
|
243
|
+
end
|
|
244
|
+
elsif @bit_offset <= other_bit_offset
|
|
221
245
|
return -1
|
|
222
246
|
else
|
|
223
247
|
return 1
|
|
@@ -225,7 +249,15 @@ module Cosmos
|
|
|
225
249
|
else
|
|
226
250
|
# Different Signs
|
|
227
251
|
if @bit_offset == other_bit_offset
|
|
228
|
-
|
|
252
|
+
if @create_index
|
|
253
|
+
if @create_index < other_item.create_index
|
|
254
|
+
return -1
|
|
255
|
+
else
|
|
256
|
+
return 1
|
|
257
|
+
end
|
|
258
|
+
else
|
|
259
|
+
return 0
|
|
260
|
+
end
|
|
229
261
|
elsif @bit_offset < other_bit_offset
|
|
230
262
|
return 1
|
|
231
263
|
else
|
|
@@ -57,14 +57,42 @@ module Cosmos
|
|
|
57
57
|
return $cmd_tlm_server.get_target_info(target_name)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
+
def get_all_target_info
|
|
61
|
+
return $cmd_tlm_server.get_all_target_info
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def get_target_ignored_parameters(target_name)
|
|
65
|
+
return $cmd_tlm_server.get_target_ignored_parameters(target_name)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def get_target_ignored_items(target_name)
|
|
69
|
+
return $cmd_tlm_server.get_target_ignored_items(target_name)
|
|
70
|
+
end
|
|
71
|
+
|
|
60
72
|
def get_interface_info(interface_name)
|
|
61
73
|
return $cmd_tlm_server.get_interface_info(interface_name)
|
|
62
74
|
end
|
|
63
75
|
|
|
76
|
+
def get_all_router_info
|
|
77
|
+
return $cmd_tlm_server.get_all_router_info
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def get_all_interface_info
|
|
81
|
+
return $cmd_tlm_server.get_all_interface_info
|
|
82
|
+
end
|
|
83
|
+
|
|
64
84
|
def get_router_info(router_name)
|
|
65
85
|
return $cmd_tlm_server.get_router_info(router_name)
|
|
66
86
|
end
|
|
67
87
|
|
|
88
|
+
def get_all_cmd_info
|
|
89
|
+
return $cmd_tlm_server.get_all_cmd_info
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def get_all_tlm_info
|
|
93
|
+
return $cmd_tlm_server.get_all_tlm_info
|
|
94
|
+
end
|
|
95
|
+
|
|
68
96
|
def get_cmd_cnt(target_name, command_name)
|
|
69
97
|
return $cmd_tlm_server.get_cmd_cnt(target_name, command_name)
|
|
70
98
|
end
|
|
@@ -73,10 +101,34 @@ module Cosmos
|
|
|
73
101
|
return $cmd_tlm_server.get_tlm_cnt(target_name, packet_name)
|
|
74
102
|
end
|
|
75
103
|
|
|
104
|
+
def get_packet_loggers
|
|
105
|
+
return $cmd_tlm_server.get_packet_loggers
|
|
106
|
+
end
|
|
107
|
+
|
|
76
108
|
def get_packet_logger_info(packet_logger_name)
|
|
77
109
|
return $cmd_tlm_server.get_packet_logger_info(packet_logger_name)
|
|
78
110
|
end
|
|
79
111
|
|
|
112
|
+
def get_all_packet_logger_info
|
|
113
|
+
return $cmd_tlm_server.get_all_packet_logger_info
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def get_background_tasks
|
|
117
|
+
return $cmd_tlm_server.get_background_tasks
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def start_background_task(task_name)
|
|
121
|
+
return $cmd_tlm_server.start_background_task(task_name)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def stop_background_task(task_name)
|
|
125
|
+
return $cmd_tlm_server.stop_background_task(task_name)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def get_server_status
|
|
129
|
+
return $cmd_tlm_server.get_server_status
|
|
130
|
+
end
|
|
131
|
+
|
|
80
132
|
def get_cmd_log_filename(packet_log_writer_name = 'DEFAULT')
|
|
81
133
|
return $cmd_tlm_server.get_cmd_log_filename(packet_log_writer_name)
|
|
82
134
|
end
|
|
@@ -133,6 +185,28 @@ module Cosmos
|
|
|
133
185
|
return $cmd_tlm_server.start_new_server_message_log
|
|
134
186
|
end
|
|
135
187
|
|
|
136
|
-
|
|
188
|
+
def subscribe_server_messages(queue_size = CmdTlmServer::DEFAULT_SERVER_MESSAGES_QUEUE_SIZE)
|
|
189
|
+
return $cmd_tlm_server.subscribe_server_messages(queue_size)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def unsubscribe_server_messages(id)
|
|
193
|
+
return $cmd_tlm_server.unsubscribe_server_messages(id)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def get_server_message(id, non_block = false)
|
|
197
|
+
return $cmd_tlm_server.get_server_message(id, non_block)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def cmd_tlm_reload
|
|
201
|
+
return $cmd_tlm_server.cmd_tlm_reload
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def cmd_tlm_clear_counters
|
|
205
|
+
return $cmd_tlm_server.cmd_tlm_clear_counters
|
|
206
|
+
end
|
|
137
207
|
|
|
138
|
-
|
|
208
|
+
def get_output_logs_filenames(filter = '*tlm.bin')
|
|
209
|
+
return $cmd_tlm_server.get_output_logs_filenames(filter)
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2017 Ball Aerospace & Technologies Corp.
|
|
4
|
+
# All Rights Reserved.
|
|
5
|
+
#
|
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
|
7
|
+
# under the terms of the GNU General Public License
|
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
|
10
|
+
|
|
11
|
+
module Cosmos
|
|
12
|
+
|
|
13
|
+
module Script
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def replay_select_file(filename, packet_log_reader = "DEFAULT")
|
|
17
|
+
$cmd_tlm_server.replay_select_file(filename, packet_log_reader)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def replay_status
|
|
21
|
+
$cmd_tlm_server.replay_status
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def replay_set_playback_delay(delay)
|
|
25
|
+
$cmd_tlm_server.replay_set_playback_delay(delay)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def replay_play
|
|
29
|
+
$cmd_tlm_server.replay_play
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def replay_reverse_play
|
|
33
|
+
$cmd_tlm_server.replay_reverse_play
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def replay_stop
|
|
37
|
+
$cmd_tlm_server.replay_stop
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def replay_step_forward
|
|
41
|
+
$cmd_tlm_server.replay_step_forward
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def replay_step_back
|
|
45
|
+
$cmd_tlm_server.replay_step_back
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def replay_move_start
|
|
49
|
+
$cmd_tlm_server.replay_move_start
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def replay_move_end
|
|
53
|
+
$cmd_tlm_server.replay_move_end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def replay_move_index(index)
|
|
57
|
+
$cmd_tlm_server.replay_move_index(index)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
data/lib/cosmos/script/script.rb
CHANGED
|
@@ -12,6 +12,7 @@ require 'cosmos'
|
|
|
12
12
|
require 'cosmos/io/json_drb_object'
|
|
13
13
|
require 'cosmos/tools/cmd_tlm_server/cmd_tlm_server'
|
|
14
14
|
require 'cosmos/script/cmd_tlm_server'
|
|
15
|
+
require 'cosmos/script/replay'
|
|
15
16
|
require 'cosmos/script/commands'
|
|
16
17
|
require 'cosmos/script/telemetry'
|
|
17
18
|
require 'cosmos/script/limits'
|
|
@@ -20,6 +21,7 @@ require 'cosmos/script/tools'
|
|
|
20
21
|
|
|
21
22
|
$cmd_tlm_server = nil
|
|
22
23
|
$cmd_tlm_disconnect = false
|
|
24
|
+
$cmd_tlm_replay_mode = false
|
|
23
25
|
|
|
24
26
|
module Cosmos
|
|
25
27
|
class CheckError < RuntimeError; end
|
|
@@ -39,6 +41,7 @@ module Cosmos
|
|
|
39
41
|
# Called when this module is mixed in using "include Cosmos::Script"
|
|
40
42
|
def self.included(base)
|
|
41
43
|
$cmd_tlm_disconnect = false
|
|
44
|
+
$cmd_tlm_replay_mode = false
|
|
42
45
|
$cmd_tlm_server = nil
|
|
43
46
|
initialize_script_module()
|
|
44
47
|
end
|
|
@@ -48,8 +51,12 @@ module Cosmos
|
|
|
48
51
|
# Start up a standalone CTS in disconnected mode
|
|
49
52
|
$cmd_tlm_server = CmdTlmServer.new(config_file, false, true)
|
|
50
53
|
else
|
|
51
|
-
# Start a Json connect to the real
|
|
52
|
-
$
|
|
54
|
+
# Start a Json connect to the real server
|
|
55
|
+
if $cmd_tlm_replay_mode
|
|
56
|
+
$cmd_tlm_server = JsonDRbObject.new(System.connect_hosts['REPLAY_API'], System.ports['REPLAY_API'])
|
|
57
|
+
else
|
|
58
|
+
$cmd_tlm_server = JsonDRbObject.new(System.connect_hosts['CTS_API'], System.ports['CTS_API'])
|
|
59
|
+
end
|
|
53
60
|
end
|
|
54
61
|
end
|
|
55
62
|
|
|
@@ -72,5 +79,16 @@ module Cosmos
|
|
|
72
79
|
$cmd_tlm_server.disconnect if $cmd_tlm_server && !$cmd_tlm_disconnect
|
|
73
80
|
end
|
|
74
81
|
|
|
82
|
+
def set_replay_mode(replay_mode)
|
|
83
|
+
if replay_mode != $cmd_tlm_replay_mode
|
|
84
|
+
$cmd_tlm_replay_mode = replay_mode
|
|
85
|
+
initialize_script_module()
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def get_replay_mode
|
|
90
|
+
$cmd_tlm_replay_mode
|
|
91
|
+
end
|
|
92
|
+
|
|
75
93
|
end
|
|
76
94
|
end
|
|
@@ -72,9 +72,9 @@ module Cosmos
|
|
|
72
72
|
prompt_combo_box(string, options)
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
def _file_dialog(message, directory, select_files = true)
|
|
75
|
+
def _file_dialog(message, directory, filter, select_files = true)
|
|
76
76
|
answer = ''
|
|
77
|
-
files = Dir["#{directory}
|
|
77
|
+
files = Dir["#{directory}/#{filter}"]
|
|
78
78
|
if select_files
|
|
79
79
|
files.select! {|f| !File.directory? f }
|
|
80
80
|
else
|
|
@@ -87,17 +87,17 @@ module Cosmos
|
|
|
87
87
|
end
|
|
88
88
|
return answer
|
|
89
89
|
end
|
|
90
|
-
def save_file_dialog(directory = Cosmos::USERPATH, message = "Save File")
|
|
91
|
-
_file_dialog(message, directory)
|
|
90
|
+
def save_file_dialog(directory = Cosmos::USERPATH, message = "Save File", filter = "*")
|
|
91
|
+
_file_dialog(message, directory, filter)
|
|
92
92
|
end
|
|
93
|
-
def open_file_dialog(directory = Cosmos::USERPATH, message = "Open File")
|
|
94
|
-
_file_dialog(message, directory)
|
|
93
|
+
def open_file_dialog(directory = Cosmos::USERPATH, message = "Open File", filter = "*")
|
|
94
|
+
_file_dialog(message, directory, filter)
|
|
95
95
|
end
|
|
96
|
-
def open_files_dialog(directory = Cosmos::USERPATH, message = "Open File(s)")
|
|
97
|
-
_file_dialog(message, directory)
|
|
96
|
+
def open_files_dialog(directory = Cosmos::USERPATH, message = "Open File(s)", filter = "*")
|
|
97
|
+
_file_dialog(message, directory, filter)
|
|
98
98
|
end
|
|
99
99
|
def open_directory_dialog(directory = Cosmos::USERPATH, message = "Open Directory")
|
|
100
|
-
_file_dialog(message, directory, false)
|
|
100
|
+
_file_dialog(message, directory, "*", false)
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
def prompt_for_hazardous(target_name, cmd_name, hazardous_description)
|
data/lib/cosmos/script/tools.rb
CHANGED
|
@@ -92,6 +92,20 @@ module Cosmos
|
|
|
92
92
|
end
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
+
###########################
|
|
96
|
+
# Telemetry Screen methods
|
|
97
|
+
###########################
|
|
98
|
+
|
|
99
|
+
# Get the organized list of available telemetry screens
|
|
100
|
+
def get_screen_list(config_filename = nil, force_refresh = false)
|
|
101
|
+
$cmd_tlm_server.get_screen_list(config_filename, force_refresh)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Get a specific screen definition
|
|
105
|
+
def get_screen_definition(screen_full_name, config_filename = nil, force_refresh = false)
|
|
106
|
+
$cmd_tlm_server.get_screen_definition(screen_full_name, config_filename, force_refresh)
|
|
107
|
+
end
|
|
108
|
+
|
|
95
109
|
end # module Script
|
|
96
110
|
|
|
97
111
|
end # module Cosmos
|
data/lib/cosmos/system/system.rb
CHANGED
|
@@ -17,6 +17,8 @@ require 'cosmos/system/target'
|
|
|
17
17
|
require 'cosmos/packet_logs'
|
|
18
18
|
require 'fileutils'
|
|
19
19
|
require 'drb/acl'
|
|
20
|
+
require 'zip'
|
|
21
|
+
require 'zip/filesystem'
|
|
20
22
|
require 'bundler'
|
|
21
23
|
|
|
22
24
|
module Cosmos
|
|
@@ -52,7 +54,7 @@ module Cosmos
|
|
|
52
54
|
# @return [String] Stores the initial configuration file used when this
|
|
53
55
|
# System was initialized
|
|
54
56
|
instance_attr_reader :initial_filename
|
|
55
|
-
# @return [
|
|
57
|
+
# @return [PacketConfig] Stores the initial packet list used when this
|
|
56
58
|
# System was initialized
|
|
57
59
|
instance_attr_reader :initial_config
|
|
58
60
|
# @return [ACL] Access control list showing which machines can have access
|
|
@@ -71,9 +73,9 @@ module Cosmos
|
|
|
71
73
|
instance_attr_reader :additional_md5_files
|
|
72
74
|
|
|
73
75
|
# Known COSMOS ports
|
|
74
|
-
KNOWN_PORTS = ['CTS_API', 'TLMVIEWER_API', 'CTS_PREIDENTIFIED', 'CTS_CMD_ROUTER']
|
|
76
|
+
KNOWN_PORTS = ['CTS_API', 'TLMVIEWER_API', 'CTS_PREIDENTIFIED', 'CTS_CMD_ROUTER', 'REPLAY_API', 'REPLAY_PREIDENTIFIED', 'REPLAY_CMD_ROUTER']
|
|
75
77
|
# Known COSMOS hosts
|
|
76
|
-
KNOWN_HOSTS = ['CTS_API', 'TLMVIEWER_API', 'CTS_PREIDENTIFIED', 'CTS_CMD_ROUTER']
|
|
78
|
+
KNOWN_HOSTS = ['CTS_API', 'TLMVIEWER_API', 'CTS_PREIDENTIFIED', 'CTS_CMD_ROUTER', 'REPLAY_API', 'REPLAY_PREIDENTIFIED', 'REPLAY_CMD_ROUTER']
|
|
77
79
|
# Known COSMOS paths
|
|
78
80
|
KNOWN_PATHS = ['LOGS', 'TMP', 'SAVED_CONFIG', 'TABLES', 'HANDBOOKS', 'PROCEDURES', 'SEQUENCES']
|
|
79
81
|
|
|
@@ -88,69 +90,7 @@ module Cosmos
|
|
|
88
90
|
# read. Be default this is <Cosmos::USERPATH>/config/system/system.txt
|
|
89
91
|
def initialize(filename = nil)
|
|
90
92
|
raise "Cosmos::System created twice" unless @@instance.nil?
|
|
91
|
-
|
|
92
|
-
@targets['UNKNOWN'] = Target.new('UNKNOWN')
|
|
93
|
-
@config = nil
|
|
94
|
-
@commands = nil
|
|
95
|
-
@telemetry = nil
|
|
96
|
-
@limits = nil
|
|
97
|
-
@default_packet_log_writer = PacketLogWriter
|
|
98
|
-
@default_packet_log_writer_params = []
|
|
99
|
-
@default_packet_log_reader = PacketLogReader
|
|
100
|
-
@default_packet_log_reader_params = []
|
|
101
|
-
@sound = false
|
|
102
|
-
@use_dns = false
|
|
103
|
-
@acl = nil
|
|
104
|
-
@staleness_seconds = 30
|
|
105
|
-
@limits_set = :DEFAULT
|
|
106
|
-
@use_utc = false
|
|
107
|
-
@additional_md5_files = []
|
|
108
|
-
@meta_init_filename = nil
|
|
109
|
-
|
|
110
|
-
@ports = {}
|
|
111
|
-
@ports['CTS_API'] = 7777
|
|
112
|
-
@ports['TLMVIEWER_API'] = 7778
|
|
113
|
-
@ports['CTS_PREIDENTIFIED'] = 7779
|
|
114
|
-
@ports['CTS_CMD_ROUTER'] = 7780
|
|
115
|
-
|
|
116
|
-
@listen_hosts = {}
|
|
117
|
-
@listen_hosts['CTS_API'] = '127.0.0.1'
|
|
118
|
-
@listen_hosts['TLMVIEWER_API'] = '127.0.0.1'
|
|
119
|
-
# Localhost would be more secure but historically these are open to allow for chaining servers by default
|
|
120
|
-
@listen_hosts['CTS_PREIDENTIFIED'] = '0.0.0.0'
|
|
121
|
-
@listen_hosts['CTS_CMD_ROUTER'] = '0.0.0.0'
|
|
122
|
-
|
|
123
|
-
@connect_hosts = {}
|
|
124
|
-
@connect_hosts['CTS_API'] = '127.0.0.1'
|
|
125
|
-
@connect_hosts['TLMVIEWER_API'] = '127.0.0.1'
|
|
126
|
-
@connect_hosts['CTS_PREIDENTIFIED'] = '127.0.0.1'
|
|
127
|
-
@connect_hosts['CTS_CMD_ROUTER'] = '127.0.0.1'
|
|
128
|
-
|
|
129
|
-
@paths = {}
|
|
130
|
-
@paths['LOGS'] = File.join(USERPATH, 'outputs', 'logs')
|
|
131
|
-
@paths['TMP'] = File.join(USERPATH, 'outputs', 'tmp')
|
|
132
|
-
@paths['SAVED_CONFIG'] = File.join(USERPATH, 'outputs', 'saved_config')
|
|
133
|
-
@paths['TABLES'] = File.join(USERPATH, 'outputs', 'tables')
|
|
134
|
-
@paths['HANDBOOKS'] = File.join(USERPATH, 'outputs', 'handbooks')
|
|
135
|
-
@paths['PROCEDURES'] = [File.join(USERPATH, 'procedures')]
|
|
136
|
-
@paths['SEQUENCES'] = File.join(USERPATH, 'outputs', 'sequences')
|
|
137
|
-
|
|
138
|
-
unless filename
|
|
139
|
-
system_arg = false
|
|
140
|
-
ARGV.each do |arg|
|
|
141
|
-
if system_arg
|
|
142
|
-
filename = File.join(USERPATH, 'config', 'system', arg)
|
|
143
|
-
break
|
|
144
|
-
end
|
|
145
|
-
system_arg = true if arg == '--system'
|
|
146
|
-
end
|
|
147
|
-
filename = File.join(USERPATH, 'config', 'system', 'system.txt') unless filename
|
|
148
|
-
end
|
|
149
|
-
process_file(filename)
|
|
150
|
-
ENV['COSMOS_LOGS_DIR'] = @paths['LOGS']
|
|
151
|
-
|
|
152
|
-
@initial_filename = filename
|
|
153
|
-
@initial_config = nil
|
|
93
|
+
reset_variables(filename)
|
|
154
94
|
@@instance = self
|
|
155
95
|
end
|
|
156
96
|
|
|
@@ -489,6 +429,8 @@ module Cosmos
|
|
|
489
429
|
end # parser.parse_file
|
|
490
430
|
end
|
|
491
431
|
|
|
432
|
+
|
|
433
|
+
|
|
492
434
|
# Load the specified configuration by iterating through the SAVED_CONFIG
|
|
493
435
|
# directory looking for a matching MD5 sum. Updates the internal state so
|
|
494
436
|
# subsequent commands and telemetry methods return the new configuration.
|
|
@@ -507,12 +449,16 @@ module Cosmos
|
|
|
507
449
|
update_config(@initial_config)
|
|
508
450
|
else
|
|
509
451
|
# Look for the requested configuration in the saved configurations
|
|
510
|
-
|
|
511
|
-
if
|
|
452
|
+
configuration = find_configuration(name)
|
|
453
|
+
if configuration
|
|
512
454
|
# We found the configuration requested. Reprocess the system.txt
|
|
513
455
|
# and reload the packets
|
|
514
456
|
begin
|
|
515
|
-
|
|
457
|
+
unless File.directory?(configuration)
|
|
458
|
+
# Zip file configuration so unzip and reset configuration path
|
|
459
|
+
configuration = unzip(configuration)
|
|
460
|
+
end
|
|
461
|
+
process_file(File.join(configuration, 'system.txt'), configuration)
|
|
516
462
|
load_packets(name)
|
|
517
463
|
rescue Exception => error
|
|
518
464
|
# Failed to load - Restore initial
|
|
@@ -539,8 +485,145 @@ module Cosmos
|
|
|
539
485
|
return self.instance.load_configuration(name)
|
|
540
486
|
end
|
|
541
487
|
|
|
488
|
+
# Resets the System's internal state to defaults.
|
|
489
|
+
#
|
|
490
|
+
# @params [String] Path to system.txt config file to process. Defaults to config/system/system.txt
|
|
491
|
+
def reset_variables(filename = nil)
|
|
492
|
+
@targets = {}
|
|
493
|
+
@targets['UNKNOWN'] = Target.new('UNKNOWN')
|
|
494
|
+
@config = nil
|
|
495
|
+
@commands = nil
|
|
496
|
+
@telemetry = nil
|
|
497
|
+
@limits = nil
|
|
498
|
+
@default_packet_log_writer = PacketLogWriter
|
|
499
|
+
@default_packet_log_writer_params = []
|
|
500
|
+
@default_packet_log_reader = PacketLogReader
|
|
501
|
+
@default_packet_log_reader_params = []
|
|
502
|
+
@sound = false
|
|
503
|
+
@use_dns = false
|
|
504
|
+
@acl = nil
|
|
505
|
+
@staleness_seconds = 30
|
|
506
|
+
@limits_set = :DEFAULT
|
|
507
|
+
@use_utc = false
|
|
508
|
+
@additional_md5_files = []
|
|
509
|
+
@meta_init_filename = nil
|
|
510
|
+
|
|
511
|
+
@ports = {}
|
|
512
|
+
@ports['CTS_API'] = 7777
|
|
513
|
+
@ports['TLMVIEWER_API'] = 7778
|
|
514
|
+
@ports['CTS_PREIDENTIFIED'] = 7779
|
|
515
|
+
@ports['CTS_CMD_ROUTER'] = 7780
|
|
516
|
+
@ports['REPLAY_API'] = 7877
|
|
517
|
+
@ports['REPLAY_PREIDENTIFIED'] = 7879
|
|
518
|
+
@ports['REPLAY_CMD_ROUTER'] = 7880
|
|
519
|
+
|
|
520
|
+
@listen_hosts = {}
|
|
521
|
+
@listen_hosts['CTS_API'] = '127.0.0.1'
|
|
522
|
+
@listen_hosts['TLMVIEWER_API'] = '127.0.0.1'
|
|
523
|
+
# Localhost would be more secure but historically these are open to allow for chaining servers by default
|
|
524
|
+
@listen_hosts['CTS_PREIDENTIFIED'] = '0.0.0.0'
|
|
525
|
+
@listen_hosts['CTS_CMD_ROUTER'] = '0.0.0.0'
|
|
526
|
+
@listen_hosts['REPLAY_API'] = '127.0.0.1'
|
|
527
|
+
# Localhost would be more secure but historically these are open to allow for chaining servers by default
|
|
528
|
+
@listen_hosts['REPLAY_PREIDENTIFIED'] = '0.0.0.0'
|
|
529
|
+
@listen_hosts['REPLAY_CMD_ROUTER'] = '0.0.0.0'
|
|
530
|
+
|
|
531
|
+
@connect_hosts = {}
|
|
532
|
+
@connect_hosts['CTS_API'] = '127.0.0.1'
|
|
533
|
+
@connect_hosts['TLMVIEWER_API'] = '127.0.0.1'
|
|
534
|
+
@connect_hosts['CTS_PREIDENTIFIED'] = '127.0.0.1'
|
|
535
|
+
@connect_hosts['CTS_CMD_ROUTER'] = '127.0.0.1'
|
|
536
|
+
@connect_hosts['REPLAY_API'] = '127.0.0.1'
|
|
537
|
+
@connect_hosts['REPLAY_PREIDENTIFIED'] = '127.0.0.1'
|
|
538
|
+
@connect_hosts['REPLAY_CMD_ROUTER'] = '127.0.0.1'
|
|
539
|
+
|
|
540
|
+
@paths = {}
|
|
541
|
+
@paths['LOGS'] = File.join(USERPATH, 'outputs', 'logs')
|
|
542
|
+
@paths['TMP'] = File.join(USERPATH, 'outputs', 'tmp')
|
|
543
|
+
@paths['SAVED_CONFIG'] = File.join(USERPATH, 'outputs', 'saved_config')
|
|
544
|
+
@paths['TABLES'] = File.join(USERPATH, 'outputs', 'tables')
|
|
545
|
+
@paths['HANDBOOKS'] = File.join(USERPATH, 'outputs', 'handbooks')
|
|
546
|
+
@paths['PROCEDURES'] = [File.join(USERPATH, 'procedures')]
|
|
547
|
+
@paths['SEQUENCES'] = File.join(USERPATH, 'outputs', 'sequences')
|
|
548
|
+
|
|
549
|
+
unless filename
|
|
550
|
+
system_arg = false
|
|
551
|
+
ARGV.each do |arg|
|
|
552
|
+
if system_arg
|
|
553
|
+
filename = File.join(USERPATH, 'config', 'system', arg)
|
|
554
|
+
break
|
|
555
|
+
end
|
|
556
|
+
system_arg = true if arg == '--system'
|
|
557
|
+
end
|
|
558
|
+
filename = File.join(USERPATH, 'config', 'system', 'system.txt') unless filename
|
|
559
|
+
end
|
|
560
|
+
process_file(filename)
|
|
561
|
+
ENV['COSMOS_LOGS_DIR'] = @paths['LOGS']
|
|
562
|
+
|
|
563
|
+
@initial_filename = filename
|
|
564
|
+
@initial_config = nil
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
# Reset variables and load packets
|
|
568
|
+
def reset(filename = nil)
|
|
569
|
+
reset_variables(filename)
|
|
570
|
+
load_packets()
|
|
571
|
+
end
|
|
572
|
+
|
|
573
|
+
# Class level convenience reset method
|
|
574
|
+
def self.reset
|
|
575
|
+
self.instance.reset
|
|
576
|
+
end
|
|
577
|
+
|
|
542
578
|
protected
|
|
543
579
|
|
|
580
|
+
def unzip(zip_file)
|
|
581
|
+
zip_dir = File.join(@paths['TMP'], File.basename(zip_file, ".*"))
|
|
582
|
+
# Only unzip if we have to. We assume the unzipped directory structure is
|
|
583
|
+
# intact. If not they'll get a popop with the errors encountered when
|
|
584
|
+
# loading the configuration.
|
|
585
|
+
unless File.exist? zip_dir
|
|
586
|
+
Zip::File.open(zip_file) do |zip_file|
|
|
587
|
+
zip_file.each do |entry|
|
|
588
|
+
path = File.join(@paths['TMP'], entry.name)
|
|
589
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
590
|
+
zip_file.extract(entry, path) unless File.exist?(path)
|
|
591
|
+
end
|
|
592
|
+
end
|
|
593
|
+
end
|
|
594
|
+
zip_dir
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
# A helper method to make the zip writing recursion work
|
|
598
|
+
def write_zip_entries(base_dir, entries, zip_path, io)
|
|
599
|
+
io.add(zip_path, base_dir) # Add the directory whether it has entries or not
|
|
600
|
+
entries.each do |e|
|
|
601
|
+
zip_file_path = File.join(zip_path, e)
|
|
602
|
+
disk_file_path = File.join(base_dir, e)
|
|
603
|
+
if File.directory? disk_file_path
|
|
604
|
+
recursively_deflate_directory(disk_file_path, io, zip_file_path)
|
|
605
|
+
else
|
|
606
|
+
put_into_archive(disk_file_path, io, zip_file_path)
|
|
607
|
+
end
|
|
608
|
+
end
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
def recursively_deflate_directory(disk_file_path, io, zip_file_path)
|
|
612
|
+
io.add(zip_file_path, disk_file_path)
|
|
613
|
+
entries = Dir.entries(disk_file_path) - %w(. ..)
|
|
614
|
+
write_zip_entries(disk_file_path, entries, zip_file_path, io)
|
|
615
|
+
end
|
|
616
|
+
|
|
617
|
+
def put_into_archive(disk_file_path, io, zip_file_path)
|
|
618
|
+
io.get_output_stream(zip_file_path) do |f|
|
|
619
|
+
data = nil
|
|
620
|
+
File.open(disk_file_path, 'rb') do |file|
|
|
621
|
+
data = file.read
|
|
622
|
+
end
|
|
623
|
+
f.write(data)
|
|
624
|
+
end
|
|
625
|
+
end
|
|
626
|
+
|
|
544
627
|
def auto_detect_gem_based_targets
|
|
545
628
|
Bundler.load.specs.each do |spec|
|
|
546
629
|
spec_name_split = spec.name.split('-')
|
|
@@ -577,7 +660,7 @@ module Cosmos
|
|
|
577
660
|
Cosmos.set_working_dir do
|
|
578
661
|
Dir.foreach(@paths['SAVED_CONFIG']) do |filename|
|
|
579
662
|
full_path = File.join(@paths['SAVED_CONFIG'], filename)
|
|
580
|
-
if
|
|
663
|
+
if File.exist?(full_path) && File.basename(filename, ".*")[-32..-1] == name
|
|
581
664
|
return full_path
|
|
582
665
|
end
|
|
583
666
|
end
|
|
@@ -587,35 +670,45 @@ module Cosmos
|
|
|
587
670
|
|
|
588
671
|
def save_configuration
|
|
589
672
|
Cosmos.set_working_dir do
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
unless
|
|
673
|
+
configuration = find_configuration(@config.name)
|
|
674
|
+
configuration = File.join(@paths['SAVED_CONFIG'], File.build_timestamped_filename([@config.name], '.zip')) unless configuration
|
|
675
|
+
unless File.exist?(configuration)
|
|
593
676
|
begin
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
@targets.each do |target_name, target|
|
|
599
|
-
destination_dir = File.join(configuration_directory, target.original_name)
|
|
600
|
-
unless Dir.exist?(destination_dir)
|
|
601
|
-
FileUtils.cp_r(target.dir, destination_dir)
|
|
602
|
-
end
|
|
603
|
-
end
|
|
677
|
+
Zip.continue_on_exists_proc = true
|
|
678
|
+
Zip::File.open(configuration, Zip::File::CREATE) do |zipfile|
|
|
679
|
+
zip_file_path = File.basename(configuration, ".zip")
|
|
680
|
+
zipfile.mkdir zip_file_path
|
|
604
681
|
|
|
605
|
-
|
|
606
|
-
|
|
682
|
+
# Copy target files into archive
|
|
683
|
+
zip_targets = []
|
|
607
684
|
@targets.each do |target_name, target|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
685
|
+
entries = Dir.entries(target.dir) - %w(. ..)
|
|
686
|
+
zip_target = File.join(zip_file_path, target.original_name)
|
|
687
|
+
# Check the stored list of targets. We can't ask the zip file
|
|
688
|
+
# itself because it's in progress and hasn't been saved
|
|
689
|
+
unless zip_targets.include?(zip_target)
|
|
690
|
+
write_zip_entries(target.dir, entries, zip_target, zipfile)
|
|
691
|
+
zip_targets << zip_target
|
|
692
|
+
end
|
|
693
|
+
end
|
|
694
|
+
|
|
695
|
+
# Create custom system.txt file
|
|
696
|
+
zipfile.get_output_stream(File.join(zip_file_path, 'system.txt')) do |file|
|
|
697
|
+
@targets.each do |target_name, target|
|
|
698
|
+
target_filename = File.basename(target.filename)
|
|
699
|
+
target_filename = nil unless File.exist?(target.filename)
|
|
700
|
+
# Create a newline character since Zip opens files in binary mode
|
|
701
|
+
newline = Kernel.is_windows? ? "\r\n" : "\n"
|
|
702
|
+
if target.substitute
|
|
703
|
+
file.write "DECLARE_TARGET #{target.original_name} #{target.name} #{target_filename}#{newline}"
|
|
704
|
+
else
|
|
705
|
+
file.write "DECLARE_TARGET #{target.name} nil #{target_filename}#{newline}"
|
|
706
|
+
end
|
|
614
707
|
end
|
|
615
708
|
end
|
|
616
709
|
end
|
|
617
710
|
rescue Exception => error
|
|
618
|
-
Logger.error "Problem saving configuration to #{
|
|
711
|
+
Logger.error "Problem saving configuration to #{configuration}: #{error.class}:#{error.message}\n#{error.backtrace.join("\n")}\n"
|
|
619
712
|
end
|
|
620
713
|
end
|
|
621
714
|
end
|