aspera-cli 4.26.0 → 4.26.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +17 -3
- data/lib/aspera/api/aoc.rb +2 -1
- data/lib/aspera/api/node.rb +2 -2
- data/lib/aspera/ascp/installation.rb +7 -4
- data/lib/aspera/assert.rb +17 -13
- data/lib/aspera/cli/extended_value.rb +6 -2
- data/lib/aspera/cli/formatter.rb +65 -60
- data/lib/aspera/cli/main.rb +69 -10
- data/lib/aspera/cli/manager.rb +130 -76
- data/lib/aspera/cli/options.schema.yaml +82 -0
- data/lib/aspera/cli/plugins/aoc.rb +36 -11
- data/lib/aspera/cli/plugins/base.rb +46 -37
- data/lib/aspera/cli/plugins/config.rb +9 -9
- data/lib/aspera/cli/plugins/faspex.rb +1 -1
- data/lib/aspera/cli/plugins/faspex5.rb +4 -5
- data/lib/aspera/cli/plugins/node.rb +1 -1
- data/lib/aspera/cli/sync_actions.rb +1 -1
- data/lib/aspera/cli/transfer_agent.rb +17 -15
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/command_line_builder.rb +22 -18
- data/lib/aspera/environment.rb +3 -3
- data/lib/aspera/formatter_interface.rb +14 -0
- data/lib/aspera/hash_ext.rb +6 -0
- data/lib/aspera/log.rb +4 -3
- data/lib/aspera/markdown.rb +4 -1
- data/lib/aspera/oauth/factory.rb +1 -1
- data/lib/aspera/proxy_auto_config.rb +3 -0
- data/lib/aspera/rest.rb +1 -1
- data/lib/aspera/schema/IBM Aspera Faspex API-5.0-enhanced.yaml +62801 -0
- data/lib/aspera/schema/IBM Aspera on Cloud API-0.2.6-enhanced.yaml +8898 -0
- data/lib/aspera/schema/documentation.rb +107 -0
- data/lib/aspera/schema/reader.rb +75 -0
- data/lib/aspera/schema/registry.rb +63 -0
- data/lib/aspera/sync/conf.schema.yaml +0 -26
- data/lib/aspera/sync/operations.rb +9 -5
- data/lib/aspera/transfer/faux_file.rb +1 -1
- data/lib/aspera/transfer/resumer.rb +1 -1
- data/lib/aspera/transfer/spec.rb +3 -3
- data/lib/aspera/transfer/spec.schema.yaml +1 -1
- data/lib/aspera/uri_reader.rb +1 -1
- data/lib/aspera/yaml.rb +4 -2
- data.tar.gz.sig +0 -0
- metadata +9 -3
- metadata.gz.sig +0 -0
- data/lib/aspera/transfer/spec_doc.rb +0 -76
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bffa626f5f4970bf91f90b15e594315d3c81a1ed92c8eff2f9533f7faef71aab
|
|
4
|
+
data.tar.gz: 552c9b1d9225d3c1360f83d920bface08022314c7227bf36e7af439310e51c75
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2b655e7eaeee027e393fc7136c3f3b1a8d679a0825fb7d92baa6fa854d5cd68b11c01ecbeb9c32c457044f6eef3ae2bdbf22afa324b3d79643ec169aaad8f632
|
|
7
|
+
data.tar.gz: eeb29fc5c14cbe809e31ee229b79cd650632987d93af8a892001e49aea06aa68ace8f7f660345dc27edf0a1ad6350a85e285ba449d8cc39774f9f4c1d4832a8a
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- markdownlint-configure-file { "no-duplicate-heading": { "siblings_only": true } } -->
|
|
4
4
|
|
|
5
|
+
## 4.26.1
|
|
6
|
+
|
|
7
|
+
Released: 2026-06-11
|
|
8
|
+
|
|
9
|
+
### New Features
|
|
10
|
+
|
|
11
|
+
* `aoc`: Added new command `admin workspace shared_folder <workspace ID> node <shared folder ID>` to provide direct access to node operations from shared folders.
|
|
12
|
+
* **global**: Schema for Extended Value for option or command argument can now be retrieved using the special value `help` (e.g., `--ts=help` or `package send help`). Those are generated from JSON schema descriptions.
|
|
13
|
+
* **doc**: Some tables in documentation are now generated from JSON schema descriptions.
|
|
14
|
+
|
|
15
|
+
### Issues Fixed
|
|
16
|
+
|
|
17
|
+
* **global**: Resolved issue where supported enumerated values were not properly listed when no value was provided (e.g., for command parameters).
|
|
18
|
+
|
|
5
19
|
## 4.26.0
|
|
6
20
|
|
|
7
21
|
Released: 2026-05-28
|
|
@@ -17,7 +31,7 @@ Released: 2026-05-28
|
|
|
17
31
|
* `aoc`: Support selection of workspace using percent selectors: `%name:` and `%id:`.
|
|
18
32
|
* **global**: Added download URLs for `transferd` 1.1.8.
|
|
19
33
|
* **global**: New Extended Value modifier: `s` converts to `String`.
|
|
20
|
-
* **global**: Parameter `str_lst_sep`
|
|
34
|
+
* **global**: Parameter `str_lst_sep` of option `table_style` allows setting separator for list of strings.
|
|
21
35
|
|
|
22
36
|
### Issues Fixed
|
|
23
37
|
|
|
@@ -57,7 +71,7 @@ Released: 2026-03-04
|
|
|
57
71
|
|
|
58
72
|
### New Features
|
|
59
73
|
|
|
60
|
-
* **
|
|
74
|
+
* **global**: If `@:` is used, then marker `END` optionally marks the end of collected arguments.
|
|
61
75
|
* `format`: `display` defaults to `info` only if `format` is set to `table`, else defaults to `data`.
|
|
62
76
|
* `node`: Parameter `accept_v4` of option `node_api` (boolean, defaults to `true`) allows using gen4 browsing with `Accept-Version: 4.0` for best performance when there are thousands of files.
|
|
63
77
|
|
|
@@ -440,7 +454,7 @@ Released: 2024-07-13
|
|
|
440
454
|
|
|
441
455
|
### Breaking Changes
|
|
442
456
|
|
|
443
|
-
* `config`: Command `remote_certificate` now takes a
|
|
457
|
+
* `config`: Command `remote_certificate` now takes a command.
|
|
444
458
|
* **global**: Moved a few internal classes in new/renamed modules.
|
|
445
459
|
* **global**: Deprecated pseudo transfer specification parameters starting with `EX_`:
|
|
446
460
|
* `EX_ssh_key_paths`: Use spec `ssh_private_key` or option `transfer_info={"ascp_args":["-i","..."]}`
|
data/lib/aspera/api/aoc.rb
CHANGED
|
@@ -362,6 +362,7 @@ module Aspera
|
|
|
362
362
|
end
|
|
363
363
|
end
|
|
364
364
|
|
|
365
|
+
# @param expected [Array<String>] Link types
|
|
365
366
|
def assert_public_link_types(expected)
|
|
366
367
|
Aspera.assert_values(public_link['purpose'], expected){'public link type'}
|
|
367
368
|
end
|
|
@@ -557,7 +558,7 @@ module Aspera
|
|
|
557
558
|
full_recipient_info = lookup_with_q(entity_type, value: short_recipient_info, query: {'workspace_id' => ws_id})
|
|
558
559
|
rescue EntityNotFound
|
|
559
560
|
# dropboxes cannot be created on the fly
|
|
560
|
-
Aspera.assert_values(entity_type,
|
|
561
|
+
Aspera.assert_values(entity_type, %w[contacts], type: Error){"No such shared inbox in workspace #{ws_id}"}
|
|
561
562
|
# unknown user: create it as external user
|
|
562
563
|
full_recipient_info = create('contacts', {
|
|
563
564
|
'current_workspace_id' => ws_id,
|
data/lib/aspera/api/node.rb
CHANGED
|
@@ -165,7 +165,7 @@ module Aspera
|
|
|
165
165
|
items = scope.split(Scope::SEPARATOR, 2)
|
|
166
166
|
Aspera.assert(items.length.eql?(2)){"invalid scope: #{scope}"}
|
|
167
167
|
Aspera.assert(items[0].start_with?(Scope::NODE_PREFIX)){"invalid scope: #{scope}"}
|
|
168
|
-
return {access_key: items[0]
|
|
168
|
+
return {access_key: items[0].delete_prefix(Scope::NODE_PREFIX), scope: items[1]}
|
|
169
169
|
end
|
|
170
170
|
|
|
171
171
|
# Create an Aspera Node bearer token
|
|
@@ -540,7 +540,7 @@ module Aspera
|
|
|
540
540
|
else
|
|
541
541
|
transfer_spec.merge!(transport_params)
|
|
542
542
|
end
|
|
543
|
-
Aspera.assert_values(transfer_spec['remote_user'], Transfer::Spec::ACCESS_KEY_TRANSFER_USER, type: :warn){'transfer user'}
|
|
543
|
+
Aspera.assert_values(transfer_spec['remote_user'], [Transfer::Spec::ACCESS_KEY_TRANSFER_USER], type: :warn){'transfer user'}
|
|
544
544
|
return transfer_spec
|
|
545
545
|
end
|
|
546
546
|
|
|
@@ -60,7 +60,7 @@ module Aspera
|
|
|
60
60
|
Aspera.assert(!ascp_location.empty?){'ascp location cannot be empty: check your config file'}
|
|
61
61
|
folder =
|
|
62
62
|
if ascp_location.start_with?(USE_PRODUCT_PREFIX)
|
|
63
|
-
product_name = ascp_location
|
|
63
|
+
product_name = ascp_location.delete_prefix(USE_PRODUCT_PREFIX)
|
|
64
64
|
if product_name.eql?(FIRST_FOUND)
|
|
65
65
|
pl = installed_products.first
|
|
66
66
|
raise "No Aspera transfer module or SDK found.\nRefer to the manual or install SDK with command:\nascli conf transferd install" if pl.nil?
|
|
@@ -113,7 +113,7 @@ module Aspera
|
|
|
113
113
|
file = File.join(File.dirname(file), Environment.instance.exe_file(k.to_s)) unless k.eql?(:transferd)
|
|
114
114
|
when :ssh_private_dsa, :ssh_private_rsa
|
|
115
115
|
# assume last 3 letters are type
|
|
116
|
-
type = k.to_s[-3
|
|
116
|
+
type = k.to_s[-3..].to_sym
|
|
117
117
|
file = check_or_create_sdk_file("aspera_bypass_#{type}.pem"){DataRepository.instance.item(type)}
|
|
118
118
|
when :aspera_license
|
|
119
119
|
file = check_or_create_sdk_file('aspera-license'){DataRepository.instance.item(:license)}
|
|
@@ -243,7 +243,9 @@ module Aspera
|
|
|
243
243
|
end
|
|
244
244
|
|
|
245
245
|
# @param sdk_archive_path [String] path to SDK archive
|
|
246
|
-
# @
|
|
246
|
+
# @yieldparam entry_name [String] File path in archive
|
|
247
|
+
# @yieldparam entry_stream [IO, Gem::Package::TarReader::Entry] Data stream
|
|
248
|
+
# @yieldparam link_target [String, nil] Link target if symlink, nil otherwise
|
|
247
249
|
def extract_archive_files(sdk_archive_path)
|
|
248
250
|
Aspera.assert(block_given?){'missing block'}
|
|
249
251
|
case sdk_archive_path
|
|
@@ -281,7 +283,8 @@ module Aspera
|
|
|
281
283
|
# @param url [nil, String] URL to SDK archive, if nil: default url for version
|
|
282
284
|
# @param version [nil, String] Specific version, if nil: latest version
|
|
283
285
|
# @param backup [Boolean] If destination folder exists, then rename
|
|
284
|
-
# @
|
|
286
|
+
# @yieldparam entry_name [String] File path from archive
|
|
287
|
+
# @yieldreturn [String, nil] Destination sub folder (end with /) or file, or nil to not extract
|
|
285
288
|
# @return [Array] name, ascp version (from execution), folder
|
|
286
289
|
def install_sdk(folder:, url: nil, version: nil, backup: true)
|
|
287
290
|
url ||= sdk_url_for_platform(version: version)
|
data/lib/aspera/assert.rb
CHANGED
|
@@ -20,21 +20,24 @@ module Aspera
|
|
|
20
20
|
class << self
|
|
21
21
|
# Replaces `raise` in assertion
|
|
22
22
|
# Allows sending exception, or just error log, when type is `:error`
|
|
23
|
-
# @param type [Exception,Symbol] Send to log if symbol, else raise exception
|
|
23
|
+
# @param type [Exception, Symbol] Send to log if symbol, else raise exception
|
|
24
24
|
# @param message [String] Message for error.
|
|
25
|
+
# @raise [Exception]
|
|
26
|
+
# @return [nil]
|
|
25
27
|
def report_error(type, message)
|
|
26
28
|
if type.is_a?(Symbol)
|
|
27
29
|
Log.log.send(type, message)
|
|
28
30
|
else
|
|
29
31
|
raise type, message
|
|
30
32
|
end
|
|
33
|
+
nil
|
|
31
34
|
end
|
|
32
35
|
|
|
33
36
|
# Assert that a condition is true, else raise exception
|
|
34
37
|
# @param assertion [TrueClass, FalseClass] Must be true
|
|
35
|
-
# @param info [String,nil] Fixed message in case assert fails, else use
|
|
38
|
+
# @param info [String,nil] Fixed message in case assert fails, else use block
|
|
36
39
|
# @param type [Exception,Symbol] Exception to raise, or Symbol for Log.log
|
|
37
|
-
# @
|
|
40
|
+
# @yieldreturn [String] A string that describes the problem for complex messages
|
|
38
41
|
# The block is executed in the context of the Aspera module
|
|
39
42
|
def assert(assertion, info = nil, type: AssertError)
|
|
40
43
|
raise InternalError, 'bad assert: both info and block given' unless info.nil? || !block_given?
|
|
@@ -50,18 +53,18 @@ module Aspera
|
|
|
50
53
|
# @param value [Object] The value to check
|
|
51
54
|
# @param classes [Class, Array] The expected type(s)
|
|
52
55
|
# @param type [Exception,Symbol] Exception to raise, or Symbol for Log.log
|
|
53
|
-
# @
|
|
56
|
+
# @yieldreturn [String] Additional description to prepend to the error message
|
|
54
57
|
def assert_type(value, *classes, type: AssertError)
|
|
55
|
-
assert(classes.any?{ |k| value.is_a?(k)}, type: type){"#{"#{yield}: " if block_given?}expecting #{classes.join(', ')}, but have (#{value.class})#{value.inspect}"}
|
|
58
|
+
assert(classes.any?{ |k| value.is_a?(k)}, type: type){"#{"#{yield}: " if block_given?}expecting type #{classes.join(', ')}, but have (#{value.class})#{value.inspect}"}
|
|
56
59
|
end
|
|
57
60
|
|
|
58
61
|
# Assert that all value of array are of the same specified type.
|
|
59
62
|
# @param array [Array] The array to check
|
|
60
63
|
# @param klass [Class] The expected type of elements
|
|
61
64
|
# @param type [Exception,Symbol] Exception to raise, or Symbol for Log.log
|
|
62
|
-
# @
|
|
65
|
+
# @yieldreturn [String] Additional description to prepend to the error message
|
|
63
66
|
def assert_array_all(array, klass, type: AssertError)
|
|
64
|
-
assert_type(array, Array, type:
|
|
67
|
+
assert_type(array, Array, type: AssertError){'array'}
|
|
65
68
|
assert(array.all?(klass), type: type){"#{"#{yield}: " if block_given?}expecting all as #{klass}, but have #{array.map(&:class).uniq}"}
|
|
66
69
|
end
|
|
67
70
|
|
|
@@ -70,19 +73,20 @@ module Aspera
|
|
|
70
73
|
# @param key_class [Class] The expected type of keys (or nil)
|
|
71
74
|
# @param value_class [Class] The expected type of values (or nil)
|
|
72
75
|
# @param type [Exception,Symbol] Exception to raise, or Symbol for Log.log
|
|
73
|
-
# @
|
|
76
|
+
# @yieldreturn [String] Additional description to prepend to the error message
|
|
74
77
|
def assert_hash_all(hash, key_class, value_class, type: AssertError)
|
|
75
|
-
assert_type(hash, Hash, type:
|
|
76
|
-
assert_array_all(hash.keys, key_class, type:
|
|
77
|
-
assert_array_all(hash.values, value_class, type:
|
|
78
|
+
assert_type(hash, Hash, type: AssertError){'hash'}
|
|
79
|
+
assert_array_all(hash.keys, key_class, type: type){"#{"#{yield}: " if block_given?}keys"} unless key_class.nil?
|
|
80
|
+
assert_array_all(hash.values, value_class, type: type){"#{"#{yield}: " if block_given?}values"} unless value_class.nil?
|
|
78
81
|
end
|
|
79
82
|
|
|
80
83
|
# Assert that value is one of the given values
|
|
81
84
|
# @param value [Object] Value to check
|
|
82
85
|
# @param values [Array] Accepted values
|
|
83
86
|
# @param type [Exception,Symbol] Exception to raise, or Symbol for Log.log
|
|
84
|
-
# @
|
|
87
|
+
# @yieldreturn [String] Additional description to prepend to the error message
|
|
85
88
|
def assert_values(value, values, type: AssertError)
|
|
89
|
+
assert_type(values, Array, type: AssertError){'values'}
|
|
86
90
|
assert(values.include?(value), type: type) do
|
|
87
91
|
val_list = values.inspect
|
|
88
92
|
val_list = "one of #{val_list}" if values.is_a?(Array)
|
|
@@ -93,7 +97,7 @@ module Aspera
|
|
|
93
97
|
# The value is not one of the expected values
|
|
94
98
|
# @param value [Object] The wrong value
|
|
95
99
|
# @param type [Exception,Symbol] Exception to raise, or Symbol for Log.log
|
|
96
|
-
# @
|
|
100
|
+
# @yieldreturn [String] Additional description to prepend to the error message
|
|
97
101
|
def error_unexpected_value(value, type: InternalError)
|
|
98
102
|
report_error(type, "#{"#{yield}: " if block_given?}unexpected value: #{value.inspect}")
|
|
99
103
|
end
|
|
@@ -15,6 +15,10 @@ require 'singleton'
|
|
|
15
15
|
module Aspera
|
|
16
16
|
module Cli
|
|
17
17
|
# Command line extended values
|
|
18
|
+
#
|
|
19
|
+
# @!method self.instance
|
|
20
|
+
# Returns the singleton instance of ExtendedValue
|
|
21
|
+
# @return [ExtendedValue] the singleton instance
|
|
18
22
|
class ExtendedValue
|
|
19
23
|
include Singleton
|
|
20
24
|
|
|
@@ -91,7 +95,7 @@ module Aspera
|
|
|
91
95
|
uri: lambda{ |i| UriReader.read(i)},
|
|
92
96
|
json: lambda{ |i| ExtendedValue.JSON_parse(i)},
|
|
93
97
|
lines: lambda{ |i| i.split("\n")},
|
|
94
|
-
list: lambda{ |i| i[1
|
|
98
|
+
list: lambda{ |i| i[1..].split(i[0])},
|
|
95
99
|
none: lambda{ |i| ExtendedValue.assert_no_value(i, :none); nil}, # rubocop:disable Style/Semicolon
|
|
96
100
|
path: lambda{ |i| File.expand_path(i)},
|
|
97
101
|
re: lambda{ |i| Regexp.new(i, Regexp::MULTILINE)},
|
|
@@ -145,7 +149,7 @@ module Aspera
|
|
|
145
149
|
# @param value [String] the value to parse
|
|
146
150
|
# @param context [String] Context in which evaluation is done
|
|
147
151
|
# @param allowed [Array<Class>,NilClass] Expected types
|
|
148
|
-
# @return [
|
|
152
|
+
# @return [String, Integer, Array, Hash, Boolean] Evaluated value
|
|
149
153
|
def evaluate(value, context:, allowed: nil)
|
|
150
154
|
return value unless value.is_a?(String)
|
|
151
155
|
Aspera.assert_array_all(allowed, Class) unless allowed.nil?
|
data/lib/aspera/cli/formatter.rb
CHANGED
|
@@ -9,6 +9,7 @@ require 'aspera/log'
|
|
|
9
9
|
require 'aspera/assert'
|
|
10
10
|
require 'aspera/markdown'
|
|
11
11
|
require 'aspera/dot_container'
|
|
12
|
+
require 'aspera/formatter_interface'
|
|
12
13
|
require 'terminal-table'
|
|
13
14
|
require 'tty-spinner'
|
|
14
15
|
require 'yaml'
|
|
@@ -18,6 +19,60 @@ require 'word_wrap'
|
|
|
18
19
|
|
|
19
20
|
module Aspera
|
|
20
21
|
module Cli
|
|
22
|
+
# Terminal formatter with ANSI colors and Unicode support
|
|
23
|
+
# @see FormatterInterface
|
|
24
|
+
# @see MarkdownFormatter (in build/lib/doc_helper.rb)
|
|
25
|
+
module TerminalFormatter
|
|
26
|
+
include FormatterInterface
|
|
27
|
+
|
|
28
|
+
# Format boolean with colored symbol (✓/✗ or Y/ )
|
|
29
|
+
def tick(yes)
|
|
30
|
+
result =
|
|
31
|
+
if Environment.terminal_supports_unicode?
|
|
32
|
+
yes ? "\u2713" : "\u2717"
|
|
33
|
+
else
|
|
34
|
+
yes ? 'Y' : ' '
|
|
35
|
+
end
|
|
36
|
+
return result.green if yes
|
|
37
|
+
return result.red
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Format special values with colors (dim for empty, reverse for others)
|
|
41
|
+
def special_format(what)
|
|
42
|
+
result = "<#{what}>"
|
|
43
|
+
return %w[null empty].any?{ |s| what.include?(s)} ? result.dim : result.reverse_color
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Prepare table row for terminal display (word wrap arrays)
|
|
47
|
+
def check_row(row)
|
|
48
|
+
row.each_key do |k|
|
|
49
|
+
row[k] = row[k].map{ |i| WordWrap.ww(i.to_s, 120).chomp}.join("\n") if row[k].is_a?(Array)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Convert Markdown to terminal format (**bold** -> blue, `code` -> bold)
|
|
54
|
+
# @param match [MatchData, String]
|
|
55
|
+
def markdown_text(match)
|
|
56
|
+
if match.is_a?(String)
|
|
57
|
+
match = Markdown::FORMATS.match(match)
|
|
58
|
+
Aspera.assert(match)
|
|
59
|
+
end
|
|
60
|
+
Aspera.assert_type(match, MatchData)
|
|
61
|
+
if match[:entity]
|
|
62
|
+
Aspera.assert_values(match[:entity], %w[bsol])
|
|
63
|
+
'\\'
|
|
64
|
+
elsif match[:bold]
|
|
65
|
+
match[:bold].to_s.blue
|
|
66
|
+
elsif match[:code]
|
|
67
|
+
match[:code].to_s.bold
|
|
68
|
+
else
|
|
69
|
+
Aspera.error_unexpected_value(match.to_s)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
module_function :tick, :special_format, :check_row, :markdown_text
|
|
74
|
+
end
|
|
75
|
+
|
|
21
76
|
# Take care of CLI output on terminal
|
|
22
77
|
class Formatter
|
|
23
78
|
# remove a fields from the list
|
|
@@ -34,56 +89,6 @@ module Aspera
|
|
|
34
89
|
private_constant :FIELDS_LESS, :DISPLAY_FORMATS, :DISPLAY_LEVELS, :SINGLE_OBJECT_COLUMN_NAMES, :STR_LST_SEP_VERT
|
|
35
90
|
|
|
36
91
|
class << self
|
|
37
|
-
# nicer display for boolean
|
|
38
|
-
# used by `spec_doc`
|
|
39
|
-
def tick(yes)
|
|
40
|
-
result =
|
|
41
|
-
if Environment.terminal_supports_unicode?
|
|
42
|
-
yes ? "\u2713" : "\u2717"
|
|
43
|
-
else
|
|
44
|
-
yes ? 'Y' : ' '
|
|
45
|
-
end
|
|
46
|
-
return result.green if yes
|
|
47
|
-
return result.red
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# Highlight special values on terminal
|
|
51
|
-
# empty values are dim
|
|
52
|
-
# used by `spec_doc`
|
|
53
|
-
def special_format(what)
|
|
54
|
-
result = "<#{what}>"
|
|
55
|
-
return %w[null empty].any?{ |s| what.include?(s)} ? result.dim : result.reverse_color
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# For transfer spec table, build line for display in terminal
|
|
59
|
-
# used by `spec_doc`
|
|
60
|
-
def check_row(row)
|
|
61
|
-
row.each_key do |k|
|
|
62
|
-
row[k] = row[k].map{ |i| WordWrap.ww(i.to_s, 120).chomp}.join("\n") if row[k].is_a?(Array)
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# Give Markdown String, or matched data, return formatted string for terminal
|
|
67
|
-
# used by `spec_doc`
|
|
68
|
-
# @param match [MatchData,String]
|
|
69
|
-
def markdown_text(match)
|
|
70
|
-
if match.is_a?(String)
|
|
71
|
-
match = Markdown::FORMATS.match(match)
|
|
72
|
-
Aspera.assert(match)
|
|
73
|
-
end
|
|
74
|
-
Aspera.assert_type(match, MatchData)
|
|
75
|
-
if match[:entity]
|
|
76
|
-
Aspera.assert_values(match[:entity], 'bsol')
|
|
77
|
-
'\\'
|
|
78
|
-
elsif match[:bold]
|
|
79
|
-
match[:bold].to_s.blue
|
|
80
|
-
elsif match[:code]
|
|
81
|
-
match[:code].to_s.bold
|
|
82
|
-
else
|
|
83
|
-
Aspera.error_unexpected_value(match.to_s)
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
92
|
# Replace special values with a readable version on terminal
|
|
88
93
|
def replace_specific_for_terminal(input_hash, string_list_separator)
|
|
89
94
|
hash_to_process = [input_hash]
|
|
@@ -92,14 +97,14 @@ module Aspera
|
|
|
92
97
|
current.each do |key, value|
|
|
93
98
|
case value
|
|
94
99
|
when NilClass
|
|
95
|
-
current[key] = special_format('null')
|
|
100
|
+
current[key] = TerminalFormatter.special_format('null')
|
|
96
101
|
when String
|
|
97
|
-
current[key] = special_format('empty string') if value.empty?
|
|
102
|
+
current[key] = TerminalFormatter.special_format('empty string') if value.empty?
|
|
98
103
|
when Proc
|
|
99
|
-
current[key] = special_format('lambda')
|
|
104
|
+
current[key] = TerminalFormatter.special_format('lambda')
|
|
100
105
|
when Array
|
|
101
106
|
if value.empty?
|
|
102
|
-
current[key] = special_format('empty list')
|
|
107
|
+
current[key] = TerminalFormatter.special_format('empty list')
|
|
103
108
|
elsif value.all?(String)
|
|
104
109
|
current[key] = value.join(string_list_separator)
|
|
105
110
|
else
|
|
@@ -109,7 +114,7 @@ module Aspera
|
|
|
109
114
|
end
|
|
110
115
|
when Hash
|
|
111
116
|
if value.empty?
|
|
112
|
-
current[key] = special_format('empty dict')
|
|
117
|
+
current[key] = TerminalFormatter.special_format('empty dict')
|
|
113
118
|
else
|
|
114
119
|
hash_to_process.push(value)
|
|
115
120
|
end
|
|
@@ -240,7 +245,7 @@ module Aspera
|
|
|
240
245
|
!@options[:show_secrets] && !@options[:display].eql?(:data)
|
|
241
246
|
end
|
|
242
247
|
|
|
243
|
-
#
|
|
248
|
+
# Hides secrets in Hash or Array
|
|
244
249
|
def hide_secrets(data)
|
|
245
250
|
SecretHider.instance.deep_remove_secret(data) if hide_secrets?
|
|
246
251
|
end
|
|
@@ -316,7 +321,7 @@ module Aspera
|
|
|
316
321
|
# :single_object is a Hash, where key=column name
|
|
317
322
|
Aspera.assert_type(data, Hash){'result'}
|
|
318
323
|
if data.empty?
|
|
319
|
-
display_message(:data,
|
|
324
|
+
display_message(:data, TerminalFormatter.special_format('empty dict'))
|
|
320
325
|
else
|
|
321
326
|
data = DotContainer.new(data).to_dotted if @options[:flat_hash]
|
|
322
327
|
display_table([data], compute_fields([data], fields), single: true)
|
|
@@ -334,7 +339,7 @@ module Aspera
|
|
|
334
339
|
Log.log.debug('no result expected')
|
|
335
340
|
return
|
|
336
341
|
end
|
|
337
|
-
display_message(:info,
|
|
342
|
+
display_message(:info, TerminalFormatter.special_format(data.to_s))
|
|
338
343
|
return
|
|
339
344
|
when :status # no table
|
|
340
345
|
# :status displays a simple message
|
|
@@ -379,7 +384,7 @@ module Aspera
|
|
|
379
384
|
removal = false
|
|
380
385
|
if item[0].eql?(FIELDS_LESS)
|
|
381
386
|
removal = true
|
|
382
|
-
item = item
|
|
387
|
+
item = item.delete_prefix(FIELDS_LESS)
|
|
383
388
|
end
|
|
384
389
|
case item
|
|
385
390
|
when SpecialValues::ALL
|
|
@@ -439,7 +444,7 @@ module Aspera
|
|
|
439
444
|
Aspera.assert_array_all(fields, String)
|
|
440
445
|
if object_array.empty?
|
|
441
446
|
# no display for csv
|
|
442
|
-
display_message(:info,
|
|
447
|
+
display_message(:info, TerminalFormatter.special_format('empty')) if @options[:format].eql?(:table)
|
|
443
448
|
return
|
|
444
449
|
end
|
|
445
450
|
filter_columns_on_select(object_array)
|