aspera-cli 4.24.1 → 4.25.0.pre
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 +1064 -745
- data/CONTRIBUTING.md +43 -100
- data/README.md +1281 -720
- data/bin/ascli +20 -1
- data/bin/asession +23 -27
- data/lib/aspera/agent/base.rb +10 -21
- data/lib/aspera/agent/connect.rb +2 -3
- data/lib/aspera/agent/desktop.rb +2 -2
- data/lib/aspera/agent/direct.rb +49 -32
- data/lib/aspera/agent/factory.rb +31 -0
- data/lib/aspera/api/aoc.rb +134 -76
- data/lib/aspera/api/cos_node.rb +3 -2
- data/lib/aspera/api/faspex.rb +213 -0
- data/lib/aspera/api/node.rb +107 -94
- data/lib/aspera/ascmd.rb +1 -2
- data/lib/aspera/ascp/installation.rb +73 -58
- data/lib/aspera/ascp/management.rb +119 -23
- data/lib/aspera/assert.rb +39 -11
- data/lib/aspera/cli/error.rb +4 -2
- data/lib/aspera/cli/extended_value.rb +91 -67
- data/lib/aspera/cli/formatter.rb +62 -27
- data/lib/aspera/cli/hints.rb +8 -0
- data/lib/aspera/cli/info.rb +4 -4
- data/lib/aspera/cli/main.rb +76 -84
- data/lib/aspera/cli/manager.rb +352 -248
- data/lib/aspera/cli/plugins/alee.rb +5 -4
- data/lib/aspera/cli/plugins/aoc.rb +175 -195
- data/lib/aspera/cli/plugins/ats.rb +4 -4
- data/lib/aspera/cli/plugins/base.rb +343 -0
- data/lib/aspera/cli/plugins/basic_auth.rb +45 -0
- data/lib/aspera/cli/plugins/config.rb +283 -269
- data/lib/aspera/cli/plugins/console.rb +27 -22
- data/lib/aspera/cli/plugins/cos.rb +3 -3
- data/lib/aspera/cli/plugins/factory.rb +78 -0
- data/lib/aspera/cli/plugins/faspex.rb +49 -46
- data/lib/aspera/cli/plugins/faspex5.rb +113 -225
- data/lib/aspera/cli/plugins/faspio.rb +19 -18
- data/lib/aspera/cli/plugins/httpgw.rb +14 -13
- data/lib/aspera/cli/plugins/node.rb +162 -149
- data/lib/aspera/cli/plugins/oauth.rb +48 -0
- data/lib/aspera/cli/plugins/orchestrator.rb +129 -45
- data/lib/aspera/cli/plugins/preview.rb +30 -50
- data/lib/aspera/cli/plugins/server.rb +21 -21
- data/lib/aspera/cli/plugins/shares.rb +45 -47
- data/lib/aspera/cli/sync_actions.rb +50 -39
- data/lib/aspera/cli/transfer_agent.rb +35 -49
- data/lib/aspera/cli/transfer_progress.rb +6 -6
- data/lib/aspera/cli/version.rb +3 -3
- data/lib/aspera/cli/wizard.rb +70 -55
- data/lib/aspera/colors.rb +6 -0
- data/lib/aspera/command_line_builder.rb +59 -61
- data/lib/aspera/command_line_converter.rb +2 -1
- data/lib/aspera/coverage.rb +2 -2
- data/lib/aspera/data_repository.rb +1 -1
- data/lib/aspera/environment.rb +51 -41
- data/lib/aspera/faspex_gw.rb +7 -5
- data/lib/aspera/faspex_postproc.rb +1 -1
- data/lib/aspera/keychain/factory.rb +1 -2
- data/lib/aspera/keychain/macos_security.rb +1 -1
- data/lib/aspera/log.rb +37 -9
- data/lib/aspera/markdown.rb +31 -0
- data/lib/aspera/nagios.rb +7 -6
- data/lib/aspera/oauth/base.rb +25 -28
- data/lib/aspera/oauth/factory.rb +9 -9
- data/lib/aspera/oauth/url_json.rb +2 -1
- data/lib/aspera/oauth/web.rb +2 -2
- data/lib/aspera/preview/file_types.rb +23 -37
- data/lib/aspera/products/connect.rb +7 -6
- data/lib/aspera/products/desktop.rb +1 -4
- data/lib/aspera/products/other.rb +9 -1
- data/lib/aspera/products/transferd.rb +0 -1
- data/lib/aspera/rest.rb +168 -113
- data/lib/aspera/rest_error_analyzer.rb +4 -4
- data/lib/aspera/ssh.rb +7 -4
- data/lib/aspera/ssl.rb +41 -0
- data/lib/aspera/sync/args.schema.yaml +46 -3
- data/lib/aspera/sync/conf.schema.yaml +307 -123
- data/lib/aspera/sync/database.rb +2 -1
- data/lib/aspera/sync/operations.rb +135 -79
- data/lib/aspera/temp_file_manager.rb +17 -5
- data/lib/aspera/transfer/error.rb +16 -7
- data/lib/aspera/transfer/parameters.rb +35 -22
- data/lib/aspera/transfer/resumer.rb +74 -0
- data/lib/aspera/transfer/spec.rb +5 -5
- data/lib/aspera/transfer/spec.schema.yaml +170 -59
- data/lib/aspera/transfer/spec_doc.rb +49 -43
- data/lib/aspera/uri_reader.rb +2 -2
- data/lib/aspera/web_auth.rb +6 -6
- data/lib/transferd_pb.rb +2 -2
- data.tar.gz.sig +0 -0
- metadata +26 -11
- metadata.gz.sig +0 -0
- data/lib/aspera/cli/basic_auth_plugin.rb +0 -43
- data/lib/aspera/cli/plugin.rb +0 -333
- data/lib/aspera/cli/plugin_factory.rb +0 -81
- data/lib/aspera/resumer.rb +0 -77
- data/lib/aspera/transfer/error_info.rb +0 -91
|
@@ -13,23 +13,15 @@ require 'singleton'
|
|
|
13
13
|
|
|
14
14
|
module Aspera
|
|
15
15
|
module Cli
|
|
16
|
-
#
|
|
16
|
+
# Command line extended values
|
|
17
17
|
class ExtendedValue
|
|
18
18
|
include Singleton
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
MARKER_IN_END = '@'
|
|
23
|
-
|
|
24
|
-
# special handlers stop processing of handlers on right
|
|
25
|
-
# extend includes processing of other handlers in itself
|
|
26
|
-
# val keeps the value intact
|
|
27
|
-
SPECIAL_HANDLERS = %i[extend val].freeze
|
|
28
|
-
|
|
29
|
-
private_constant :MARKER_START, :MARKER_END, :MARKER_IN_END, :SPECIAL_HANDLERS
|
|
20
|
+
# First is default
|
|
21
|
+
DEFAULT_DECODERS = %i[none json ruby yaml]
|
|
30
22
|
|
|
31
23
|
class << self
|
|
32
|
-
#
|
|
24
|
+
# Decode comma separated table text
|
|
33
25
|
def decode_csvt(value)
|
|
34
26
|
col_titles = nil
|
|
35
27
|
hash_array = []
|
|
@@ -45,16 +37,41 @@ module Aspera
|
|
|
45
37
|
return hash_array
|
|
46
38
|
end
|
|
47
39
|
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
# JSON Parser, with more information on error location
|
|
41
|
+
# extract a context: 10 chars before and after the error on the given line and display a pointer "^"
|
|
42
|
+
# :reek:UncommunicativeMethodName
|
|
43
|
+
def JSON_parse(value) # rubocop:disable Naming/MethodName
|
|
44
|
+
JSON.parse(value)
|
|
45
|
+
rescue JSON::ParserError => e
|
|
46
|
+
m = /at line (\d+) column (\d+)/.match(e.message)
|
|
47
|
+
raise if m.nil?
|
|
48
|
+
line = m[1].to_i - 1
|
|
49
|
+
column = m[2].to_i - 1
|
|
50
|
+
lines = value.lines
|
|
51
|
+
raise if line >= lines.size
|
|
52
|
+
error_line = lines[line].chomp
|
|
53
|
+
context_col_beg = [column - 10, 0].max
|
|
54
|
+
context_col_end = [column + 10, error_line.length].min
|
|
55
|
+
context = error_line[context_col_beg...context_col_end]
|
|
56
|
+
cursor_pos = column - context_col_beg
|
|
57
|
+
pointer = ' ' * cursor_pos + '^'.blink
|
|
58
|
+
raise BadArgument, "#{e.message}\n#{context}\n#{pointer}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# The value must be empty
|
|
62
|
+
# @param value [String] The value as parameter
|
|
63
|
+
# @param ext_type [Symbol] The method of extended value
|
|
64
|
+
def assert_no_value(value, ext_type)
|
|
65
|
+
Aspera.assert(value.empty?, type: BadArgument){"no value allowed for extended value type: #{ext_type}"}
|
|
50
66
|
end
|
|
51
67
|
end
|
|
52
68
|
|
|
53
69
|
private
|
|
54
70
|
|
|
55
71
|
def initialize
|
|
56
|
-
#
|
|
57
|
-
#
|
|
72
|
+
# Base handlers
|
|
73
|
+
# Other handlers can be set using `on`
|
|
74
|
+
# e.g. `preset` is reader in config plugin
|
|
58
75
|
@handlers = {
|
|
59
76
|
val: lambda{ |i| i},
|
|
60
77
|
base64: lambda{ |i| Base64.decode64(i)},
|
|
@@ -62,7 +79,7 @@ module Aspera
|
|
|
62
79
|
env: lambda{ |i| ENV.fetch(i, nil)},
|
|
63
80
|
file: lambda{ |i| File.read(File.expand_path(i))},
|
|
64
81
|
uri: lambda{ |i| UriReader.read(i)},
|
|
65
|
-
json: lambda{ |i| JSON_parse(i)},
|
|
82
|
+
json: lambda{ |i| ExtendedValue.JSON_parse(i)},
|
|
66
83
|
lines: lambda{ |i| i.split("\n")},
|
|
67
84
|
list: lambda{ |i| i[1..-1].split(i[0])},
|
|
68
85
|
none: lambda{ |i| ExtendedValue.assert_no_value(i, :none); nil}, # rubocop:disable Style/Semicolon
|
|
@@ -74,63 +91,60 @@ module Aspera
|
|
|
74
91
|
stdbin: lambda{ |i| ExtendedValue.assert_no_value(i, :stdbin); $stdin.binmode.read}, # rubocop:disable Style/Semicolon
|
|
75
92
|
yaml: lambda{ |i| YAML.load(i)},
|
|
76
93
|
zlib: lambda{ |i| Zlib::Inflate.inflate(i)},
|
|
77
|
-
extend: lambda{ |i| ExtendedValue.instance.
|
|
94
|
+
extend: lambda{ |i| ExtendedValue.instance.evaluate_extend(i)}
|
|
78
95
|
}
|
|
96
|
+
@regex_single = nil
|
|
97
|
+
@regex_extend = nil
|
|
79
98
|
@default_decoder = nil
|
|
99
|
+
update_regex
|
|
80
100
|
end
|
|
81
101
|
|
|
82
|
-
# Regex to match an extended value
|
|
83
|
-
def
|
|
84
|
-
"#{MARKER_START}(#{modifiers.join('|')})#{MARKER_END}"
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
# JSON Parser, with more information on error location
|
|
88
|
-
# :reek:UncommunicativeMethodName
|
|
89
|
-
def JSON_parse(value) # rubocop:disable Naming/MethodName
|
|
90
|
-
JSON.parse(value)
|
|
91
|
-
rescue JSON::ParserError => e
|
|
92
|
-
m = /at line (\d+) column (\d+)/.match(e.message)
|
|
93
|
-
raise if m.nil?
|
|
94
|
-
line = m[1].to_i - 1
|
|
95
|
-
column = m[2].to_i - 1
|
|
96
|
-
lines = value.lines
|
|
97
|
-
raise if line >= lines.size
|
|
98
|
-
error_line = lines[line].chomp
|
|
99
|
-
context_col_beg = [column - 10, 0].max
|
|
100
|
-
context_col_end = [column + 10, error_line.length].min
|
|
101
|
-
context = error_line[context_col_beg...context_col_end]
|
|
102
|
-
cursor_pos = column - context_col_beg
|
|
103
|
-
pointer = ' ' * cursor_pos + '^'.blink
|
|
104
|
-
raise BadArgument, "#{e.message}\n#{context}\n#{pointer}"
|
|
102
|
+
# Update the Regex to match an extended value based on @handlers
|
|
103
|
+
def update_regex
|
|
104
|
+
handler_regex = "#{MARKER_START}(#{modifiers.join('|')})#{MARKER_END}"
|
|
105
|
+
@regex_single = Regexp.new("^#{handler_regex}(.*)$", Regexp::MULTILINE)
|
|
106
|
+
@regex_extend = Regexp.new("^(.*)#{handler_regex}([^#{MARKER_IN_END}]*)#{MARKER_IN_END}(.*)$", Regexp::MULTILINE)
|
|
105
107
|
end
|
|
106
108
|
|
|
107
109
|
public
|
|
108
110
|
|
|
111
|
+
attr_reader :default_decoder
|
|
112
|
+
|
|
109
113
|
def default_decoder=(value)
|
|
110
|
-
Log.log.debug{"
|
|
111
|
-
Aspera.
|
|
114
|
+
Log.log.debug{"Setting default decoder to (#{value.class}) #{value}"}
|
|
115
|
+
Aspera.assert_values(value, DEFAULT_DECODERS)
|
|
116
|
+
value = nil if value.eql?(:none)
|
|
112
117
|
@default_decoder = value
|
|
113
118
|
end
|
|
114
119
|
|
|
120
|
+
# List of Extended Value methods
|
|
115
121
|
def modifiers; @handlers.keys; end
|
|
116
122
|
|
|
117
|
-
#
|
|
118
|
-
def
|
|
119
|
-
Log.log.debug{"setting handler for #{name}"}
|
|
123
|
+
# Add a new handler
|
|
124
|
+
def on(name, &block)
|
|
120
125
|
Aspera.assert_type(name, Symbol){'name'}
|
|
121
|
-
|
|
126
|
+
Aspera.assert(block)
|
|
127
|
+
Log.log.debug{"Setting handler for #{name}"}
|
|
128
|
+
@handlers[name] = block
|
|
129
|
+
update_regex
|
|
122
130
|
end
|
|
123
131
|
|
|
124
|
-
#
|
|
125
|
-
#
|
|
126
|
-
#
|
|
127
|
-
# @param
|
|
128
|
-
|
|
132
|
+
# Parses a `String` value to extended value.
|
|
133
|
+
# If it is a String using supported extended value modifiers, then evaluate them.
|
|
134
|
+
# Other value types are returned as is.
|
|
135
|
+
# @param value [String] the value to parse
|
|
136
|
+
# @param context [String] Context in which evaluation is done
|
|
137
|
+
# @param allowed [Array<Class>,NilClass] Expected types
|
|
138
|
+
# @return [Object] Evaluated value
|
|
139
|
+
def evaluate(value, context:, allowed: nil)
|
|
129
140
|
return value unless value.is_a?(String)
|
|
130
|
-
|
|
131
|
-
#
|
|
141
|
+
Aspera.assert_array_all(allowed, Class) unless allowed.nil?
|
|
142
|
+
# use default decoder if not an extended value and expect complex types
|
|
143
|
+
using_default_decoder = allowed&.all?{ |t| DEFAULT_PARSER_TYPES.include?(t)} && !@regex_single.match?(value) && !@default_decoder.nil?
|
|
144
|
+
value = [MARKER_START, @default_decoder, MARKER_END, value].join if using_default_decoder
|
|
145
|
+
# First determine decoders, in reversed order
|
|
132
146
|
handlers_reversed = []
|
|
133
|
-
while (m = value.match(
|
|
147
|
+
while (m = value.match(@regex_single))
|
|
134
148
|
handler = m[1].to_sym
|
|
135
149
|
handlers_reversed.unshift(handler)
|
|
136
150
|
value = m[2]
|
|
@@ -139,27 +153,37 @@ module Aspera
|
|
|
139
153
|
Log.log.trace1{"evaluating: #{handlers_reversed}, value: #{value}"}
|
|
140
154
|
handlers_reversed.each do |handler|
|
|
141
155
|
value = @handlers[handler].call(value)
|
|
156
|
+
rescue => e
|
|
157
|
+
raise BadArgument, "Evaluation of #{handler} for #{context}: #{e.message}"
|
|
142
158
|
end
|
|
143
159
|
return value
|
|
144
160
|
end
|
|
145
161
|
|
|
146
|
-
#
|
|
147
|
-
#
|
|
148
|
-
def
|
|
149
|
-
|
|
150
|
-
return evaluate(value)
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
# find inner extended values
|
|
154
|
-
def evaluate_all(value)
|
|
155
|
-
regex = Regexp.new("^(.*)#{handler_regex_string}([^#{MARKER_IN_END}]*)#{MARKER_IN_END}(.*)$", Regexp::MULTILINE)
|
|
156
|
-
while (m = value.match(regex))
|
|
162
|
+
# Find inner extended values
|
|
163
|
+
# Only used in above lambda
|
|
164
|
+
def evaluate_extend(value)
|
|
165
|
+
while (m = value.match(@regex_extend))
|
|
157
166
|
sub_value = "@#{m[2]}:#{m[3]}"
|
|
158
167
|
Log.log.debug{"evaluating #{sub_value}"}
|
|
159
|
-
value = "#{m[1]}#{evaluate(sub_value)}#{m[4]}"
|
|
168
|
+
value = "#{m[1]}#{evaluate(sub_value, context: 'composite extended value')}#{m[4]}"
|
|
160
169
|
end
|
|
161
170
|
return value
|
|
162
171
|
end
|
|
172
|
+
# marker "@"
|
|
173
|
+
MARKER_START = '@'
|
|
174
|
+
# marker ":"
|
|
175
|
+
MARKER_END = ':'
|
|
176
|
+
# marker "@"
|
|
177
|
+
MARKER_IN_END = '@'
|
|
178
|
+
|
|
179
|
+
# Special handlers stop processing of handlers on right
|
|
180
|
+
# :extend includes processing of other handlers in itself
|
|
181
|
+
# :val keeps the value intact
|
|
182
|
+
SPECIAL_HANDLERS = %i[extend val].freeze
|
|
183
|
+
|
|
184
|
+
# Array and Hash types:
|
|
185
|
+
DEFAULT_PARSER_TYPES = [Array, Hash].freeze
|
|
186
|
+
private_constant :MARKER_START, :MARKER_END, :MARKER_IN_END, :SPECIAL_HANDLERS, :DEFAULT_PARSER_TYPES
|
|
163
187
|
end
|
|
164
188
|
end
|
|
165
189
|
end
|
data/lib/aspera/cli/formatter.rb
CHANGED
|
@@ -7,6 +7,7 @@ require 'aspera/secret_hider'
|
|
|
7
7
|
require 'aspera/environment'
|
|
8
8
|
require 'aspera/log'
|
|
9
9
|
require 'aspera/assert'
|
|
10
|
+
require 'aspera/markdown'
|
|
10
11
|
require 'terminal-table'
|
|
11
12
|
require 'tty-spinner'
|
|
12
13
|
require 'yaml'
|
|
@@ -64,11 +65,26 @@ module Aspera
|
|
|
64
65
|
end
|
|
65
66
|
|
|
66
67
|
# used by spec_doc
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
# @param match [MatchData,String]
|
|
69
|
+
def markdown(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
|
|
69
85
|
end
|
|
70
86
|
|
|
71
|
-
# replace empty values with a readable version
|
|
87
|
+
# replace empty values with a readable version on terminal
|
|
72
88
|
def enhance_display_values_hash(input_hash)
|
|
73
89
|
stack = [input_hash]
|
|
74
90
|
until stack.empty?
|
|
@@ -79,6 +95,8 @@ module Aspera
|
|
|
79
95
|
current[key] = special_format('null')
|
|
80
96
|
when String
|
|
81
97
|
current[key] = special_format('empty string') if value.empty?
|
|
98
|
+
when Proc
|
|
99
|
+
current[key] = special_format('lambda')
|
|
82
100
|
when Array
|
|
83
101
|
if value.empty?
|
|
84
102
|
current[key] = special_format('empty list')
|
|
@@ -98,30 +116,49 @@ module Aspera
|
|
|
98
116
|
end
|
|
99
117
|
end
|
|
100
118
|
|
|
119
|
+
# Given a list of string, display that list in a single cell
|
|
120
|
+
def list_to_string(list)
|
|
121
|
+
list.join(',')
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Build new prefix
|
|
125
|
+
def add_prefix(prefix, key)
|
|
126
|
+
[prefix, key].compact.join('.')
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Add elements of enumerator to the stack, in reverse order
|
|
130
|
+
def add_elements(stack, prefix, enum)
|
|
131
|
+
enum.reverse_each do |key, value|
|
|
132
|
+
stack.push([add_prefix(prefix, key), value])
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
101
136
|
# Flatten a Hash into single level hash
|
|
102
137
|
def flatten_hash(input)
|
|
103
138
|
Aspera.assert_type(input, Hash)
|
|
104
139
|
return input if input.empty?
|
|
105
140
|
flat = {}
|
|
141
|
+
# tail (pop,push) contains the next element to display
|
|
106
142
|
stack = [[nil, input]]
|
|
107
143
|
until stack.empty?
|
|
108
144
|
prefix, current = stack.pop
|
|
145
|
+
# empty things will be displayed as such
|
|
109
146
|
if current.respond_to?(:empty?) && current.empty?
|
|
110
147
|
flat[prefix] = current
|
|
111
148
|
next
|
|
112
149
|
end
|
|
113
150
|
case current
|
|
114
151
|
when Hash
|
|
115
|
-
|
|
152
|
+
add_elements(stack, prefix, current)
|
|
116
153
|
when Array
|
|
117
|
-
if current.
|
|
118
|
-
flat[prefix] = current.
|
|
154
|
+
if current.none?{ |i| i.is_a?(Array) || i.is_a?(Hash)}
|
|
155
|
+
flat[prefix] = list_to_string(current.map(&:to_s))
|
|
119
156
|
elsif current.all?{ |i| i.is_a?(Hash) && i.keys == ['name']}
|
|
120
|
-
flat[prefix] = current.map{ |i| i['name']}
|
|
157
|
+
flat[prefix] = list_to_string(current.map{ |i| i['name']})
|
|
121
158
|
elsif current.all?{ |i| i.is_a?(Hash) && i.keys.sort == %w[name value]}
|
|
122
|
-
stack
|
|
159
|
+
add_elements(stack, prefix, current.each_with_object({}){ |i, h| h[i['name']] = i['value']})
|
|
123
160
|
else
|
|
124
|
-
current.each_with_index.
|
|
161
|
+
add_elements(stack, prefix, current.each_with_index.map{ |v, i| [i, v]})
|
|
125
162
|
end
|
|
126
163
|
else
|
|
127
164
|
flat[prefix] = current
|
|
@@ -164,23 +201,23 @@ module Aspera
|
|
|
164
201
|
else
|
|
165
202
|
{}
|
|
166
203
|
end
|
|
167
|
-
options.declare(:format, 'Output format',
|
|
168
|
-
options.declare(:output, 'Destination for results',
|
|
169
|
-
options.declare(:display, 'Output only some information',
|
|
204
|
+
options.declare(:format, 'Output format', allowed: DISPLAY_FORMATS, handler: {o: self, m: :option_handler}, default: :table)
|
|
205
|
+
options.declare(:output, 'Destination for results', handler: {o: self, m: :option_handler})
|
|
206
|
+
options.declare(:display, 'Output only some information', allowed: DISPLAY_LEVELS, handler: {o: self, m: :option_handler}, default: :info)
|
|
170
207
|
options.declare(
|
|
171
208
|
:fields, "Comma separated list of: fields, or #{SpecialValues::ALL}, or #{SpecialValues::DEF}", handler: {o: self, m: :option_handler},
|
|
172
|
-
|
|
209
|
+
allowed: [String, Array, Regexp, Proc],
|
|
173
210
|
default: SpecialValues::DEF
|
|
174
211
|
)
|
|
175
|
-
options.declare(:select, 'Select only some items in lists: column, value',
|
|
176
|
-
options.declare(:table_style, '(Table) Display style',
|
|
177
|
-
options.declare(:flat_hash, '(Table) Display deep values as additional keys',
|
|
212
|
+
options.declare(:select, 'Select only some items in lists: column, value', allowed: [Hash, Proc], handler: {o: self, m: :option_handler})
|
|
213
|
+
options.declare(:table_style, '(Table) Display style', allowed: [Hash], handler: {o: self, m: :option_handler}, default: default_table_style)
|
|
214
|
+
options.declare(:flat_hash, '(Table) Display deep values as additional keys', allowed: Allowed::TYPES_BOOLEAN, handler: {o: self, m: :option_handler}, default: true)
|
|
178
215
|
options.declare(
|
|
179
|
-
:multi_single, '(Table) Control how object list is displayed as single table, or multiple objects',
|
|
216
|
+
:multi_single, '(Table) Control how object list is displayed as single table, or multiple objects', allowed: %i[no yes single],
|
|
180
217
|
handler: {o: self, m: :option_handler}, default: :no
|
|
181
218
|
)
|
|
182
|
-
options.declare(:show_secrets, 'Show secrets on command output',
|
|
183
|
-
options.declare(:image, 'Options for image display',
|
|
219
|
+
options.declare(:show_secrets, 'Show secrets on command output', allowed: Allowed::TYPES_BOOLEAN, handler: {o: self, m: :option_handler}, default: false)
|
|
220
|
+
options.declare(:image, 'Options for image display', allowed: Hash, handler: {o: self, m: :option_handler}, default: {})
|
|
184
221
|
end
|
|
185
222
|
|
|
186
223
|
# method accessed by option manager
|
|
@@ -225,8 +262,8 @@ module Aspera
|
|
|
225
262
|
end
|
|
226
263
|
end
|
|
227
264
|
|
|
228
|
-
def display_status(status, **
|
|
229
|
-
display_message(:info, status, **
|
|
265
|
+
def display_status(status, **kwargs)
|
|
266
|
+
display_message(:info, status, **kwargs)
|
|
230
267
|
end
|
|
231
268
|
|
|
232
269
|
def display_item_count(number, total)
|
|
@@ -314,7 +351,7 @@ module Aspera
|
|
|
314
351
|
when :table, :csv
|
|
315
352
|
case type
|
|
316
353
|
when :single_object
|
|
317
|
-
# :single_object is a Hash, where key=
|
|
354
|
+
# :single_object is a Hash, where key=column name
|
|
318
355
|
Aspera.assert_type(data, Hash)
|
|
319
356
|
if data.empty?
|
|
320
357
|
display_message(:data, self.class.special_format('empty dict'))
|
|
@@ -323,9 +360,8 @@ module Aspera
|
|
|
323
360
|
display_table([data], compute_fields([data], fields), single: true)
|
|
324
361
|
end
|
|
325
362
|
when :object_list
|
|
326
|
-
# :object_list is an Array of Hash, where key=
|
|
327
|
-
Aspera.
|
|
328
|
-
Aspera.assert(data.all?(Hash)){"expecting Array of Hash: #{data.inspect}"}
|
|
363
|
+
# :object_list is an Array of Hash, where key=column name
|
|
364
|
+
Aspera.assert_array_all(data, Hash){'result'}
|
|
329
365
|
data = data.map{ |obj| self.class.flatten_hash(obj)} if @options[:flat_hash]
|
|
330
366
|
display_table(data, compute_fields(data, fields), single: type.eql?(:single_object))
|
|
331
367
|
when :value_list
|
|
@@ -404,8 +440,7 @@ module Aspera
|
|
|
404
440
|
def filter_list_on_fields(data)
|
|
405
441
|
# by default, keep all data intact
|
|
406
442
|
return data if @options[:fields].eql?(SpecialValues::DEF) && @options[:select].nil?
|
|
407
|
-
Aspera.
|
|
408
|
-
Aspera.assert(data.all?(Hash)){'Filtering fields or select requires result is an Array of Hash'}
|
|
443
|
+
Aspera.assert_array_all(data, Hash){'filter or select'}
|
|
409
444
|
filter_columns_on_select(data)
|
|
410
445
|
return data if @options[:fields].eql?(SpecialValues::DEF)
|
|
411
446
|
selected_fields = compute_fields(data, @options[:fields])
|
data/lib/aspera/cli/hints.rb
CHANGED
|
@@ -100,6 +100,14 @@ module Aspera
|
|
|
100
100
|
remediation: [
|
|
101
101
|
'home not created in Windows?'
|
|
102
102
|
]
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
exception: Aspera::RestCallError,
|
|
106
|
+
match: /Server is not configured for this request/,
|
|
107
|
+
remediation: [
|
|
108
|
+
'Transfer user shall have those parameters in aspera.conf set to: token',
|
|
109
|
+
'authorization_transfer_in_value authorization_transfer_out_value'
|
|
110
|
+
]
|
|
103
111
|
}
|
|
104
112
|
]
|
|
105
113
|
private_constant :ERROR_HINTS
|
data/lib/aspera/cli/info.rb
CHANGED
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
module Aspera
|
|
4
4
|
module Cli
|
|
5
5
|
module Info
|
|
6
|
-
#
|
|
6
|
+
# Name of command line tool, also used as foldername where config is stored
|
|
7
7
|
CMD_NAME = 'ascli'
|
|
8
|
-
#
|
|
8
|
+
# Name of the containing gem, same as in <gem name>.gemspec
|
|
9
9
|
GEM_NAME = 'aspera-cli'
|
|
10
10
|
DOC_URL = "https://www.rubydoc.info/gems/#{GEM_NAME}"
|
|
11
11
|
GEM_URL = "https://rubygems.org/gems/#{GEM_NAME}"
|
|
12
12
|
SRC_URL = 'https://github.com/IBM/aspera-cli'
|
|
13
13
|
CONTAINER = 'docker.io/martinlaurent/ascli'
|
|
14
|
-
#
|
|
15
|
-
#
|
|
14
|
+
# Set this to warn in advance when minimum required ruby version will increase
|
|
15
|
+
# See also required_ruby_version in gemspec file
|
|
16
16
|
RUBY_FUTURE_MINIMUM_VERSION = '3.2'
|
|
17
17
|
end
|
|
18
18
|
end
|