aspera-cli 4.26.0 → 4.26.2
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
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +36 -4
- data/CONTRIBUTING.md +2 -5
- data/bin/ascli +2 -2
- data/lib/aspera/agent/direct.rb +1 -1
- data/lib/aspera/agent/factory.rb +4 -0
- data/lib/aspera/agent/httpgw.rb +1 -1
- data/lib/aspera/agent/node.rb +2 -2
- data/lib/aspera/api/aoc.rb +45 -37
- data/lib/aspera/api/cos_node.rb +1 -1
- data/lib/aspera/api/faspex.rb +7 -6
- data/lib/aspera/api/node.rb +9 -9
- data/lib/aspera/ascmd.rb +4 -4
- data/lib/aspera/ascp/installation.rb +13 -6
- data/lib/aspera/assert.rb +17 -13
- data/lib/aspera/cli/context.rb +58 -0
- data/lib/aspera/cli/extended_value.rb +9 -4
- data/lib/aspera/cli/formatter.rb +91 -187
- data/lib/aspera/cli/http.rb +167 -0
- data/lib/aspera/cli/manager.rb +132 -77
- data/lib/aspera/cli/options.schema.yaml +82 -0
- data/lib/aspera/cli/plugins/alee.rb +2 -2
- data/lib/aspera/cli/plugins/aoc.rb +113 -77
- data/lib/aspera/cli/plugins/ats.rb +16 -16
- data/lib/aspera/cli/plugins/base.rb +64 -49
- data/lib/aspera/cli/plugins/config.rb +172 -444
- data/lib/aspera/cli/plugins/console.rb +7 -7
- data/lib/aspera/cli/plugins/cos.rb +2 -2
- data/lib/aspera/cli/plugins/factory.rb +3 -0
- data/lib/aspera/cli/plugins/faspex.rb +22 -22
- data/lib/aspera/cli/plugins/faspex5.rb +68 -49
- data/lib/aspera/cli/plugins/faspio.rb +1 -1
- data/lib/aspera/cli/plugins/httpgw.rb +2 -2
- data/lib/aspera/cli/plugins/node.rb +80 -80
- data/lib/aspera/cli/plugins/orchestrator.rb +21 -26
- data/lib/aspera/cli/plugins/preview.rb +9 -9
- data/lib/aspera/cli/plugins/server.rb +7 -7
- data/lib/aspera/cli/plugins/shares.rb +2 -2
- data/lib/aspera/cli/preset_manager.rb +235 -0
- data/lib/aspera/cli/result.rb +310 -0
- data/lib/aspera/cli/{main.rb → runner.rb} +48 -130
- data/lib/aspera/cli/sync_actions.rb +15 -11
- data/lib/aspera/cli/terminal_formatter.rb +65 -0
- data/lib/aspera/cli/transfer_agent.rb +17 -15
- data/lib/aspera/cli/transfer_progress.rb +6 -6
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/cli/wizard.rb +5 -6
- data/lib/aspera/command_line_builder.rb +22 -18
- data/lib/aspera/data_repository.rb +4 -0
- data/lib/aspera/dot_container.rb +1 -1
- data/lib/aspera/environment.rb +25 -6
- data/lib/aspera/faspex_gw.rb +1 -1
- data/lib/aspera/formatter_interface.rb +14 -0
- data/lib/aspera/hash_ext.rb +6 -0
- data/lib/aspera/json_rpc.rb +6 -5
- data/lib/aspera/keychain/base.rb +1 -1
- data/lib/aspera/keychain/encrypted_hash.rb +1 -1
- data/lib/aspera/keychain/factory.rb +1 -1
- data/lib/aspera/keychain/macos_security.rb +1 -1
- data/lib/aspera/log.rb +10 -5
- data/lib/aspera/markdown.rb +4 -1
- data/lib/aspera/nagios.rb +2 -2
- data/lib/aspera/oauth/base.rb +5 -5
- data/lib/aspera/oauth/boot.rb +43 -0
- data/lib/aspera/oauth/factory.rb +38 -14
- data/lib/aspera/oauth/web.rb +2 -2
- data/lib/aspera/oauth.rb +1 -0
- data/lib/aspera/persistency_action_once.rb +2 -2
- data/lib/aspera/preview/file_types.rb +4 -0
- data/lib/aspera/products/connect.rb +3 -0
- data/lib/aspera/products/transferd.rb +2 -2
- data/lib/aspera/proxy_auto_config.rb +6 -3
- data/lib/aspera/rest.rb +9 -5
- data/lib/aspera/rest_error_analyzer.rb +4 -0
- data/lib/aspera/rest_list.rb +10 -3
- data/lib/aspera/schema/IBM Aspera Faspex API-5.0-enhanced.yaml +62811 -0
- data/lib/aspera/schema/IBM Aspera on Cloud API-0.2.6-enhanced.yaml +9637 -0
- data/lib/aspera/schema/async_tables.yaml +361 -0
- data/lib/aspera/schema/documentation.rb +107 -0
- data/lib/aspera/schema/reader.rb +75 -0
- data/lib/aspera/schema/registry.rb +70 -0
- data/lib/aspera/secret_hider.rb +4 -0
- data/lib/aspera/sync/conf.schema.yaml +0 -26
- data/lib/aspera/sync/database.rb +14 -10
- data/lib/aspera/sync/operations.rb +14 -10
- data/lib/aspera/temp_file_manager.rb +4 -0
- data/lib/aspera/transfer/faux_file.rb +1 -1
- data/lib/aspera/transfer/parameters.rb +4 -4
- data/lib/aspera/transfer/resumer.rb +2 -2
- data/lib/aspera/transfer/spec.rb +3 -3
- data/lib/aspera/transfer/spec.schema.yaml +18 -9
- data/lib/aspera/transfer/uri.rb +1 -1
- data/lib/aspera/uri_reader.rb +1 -1
- data/lib/aspera/yaml.rb +4 -2
- data.tar.gz.sig +0 -0
- metadata +28 -15
- metadata.gz.sig +1 -1
- data/lib/aspera/transfer/spec_doc.rb +0 -76
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
# Schema for the SQLite tables inside the Async snap database (snap.db).
|
|
2
|
+
# Sources:
|
|
3
|
+
# include/async/session/Sqlite3_SSDB.h (SYNC_SQLITE3_META_SCHEMA, SYNC_SQLITE3_COUNTERS_SCHEMA, SYNC_SQLITE3_SCHEMA_1_0)
|
|
4
|
+
# include/async/common/Sync_types.h (SSSTATE values)
|
|
5
|
+
# Verified against a live snap.db using: ascli config sync admin overview <path>
|
|
6
|
+
$schema: https://json-schema.org/draft/2020-12/schema
|
|
7
|
+
$id: https://github.com/IBM/aspera-cli/tree/main/lib/aspera/schema/async_tables.yaml
|
|
8
|
+
title: Async snap database tables
|
|
9
|
+
description: Schemas for the SQLite tables stored inside the Async snap database (`snap.db`).
|
|
10
|
+
type: object
|
|
11
|
+
properties:
|
|
12
|
+
meta:
|
|
13
|
+
title: sync_snapmeta_table
|
|
14
|
+
description: One row per session, written at start and updated at stop.
|
|
15
|
+
type: object
|
|
16
|
+
properties:
|
|
17
|
+
dbversion:
|
|
18
|
+
description: Database schema version.
|
|
19
|
+
type: string
|
|
20
|
+
pairname:
|
|
21
|
+
description: Sync session name.
|
|
22
|
+
type: string
|
|
23
|
+
ldir:
|
|
24
|
+
description: Local directory path.
|
|
25
|
+
type: string
|
|
26
|
+
rhost:
|
|
27
|
+
description: Remote host.
|
|
28
|
+
type: string
|
|
29
|
+
rdir:
|
|
30
|
+
description: Remote directory path.
|
|
31
|
+
type: string
|
|
32
|
+
direction:
|
|
33
|
+
description: Sync direction.
|
|
34
|
+
type: string
|
|
35
|
+
enum:
|
|
36
|
+
- push
|
|
37
|
+
- pull
|
|
38
|
+
- bidi
|
|
39
|
+
inode_format:
|
|
40
|
+
description: Inode format used by the session.
|
|
41
|
+
type: string
|
|
42
|
+
checksum:
|
|
43
|
+
description: Checksum algorithm.
|
|
44
|
+
type: string
|
|
45
|
+
enum:
|
|
46
|
+
- sha1
|
|
47
|
+
- md5
|
|
48
|
+
- sha1_sparse
|
|
49
|
+
- md5_sparse
|
|
50
|
+
- none
|
|
51
|
+
start_time:
|
|
52
|
+
description: Session start timestamp.
|
|
53
|
+
type: string
|
|
54
|
+
format: date-time
|
|
55
|
+
stop_time:
|
|
56
|
+
description: Session stop timestamp (written when session ends).
|
|
57
|
+
type: string
|
|
58
|
+
format: date-time
|
|
59
|
+
condition:
|
|
60
|
+
description: Last known session condition.
|
|
61
|
+
type: string
|
|
62
|
+
enum:
|
|
63
|
+
- running
|
|
64
|
+
- stopped
|
|
65
|
+
scn_true_val:
|
|
66
|
+
description: Scan counter true value (internal).
|
|
67
|
+
type: integer
|
|
68
|
+
sync_point:
|
|
69
|
+
description: Synchronization point sequence number.
|
|
70
|
+
type: integer
|
|
71
|
+
max_recid:
|
|
72
|
+
description: Highest record ID allocated in the snapshot table.
|
|
73
|
+
type: integer
|
|
74
|
+
sync_uuid:
|
|
75
|
+
description: UUID identifying this sync pair.
|
|
76
|
+
type: string
|
|
77
|
+
cip_true_val:
|
|
78
|
+
description: Candidate-in-progress counter true value (internal).
|
|
79
|
+
type: integer
|
|
80
|
+
exclude_dirs_older_than:
|
|
81
|
+
description: Exclude directories with modification time older than this epoch value (0 = disabled).
|
|
82
|
+
type: integer
|
|
83
|
+
path_synced:
|
|
84
|
+
description: Number of paths successfully synchronized.
|
|
85
|
+
type: integer
|
|
86
|
+
byte_synced:
|
|
87
|
+
description: Number of bytes successfully synchronized.
|
|
88
|
+
type: integer
|
|
89
|
+
filters:
|
|
90
|
+
description: Active include/exclude filter patterns.
|
|
91
|
+
type: string
|
|
92
|
+
path_peerxfer:
|
|
93
|
+
description: Number of paths transferred by the peer.
|
|
94
|
+
type: integer
|
|
95
|
+
byte_peerxfer:
|
|
96
|
+
description: Number of bytes transferred by the peer.
|
|
97
|
+
type: integer
|
|
98
|
+
path_xferres:
|
|
99
|
+
description: Number of paths for which transfer was resumed.
|
|
100
|
+
type: integer
|
|
101
|
+
byte_xferres:
|
|
102
|
+
description: Number of bytes for which transfer was resumed.
|
|
103
|
+
type: integer
|
|
104
|
+
file_synced:
|
|
105
|
+
description: Number of files successfully synchronized.
|
|
106
|
+
type: integer
|
|
107
|
+
file_peerxfer:
|
|
108
|
+
description: Number of files transferred by the peer.
|
|
109
|
+
type: integer
|
|
110
|
+
file_xferres:
|
|
111
|
+
description: Number of files for which transfer was resumed.
|
|
112
|
+
type: integer
|
|
113
|
+
ascp_sids:
|
|
114
|
+
description: Last known FASP (ascp) session IDs.
|
|
115
|
+
type: string
|
|
116
|
+
counters:
|
|
117
|
+
title: sync_snap_counters_table
|
|
118
|
+
description: One row, updated live during the session with path and file counts per state.
|
|
119
|
+
type: object
|
|
120
|
+
properties:
|
|
121
|
+
syncd:
|
|
122
|
+
description: Number of paths in the `Syncd` state.
|
|
123
|
+
type: integer
|
|
124
|
+
conflict:
|
|
125
|
+
description: Number of paths in the `Conflict` state.
|
|
126
|
+
type: integer
|
|
127
|
+
potential_conflict:
|
|
128
|
+
description: Number of paths in the `Potential conflict` state.
|
|
129
|
+
type: integer
|
|
130
|
+
error:
|
|
131
|
+
description: Number of paths in the `Error` state.
|
|
132
|
+
type: integer
|
|
133
|
+
pending:
|
|
134
|
+
description: Number of paths still pending synchronization.
|
|
135
|
+
type: integer
|
|
136
|
+
unused:
|
|
137
|
+
description: Reserved (unused counter slot).
|
|
138
|
+
type: integer
|
|
139
|
+
files_syncd:
|
|
140
|
+
description: Number of files in the `Syncd` state.
|
|
141
|
+
type: integer
|
|
142
|
+
files_conflict:
|
|
143
|
+
description: Number of files in the `Conflict` state.
|
|
144
|
+
type: integer
|
|
145
|
+
files_potential_conflict:
|
|
146
|
+
description: Number of files in the `Potential conflict` state.
|
|
147
|
+
type: integer
|
|
148
|
+
files_error:
|
|
149
|
+
description: Number of files in the `Error` state.
|
|
150
|
+
type: integer
|
|
151
|
+
files_pending:
|
|
152
|
+
description: Number of files still pending synchronization.
|
|
153
|
+
type: integer
|
|
154
|
+
file_info:
|
|
155
|
+
title: sync_snapdb_table
|
|
156
|
+
description: One row per tracked file or directory. Primary source for the `file_info` command.
|
|
157
|
+
type: object
|
|
158
|
+
properties:
|
|
159
|
+
record_id:
|
|
160
|
+
description: Primary key (auto-increment).
|
|
161
|
+
type: integer
|
|
162
|
+
nodeid:
|
|
163
|
+
description: Local filesystem node ID.
|
|
164
|
+
type: integer
|
|
165
|
+
peer_rid:
|
|
166
|
+
description: Peer record ID for this entry.
|
|
167
|
+
type: integer
|
|
168
|
+
state:
|
|
169
|
+
description: |
|
|
170
|
+
Sync state of the entry.
|
|
171
|
+
|
|
172
|
+
| Value | Name |
|
|
173
|
+
|-------|-------------------|
|
|
174
|
+
| 0 | Nil |
|
|
175
|
+
| 1–18 | Pending (variant) |
|
|
176
|
+
| 19 | Syncd |
|
|
177
|
+
| 20 | Error |
|
|
178
|
+
| 21 | Conflict |
|
|
179
|
+
| 22 | PotentialConflict |
|
|
180
|
+
| 23–24 | Pending (variant) |
|
|
181
|
+
type: integer
|
|
182
|
+
version:
|
|
183
|
+
description: Schema version field (not used).
|
|
184
|
+
type: integer
|
|
185
|
+
c_meta_type:
|
|
186
|
+
description: Current metadata — file type (file, directory, …).
|
|
187
|
+
type: integer
|
|
188
|
+
c_meta_parentrid:
|
|
189
|
+
description: Current metadata — parent record ID.
|
|
190
|
+
type: integer
|
|
191
|
+
c_meta_path:
|
|
192
|
+
description: Current metadata — file path as known to the snapshot.
|
|
193
|
+
type: string
|
|
194
|
+
c_meta_attrs:
|
|
195
|
+
description: Current metadata — file attributes.
|
|
196
|
+
type: string
|
|
197
|
+
c_meta_uid:
|
|
198
|
+
description: Current metadata — user ID (Unix).
|
|
199
|
+
type: integer
|
|
200
|
+
c_meta_gid:
|
|
201
|
+
description: Current metadata — group ID (Unix).
|
|
202
|
+
type: integer
|
|
203
|
+
c_meta_mtime:
|
|
204
|
+
description: Current metadata — modification time (epoch).
|
|
205
|
+
type: integer
|
|
206
|
+
c_meta_atime:
|
|
207
|
+
description: Current metadata — access time (epoch).
|
|
208
|
+
type: integer
|
|
209
|
+
c_meta_ctime:
|
|
210
|
+
description: Current metadata — change time (epoch).
|
|
211
|
+
type: integer
|
|
212
|
+
c_meta_xattrs:
|
|
213
|
+
description: Current metadata — extended attributes (not used).
|
|
214
|
+
type: integer
|
|
215
|
+
c_meta_xattrs_cksum:
|
|
216
|
+
description: Current metadata — checksum of extended attributes.
|
|
217
|
+
type: string
|
|
218
|
+
c_meta_ol_legal_hold:
|
|
219
|
+
description: Current metadata — object lock legal hold flag.
|
|
220
|
+
type: integer
|
|
221
|
+
c_meta_ol_mode:
|
|
222
|
+
description: Current metadata — object lock mode.
|
|
223
|
+
type: integer
|
|
224
|
+
c_meta_ol_retain_until:
|
|
225
|
+
description: Current metadata — object lock retain-until date (epoch).
|
|
226
|
+
type: integer
|
|
227
|
+
c_meta_object_metadata:
|
|
228
|
+
description: Current metadata — object metadata (JSON).
|
|
229
|
+
type: string
|
|
230
|
+
c_cont_size:
|
|
231
|
+
description: Current content — file size in bytes.
|
|
232
|
+
type: integer
|
|
233
|
+
c_cont_csum:
|
|
234
|
+
description: Current content — checksum.
|
|
235
|
+
type: string
|
|
236
|
+
c_cont_mtime:
|
|
237
|
+
description: Current content — modification time (epoch).
|
|
238
|
+
type: integer
|
|
239
|
+
c_cont_timestamp:
|
|
240
|
+
description: Current content — internal timestamp.
|
|
241
|
+
type: integer
|
|
242
|
+
p_cont_size:
|
|
243
|
+
description: Pending content — file size in bytes.
|
|
244
|
+
type: integer
|
|
245
|
+
p_cont_csum:
|
|
246
|
+
description: Pending content — checksum.
|
|
247
|
+
type: string
|
|
248
|
+
p_cont_mtime:
|
|
249
|
+
description: Pending content — modification time (epoch).
|
|
250
|
+
type: integer
|
|
251
|
+
p_cont_timestamp:
|
|
252
|
+
description: Pending content — internal timestamp.
|
|
253
|
+
type: integer
|
|
254
|
+
f_meta_type:
|
|
255
|
+
description: Filesystem metadata — file type.
|
|
256
|
+
type: integer
|
|
257
|
+
f_meta_parentrid:
|
|
258
|
+
description: Filesystem metadata — parent record ID.
|
|
259
|
+
type: integer
|
|
260
|
+
f_meta_path:
|
|
261
|
+
description: Filesystem metadata — file path as seen on disk (displayed by `file_info`).
|
|
262
|
+
type: string
|
|
263
|
+
f_meta_attrs:
|
|
264
|
+
description: Filesystem metadata — file attributes.
|
|
265
|
+
type: string
|
|
266
|
+
f_meta_uid:
|
|
267
|
+
description: Filesystem metadata — user ID (Unix).
|
|
268
|
+
type: integer
|
|
269
|
+
f_meta_gid:
|
|
270
|
+
description: Filesystem metadata — group ID (Unix).
|
|
271
|
+
type: integer
|
|
272
|
+
f_meta_mtime:
|
|
273
|
+
description: Filesystem metadata — modification time (epoch).
|
|
274
|
+
type: integer
|
|
275
|
+
f_meta_atime:
|
|
276
|
+
description: Filesystem metadata — access time (epoch).
|
|
277
|
+
type: integer
|
|
278
|
+
f_meta_ctime:
|
|
279
|
+
description: Filesystem metadata — change time (epoch).
|
|
280
|
+
type: integer
|
|
281
|
+
f_meta_xattrs:
|
|
282
|
+
description: Filesystem metadata — extended attributes (not used).
|
|
283
|
+
type: integer
|
|
284
|
+
f_meta_xattrs_cksum:
|
|
285
|
+
description: Filesystem metadata — checksum of extended attributes.
|
|
286
|
+
type: string
|
|
287
|
+
f_meta_ol_legal_hold:
|
|
288
|
+
description: Filesystem metadata — object lock legal hold flag.
|
|
289
|
+
type: integer
|
|
290
|
+
f_meta_ol_mode:
|
|
291
|
+
description: Filesystem metadata — object lock mode.
|
|
292
|
+
type: integer
|
|
293
|
+
f_meta_ol_retain_until:
|
|
294
|
+
description: Filesystem metadata — object lock retain-until date (epoch).
|
|
295
|
+
type: integer
|
|
296
|
+
f_meta_object_metadata:
|
|
297
|
+
description: Filesystem metadata — object metadata (JSON).
|
|
298
|
+
type: string
|
|
299
|
+
f_cont_size:
|
|
300
|
+
description: Filesystem content — file size in bytes.
|
|
301
|
+
type: integer
|
|
302
|
+
f_cont_csum:
|
|
303
|
+
description: Filesystem content — checksum.
|
|
304
|
+
type: string
|
|
305
|
+
f_cont_mtime:
|
|
306
|
+
description: Filesystem content — modification time (epoch).
|
|
307
|
+
type: integer
|
|
308
|
+
f_cont_timestamp:
|
|
309
|
+
description: Filesystem content — internal timestamp.
|
|
310
|
+
type: integer
|
|
311
|
+
pcr_reqno:
|
|
312
|
+
description: Peer content request sequence number.
|
|
313
|
+
type: integer
|
|
314
|
+
pp_cont_size:
|
|
315
|
+
description: Peer pending content — file size in bytes.
|
|
316
|
+
type: integer
|
|
317
|
+
pp_cont_csum:
|
|
318
|
+
description: Peer pending content — checksum.
|
|
319
|
+
type: string
|
|
320
|
+
pp_cont_mtime:
|
|
321
|
+
description: Peer pending content — modification time (epoch).
|
|
322
|
+
type: integer
|
|
323
|
+
pp_cont_timestamp:
|
|
324
|
+
description: Peer pending content — internal timestamp.
|
|
325
|
+
type: integer
|
|
326
|
+
tobe_deleted:
|
|
327
|
+
description: Set to 1 when the record is flagged for deletion (garbage collection pending).
|
|
328
|
+
type: integer
|
|
329
|
+
scn_not_visited:
|
|
330
|
+
description: Set to 1 when the scanner has not yet visited this entry in the current scan pass.
|
|
331
|
+
type: integer
|
|
332
|
+
scn_required:
|
|
333
|
+
description: Set to 1 when a rescan of this entry is required.
|
|
334
|
+
type: integer
|
|
335
|
+
scn_completed:
|
|
336
|
+
description: Set to 1 when the scan of this directory entry has completed.
|
|
337
|
+
type: integer
|
|
338
|
+
candidate_in_prog:
|
|
339
|
+
description: Set to 1 when this record is currently in the candidate transfer list.
|
|
340
|
+
type: integer
|
|
341
|
+
meta_lastreq_no:
|
|
342
|
+
description: Sequence number of the last metadata request sent.
|
|
343
|
+
type: integer
|
|
344
|
+
meta_lastresp_no:
|
|
345
|
+
description: Sequence number of the last metadata response received.
|
|
346
|
+
type: integer
|
|
347
|
+
commit_version:
|
|
348
|
+
description: Local commit version for this entry.
|
|
349
|
+
type: integer
|
|
350
|
+
peer_commit_version:
|
|
351
|
+
description: Peer commit version for this entry.
|
|
352
|
+
type: integer
|
|
353
|
+
peer_nodeid:
|
|
354
|
+
description: Peer filesystem node ID.
|
|
355
|
+
type: integer
|
|
356
|
+
recursive_mtime:
|
|
357
|
+
description: Most recent modification time across all descendants (directories only).
|
|
358
|
+
type: integer
|
|
359
|
+
message:
|
|
360
|
+
description: Error or status message associated with this entry.
|
|
361
|
+
type: string
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'aspera/agent/factory'
|
|
4
|
+
require 'aspera/markdown'
|
|
5
|
+
|
|
6
|
+
module Aspera
|
|
7
|
+
module Schema
|
|
8
|
+
# Generate documentation from Schema, for Transfer Spec, or async Conf spec
|
|
9
|
+
class Documentation
|
|
10
|
+
# @param formatter [Cli::Formatter] Formatter instance with methods: markdown_text, tick, check_row
|
|
11
|
+
# @param schema [Reader]
|
|
12
|
+
# @param include_option [Boolean] `true`: include CLI options (switches, env vars) in descriptions
|
|
13
|
+
# @param agent_columns [Boolean] `true`: add separate columns for each transfer agent compatibility
|
|
14
|
+
# @param code_highlight [Boolean] `true`: format name and type as code
|
|
15
|
+
def initialize(formatter, schema, include_option: false, agent_columns: false, code_highlight: false)
|
|
16
|
+
@formatter = formatter
|
|
17
|
+
@schema = schema
|
|
18
|
+
@include_option = include_option
|
|
19
|
+
@agent_columns = agent_columns
|
|
20
|
+
@code_highlight = code_highlight
|
|
21
|
+
@columns = %i[name type description]
|
|
22
|
+
@columns.insert(-2, *Agent::Factory::ALL.values.map{ |i| i[:short]}.sort) if @agent_columns
|
|
23
|
+
# @type [Array<Hash<Symbol,String>>]
|
|
24
|
+
@rows = []
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def rows
|
|
28
|
+
@rows.sort_by{ |i| i[:name]}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @return [Array<String>]
|
|
32
|
+
def columns
|
|
33
|
+
@columns.map(&:to_s)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# First row is the titles
|
|
37
|
+
# @return [Array<Array<String>>]
|
|
38
|
+
def table
|
|
39
|
+
[@columns.map(&:to_s)] + @rows.sort_by{ |i| i[:name]}.map{ |row| @columns.map{ |field| row[field]}}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Generate a documentation table from a JSON schema for transfer specifications
|
|
43
|
+
#
|
|
44
|
+
# Recursively processes a JSON schema to create a formatted table for manual documentation.
|
|
45
|
+
# Handles nested objects, arrays, and extracts metadata (descriptions, types, enums, deprecations).
|
|
46
|
+
#
|
|
47
|
+
# @param schema [Reader] The JSON schema to process
|
|
48
|
+
# @return [Documentation]
|
|
49
|
+
def build(schema = nil)
|
|
50
|
+
code = @code_highlight ? ->(c){"`#{c}`"} : ->(c){c}
|
|
51
|
+
schema ||= @schema
|
|
52
|
+
schema.each_property do |property_schema, _name, property_full_name|
|
|
53
|
+
node = property_schema.current
|
|
54
|
+
# Manual table
|
|
55
|
+
item = {
|
|
56
|
+
name: code.call(property_full_name),
|
|
57
|
+
type: code.call(node['type']),
|
|
58
|
+
description: []
|
|
59
|
+
}
|
|
60
|
+
# Render Markdown formatting and split lines
|
|
61
|
+
item[:description] =
|
|
62
|
+
node['description']
|
|
63
|
+
.gsub(Markdown::FORMATS){@formatter.markdown_text(Regexp.last_match)}
|
|
64
|
+
.split("\n") if node.key?('description')
|
|
65
|
+
item[:description].unshift("DEPRECATED: #{node['x-deprecation']}") if node.key?('x-deprecation')
|
|
66
|
+
# Add flags for supported agents in doc
|
|
67
|
+
agents = []
|
|
68
|
+
Agent::Factory::ALL.each_key do |sym|
|
|
69
|
+
agents.push(sym) if node['x-agents'].nil? || node['x-agents'].include?(sym.to_s)
|
|
70
|
+
end
|
|
71
|
+
Aspera.assert(agents.include?(:direct)){"#{name}: x-cli-option requires agent direct (or nil)"} if node['x-cli-option']
|
|
72
|
+
if @agent_columns
|
|
73
|
+
Agent::Factory::ALL.each do |sym, names|
|
|
74
|
+
item[names[:short]] = @formatter.tick(agents.include?(sym))
|
|
75
|
+
end
|
|
76
|
+
else
|
|
77
|
+
item[:description].push("(#{agents.map{ |i| Agent::Factory::ALL[i][:short].to_s.upcase}.sort.join(', ')})") unless agents.length.eql?(Agent::Factory::ALL.length)
|
|
78
|
+
end
|
|
79
|
+
# Only keep lines that are usable in supported agents
|
|
80
|
+
next false if agents.empty?
|
|
81
|
+
item[:description].push("Allowed values: #{node['enum'].map{ |v| @formatter.markdown_text("`#{v}`")}.join(', ')}.") if node.key?('enum')
|
|
82
|
+
item[:description].push("Default: #{code.call(node['default'])}.") if node.key?('default')
|
|
83
|
+
if @include_option
|
|
84
|
+
envvar_prefix = ''
|
|
85
|
+
cli_option =
|
|
86
|
+
if node.key?('x-cli-envvar')
|
|
87
|
+
envvar_prefix = 'env:'
|
|
88
|
+
node['x-cli-envvar']
|
|
89
|
+
elsif node['x-cli-switch']
|
|
90
|
+
node['x-cli-option']
|
|
91
|
+
elsif node['x-cli-option']
|
|
92
|
+
arg_type = node.key?('enum') ? '{enum}' : "{#{[node['type']].flatten.join('|')}}"
|
|
93
|
+
# conversion_tag = node['x-cli-convert']
|
|
94
|
+
conversion_tag = node.key?('x-cli-convert') ? 'conversion' : nil
|
|
95
|
+
sep = node['x-cli-option'].start_with?('--') ? '=' : ' '
|
|
96
|
+
"#{node['x-cli-option']}#{sep}#{"(#{conversion_tag})" if conversion_tag}#{arg_type}"
|
|
97
|
+
end
|
|
98
|
+
short = node.key?('x-cli-short') ? "(#{node['x-cli-short']})" : nil
|
|
99
|
+
item[:description].push("(#{'special:' if node['x-cli-special']}#{envvar_prefix}#{@formatter.markdown_text("`#{cli_option}`")})#{short}") if cli_option
|
|
100
|
+
end
|
|
101
|
+
@rows.push(@formatter.check_row(item))
|
|
102
|
+
end
|
|
103
|
+
self
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Aspera
|
|
4
|
+
# base class for plugins modules
|
|
5
|
+
module Schema
|
|
6
|
+
# JSON schema reader
|
|
7
|
+
class Reader
|
|
8
|
+
attr_reader :current
|
|
9
|
+
|
|
10
|
+
# Shortcut to access current value at path
|
|
11
|
+
# @param x [String] path element
|
|
12
|
+
# @return [Hash, Array, String, Integer] current value at path
|
|
13
|
+
def [](x)
|
|
14
|
+
@current[x]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Find sub path relative to current
|
|
18
|
+
# Honors $ref
|
|
19
|
+
def dig(*path)
|
|
20
|
+
current = @current
|
|
21
|
+
path.each do |p|
|
|
22
|
+
Aspera.assert(current.key?(p)){"schema: #{p} in #{path}"}
|
|
23
|
+
current = current[p]
|
|
24
|
+
Aspera.assert_type(current, Hash){'schema'}
|
|
25
|
+
if current.key?('$ref')
|
|
26
|
+
ref = current['$ref']
|
|
27
|
+
Aspera.assert(ref.start_with?('#/')){"schema $ref must start with '#/': #{ref}"}
|
|
28
|
+
current = @root.dig(*ref[2..].split('/'))
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
Reader.new(@root, current)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Read schema from file or from cache
|
|
35
|
+
# @param root [Hash] root schema
|
|
36
|
+
# @param current [Hash, nil] current position in
|
|
37
|
+
# @return [Hash, nil] schema
|
|
38
|
+
def initialize(root, current = nil)
|
|
39
|
+
@root = root
|
|
40
|
+
@current = current || root
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Recursively traverse schema properties with a block
|
|
44
|
+
# Handles nested objects and arrays automatically
|
|
45
|
+
# @param prefix [String] Prefix for property names (e.g., 'parent.child.')
|
|
46
|
+
# @yield [property_schema, name, full_name] Yields property info to block
|
|
47
|
+
# @yieldparam property_schema [Reader] Schema reader for this property (use .current to get node hash)
|
|
48
|
+
# @yieldparam name [String] Property name
|
|
49
|
+
# @yieldparam full_name [String] Full property name with prefix
|
|
50
|
+
# @return [nil]
|
|
51
|
+
def each_property(prefix = '', &block)
|
|
52
|
+
properties = dig('properties')
|
|
53
|
+
properties.current.each_key do |name|
|
|
54
|
+
property_full_name = "#{prefix}#{name}"
|
|
55
|
+
property_schema = properties.dig(name)
|
|
56
|
+
node = property_schema.current
|
|
57
|
+
|
|
58
|
+
# Yield current property to block
|
|
59
|
+
yield(property_schema, name, property_full_name)
|
|
60
|
+
|
|
61
|
+
# Recursively process nested structures
|
|
62
|
+
case node['type']
|
|
63
|
+
when 'object'
|
|
64
|
+
property_schema.each_property("#{property_full_name}.", &block) if node['properties']
|
|
65
|
+
when 'array'
|
|
66
|
+
if node['items']
|
|
67
|
+
array_item_schema = property_schema.dig('items')
|
|
68
|
+
array_item_schema.each_property("#{property_full_name}[].", &block) if array_item_schema.current['properties']
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'singleton'
|
|
4
|
+
require 'aspera/yaml'
|
|
5
|
+
require 'aspera/schema/reader'
|
|
6
|
+
|
|
7
|
+
module Aspera
|
|
8
|
+
# base class for plugins modules
|
|
9
|
+
module Schema
|
|
10
|
+
# @!method self.instance
|
|
11
|
+
# Returns the singleton instance of Registry
|
|
12
|
+
# @return [Registry] the singleton instance
|
|
13
|
+
class Registry
|
|
14
|
+
include Singleton
|
|
15
|
+
|
|
16
|
+
class << self
|
|
17
|
+
def known?(sym)
|
|
18
|
+
LOCATIONS.key?(sym)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Get path to request body, no check if it exists
|
|
22
|
+
# @return [String] path to request body
|
|
23
|
+
def req_body(component, endpoint)
|
|
24
|
+
"#{component}:paths./#{endpoint}.requestBody.content.application/json.schema"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
LOCATIONS = {
|
|
29
|
+
spec: 'aspera/transfer/spec.schema.yaml',
|
|
30
|
+
args: 'aspera/sync/args.schema.yaml',
|
|
31
|
+
conf: 'aspera/sync/conf.schema.yaml',
|
|
32
|
+
opts: 'aspera/cli/options.schema.yaml',
|
|
33
|
+
aoc: 'aspera/schema/IBM Aspera on Cloud API-0.2.6-enhanced.yaml',
|
|
34
|
+
faspex: 'aspera/schema/IBM Aspera Faspex API-5.0-enhanced.yaml',
|
|
35
|
+
async_tables: 'aspera/schema/async_tables.yaml'
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
OPTIONS = 'opts'
|
|
39
|
+
TRANSFER_SPEC = 'spec'
|
|
40
|
+
SYNC_CONF = 'conf'
|
|
41
|
+
SYNC_ARGS = 'args'
|
|
42
|
+
AOC = 'aoc'
|
|
43
|
+
FASPEX = 'faspex'
|
|
44
|
+
ASYNC_TABLES = 'async_tables'
|
|
45
|
+
TRANSFER_INFO = "#{OPTIONS}:components.schemas.TransferInfo"
|
|
46
|
+
|
|
47
|
+
REQ_BODY = '.requestBody.content.application/json.schema'
|
|
48
|
+
|
|
49
|
+
def initialize
|
|
50
|
+
@cache = {}
|
|
51
|
+
@main_folder = File.expand_path('../..', __dir__)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Read schema from file or from cache
|
|
55
|
+
# @param name_path [String] one of the keys in LOCATIONS, with optional :<path> suffix
|
|
56
|
+
# @return [Reader] schema
|
|
57
|
+
def reader(name_path)
|
|
58
|
+
name, path = name_path.split(':', 2)
|
|
59
|
+
sym = name.to_sym
|
|
60
|
+
Aspera.assert(Registry.known?(sym)){"schema: #{sym}"}
|
|
61
|
+
spec_file = File.join(@main_folder, LOCATIONS[sym])
|
|
62
|
+
@cache[sym] = Yaml.safe_load(File.read(spec_file)) if spec_file.end_with?('.yaml') && !@cache.key?(sym)
|
|
63
|
+
@cache[sym] = JSON.parse(File.read(spec_file)) if spec_file.end_with?('.json') && !@cache.key?(sym)
|
|
64
|
+
reader = Reader.new(@cache[sym])
|
|
65
|
+
return reader unless path
|
|
66
|
+
reader.dig(*path.split('.'))
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
data/lib/aspera/secret_hider.rb
CHANGED