aspera-cli 4.25.1 → 4.25.3
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 +456 -405
- data/CONTRIBUTING.md +22 -18
- data/README.md +33 -9741
- data/bin/asession +111 -88
- data/lib/aspera/agent/connect.rb +1 -1
- data/lib/aspera/agent/desktop.rb +1 -1
- data/lib/aspera/agent/direct.rb +19 -18
- data/lib/aspera/agent/node.rb +1 -1
- data/lib/aspera/api/aoc.rb +44 -20
- data/lib/aspera/api/faspex.rb +25 -6
- data/lib/aspera/api/node.rb +20 -16
- data/lib/aspera/ascp/installation.rb +32 -51
- data/lib/aspera/assert.rb +2 -2
- data/lib/aspera/cli/extended_value.rb +1 -0
- data/lib/aspera/cli/formatter.rb +0 -4
- data/lib/aspera/cli/hints.rb +18 -4
- data/lib/aspera/cli/main.rb +3 -6
- data/lib/aspera/cli/manager.rb +46 -30
- data/lib/aspera/cli/plugins/aoc.rb +155 -131
- data/lib/aspera/cli/plugins/base.rb +15 -18
- data/lib/aspera/cli/plugins/config.rb +50 -87
- data/lib/aspera/cli/plugins/factory.rb +2 -2
- data/lib/aspera/cli/plugins/faspex.rb +4 -4
- data/lib/aspera/cli/plugins/faspex5.rb +74 -76
- data/lib/aspera/cli/plugins/node.rb +3 -5
- data/lib/aspera/cli/plugins/oauth.rb +26 -25
- data/lib/aspera/cli/plugins/preview.rb +9 -14
- data/lib/aspera/cli/plugins/shares.rb +15 -7
- data/lib/aspera/cli/transfer_agent.rb +2 -2
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/colors.rb +7 -0
- data/lib/aspera/environment.rb +30 -16
- data/lib/aspera/faspex_gw.rb +6 -6
- data/lib/aspera/faspex_postproc.rb +20 -14
- data/lib/aspera/hash_ext.rb +8 -0
- data/lib/aspera/log.rb +15 -15
- data/lib/aspera/markdown.rb +22 -0
- data/lib/aspera/node_simulator.rb +1 -1
- data/lib/aspera/oauth/base.rb +2 -2
- data/lib/aspera/oauth/url_json.rb +2 -2
- data/lib/aspera/oauth/web.rb +1 -1
- data/lib/aspera/preview/generator.rb +9 -9
- data/lib/aspera/rest.rb +44 -37
- data/lib/aspera/rest_call_error.rb +16 -8
- data/lib/aspera/rest_error_analyzer.rb +38 -36
- data/lib/aspera/rest_errors_aspera.rb +19 -18
- data/lib/aspera/transfer/resumer.rb +2 -2
- data/lib/aspera/yaml.rb +49 -0
- data.tar.gz.sig +0 -0
- metadata +17 -3
- metadata.gz.sig +0 -0
- data/release_notes.md +0 -8
|
@@ -26,10 +26,7 @@ module Aspera
|
|
|
26
26
|
# Singleton that tells where to find ascp and other local resources (keys..) , using the "path(:name)" method.
|
|
27
27
|
# It is used by object : AgentDirect to find necessary resources
|
|
28
28
|
# By default it takes the first Aspera product found
|
|
29
|
-
# The user can specify ascp location by calling:
|
|
30
|
-
# Installation.instance.use_ascp_from_product(product_name)
|
|
31
|
-
# or
|
|
32
|
-
# Installation.instance.ascp_path=""
|
|
29
|
+
# The user can specify `ascp` location by calling: `sdk_folder=` method
|
|
33
30
|
class Installation
|
|
34
31
|
include Singleton
|
|
35
32
|
|
|
@@ -53,37 +50,37 @@ module Aspera
|
|
|
53
50
|
end
|
|
54
51
|
end
|
|
55
52
|
|
|
56
|
-
#
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
# Set `ascp` executable "location"
|
|
54
|
+
# It can be:
|
|
55
|
+
# - Full path to folder where `ascp` executable is located
|
|
56
|
+
# - "product:PRODUCT_NAME" to use ascp from named product
|
|
57
|
+
# - "product:FIRST" to use ascp from first found product
|
|
58
|
+
def sdk_folder=(ascp_location)
|
|
59
|
+
Aspera.assert_type(ascp_location, String){'ascp_location'}
|
|
60
|
+
Aspera.assert(!ascp_location.empty?){'ascp location cannot be empty: check your config file'}
|
|
61
|
+
folder =
|
|
62
|
+
if ascp_location.start_with?(USE_PRODUCT_PREFIX)
|
|
63
|
+
product_name = ascp_location[USE_PRODUCT_PREFIX.length..-1]
|
|
64
|
+
if product_name.eql?(FIRST_FOUND)
|
|
65
|
+
pl = installed_products.first
|
|
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?
|
|
67
|
+
else
|
|
68
|
+
pl = installed_products.find{ |i| i[:name].eql?(product_name)}
|
|
69
|
+
raise "No such product installed: #{product_name}" if pl.nil?
|
|
70
|
+
end
|
|
71
|
+
File.dirname(pl[:ascp_path])
|
|
72
|
+
else
|
|
73
|
+
ascp_location.include?('/ascp') ? File.dirname(ascp_location) : ascp_location
|
|
74
|
+
end
|
|
75
|
+
Log.log.debug{"ascp_folder=#{folder}"}
|
|
76
|
+
Products::Transferd.sdk_directory = folder
|
|
62
77
|
return
|
|
63
78
|
end
|
|
64
79
|
|
|
65
|
-
def
|
|
80
|
+
def sdk_folder
|
|
66
81
|
path(:ascp)
|
|
67
82
|
end
|
|
68
83
|
|
|
69
|
-
# Compatibility
|
|
70
|
-
def sdk_folder=(v)
|
|
71
|
-
Products::Transferd.sdk_directory = v
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
# find ascp in named product (use value : FIRST_FOUND='FIRST' to just use first one)
|
|
75
|
-
# or select one from installed_products()
|
|
76
|
-
def use_ascp_from_product(product_name)
|
|
77
|
-
if product_name.eql?(FIRST_FOUND)
|
|
78
|
-
pl = installed_products.first
|
|
79
|
-
raise "No Aspera transfer module or SDK found.\nRefer to the manual or install SDK with command:\nascli conf transferd install" if pl.nil?
|
|
80
|
-
else
|
|
81
|
-
pl = installed_products.find{ |i| i[:name].eql?(product_name)}
|
|
82
|
-
raise "No such product installed: #{product_name}" if pl.nil?
|
|
83
|
-
end
|
|
84
|
-
@ascp_path = pl[:ascp_path]
|
|
85
|
-
end
|
|
86
|
-
|
|
87
84
|
# @return [Hash] with key = file name (String), and value = path to file
|
|
88
85
|
def file_paths
|
|
89
86
|
return SDK_FILES.each_with_object({}) do |v, m|
|
|
@@ -113,22 +110,8 @@ module Aspera
|
|
|
113
110
|
case k
|
|
114
111
|
when *EXE_FILES
|
|
115
112
|
file_is_required = k.eql?(:ascp)
|
|
116
|
-
file =
|
|
117
|
-
|
|
118
|
-
else
|
|
119
|
-
# find ascp when needed
|
|
120
|
-
if @ascp_path.nil?
|
|
121
|
-
if @ascp_location.start_with?(USE_PRODUCT_PREFIX)
|
|
122
|
-
use_ascp_from_product(@ascp_location[USE_PRODUCT_PREFIX.length..-1])
|
|
123
|
-
else
|
|
124
|
-
@ascp_path = @ascp_location
|
|
125
|
-
end
|
|
126
|
-
Aspera.assert(File.exist?(@ascp_path)){"No such file: [#{@ascp_path}]"}
|
|
127
|
-
Log.log.debug{"ascp_path=#{@ascp_path}"}
|
|
128
|
-
end
|
|
129
|
-
# NOTE: that there might be a .exe at the end
|
|
130
|
-
@ascp_path.gsub('ascp', k.to_s)
|
|
131
|
-
end
|
|
113
|
+
file = Products::Transferd.transferd_path
|
|
114
|
+
file = File.join(File.dirname(file), Environment.instance.exe_file(k.to_s)) unless k.eql?(:transferd)
|
|
132
115
|
when :ssh_private_dsa, :ssh_private_rsa
|
|
133
116
|
# assume last 3 letters are type
|
|
134
117
|
type = k.to_s[-3..-1].to_sym
|
|
@@ -197,7 +180,7 @@ module Aspera
|
|
|
197
180
|
def ascp_info_from_log
|
|
198
181
|
data = {}
|
|
199
182
|
# read PATHs from ascp directly, and pvcl modules as well
|
|
200
|
-
Open3.popen3(
|
|
183
|
+
Open3.popen3(path(:ascp), '-DDL-') do |_stdin, _stdout, stderr, thread|
|
|
201
184
|
last_line = ''
|
|
202
185
|
while (line = stderr.gets)
|
|
203
186
|
line.chomp!
|
|
@@ -230,13 +213,13 @@ module Aspera
|
|
|
230
213
|
# Openssl information
|
|
231
214
|
def ascp_info_from_file
|
|
232
215
|
data = {}
|
|
233
|
-
File.binread(
|
|
216
|
+
File.binread(path(:ascp)).scan(/[\x20-\x7E]{10,}/) do |bin_string|
|
|
234
217
|
if (m = bin_string.match(/OPENSSLDIR.*"(.*)"/))
|
|
235
218
|
data['ascp_openssl_dir'] = m[1]
|
|
236
219
|
elsif (m = bin_string.match(/OpenSSL (\d[^ -]+)/))
|
|
237
220
|
data['ascp_openssl_version'] = m[1]
|
|
238
221
|
end
|
|
239
|
-
end if File.file?(
|
|
222
|
+
end if File.file?(path(:ascp))
|
|
240
223
|
return data
|
|
241
224
|
end
|
|
242
225
|
|
|
@@ -374,9 +357,7 @@ module Aspera
|
|
|
374
357
|
private_constant :DEFAULT_ASPERA_CONF, :EXE_FILES, :SDK_FILES, :TRANSFERD_ARCHIVE_LOCATION_URL
|
|
375
358
|
|
|
376
359
|
def initialize
|
|
377
|
-
|
|
378
|
-
@ascp_location = nil
|
|
379
|
-
@sdk_dir = nil
|
|
360
|
+
# cache for installed products found
|
|
380
361
|
@found_products = nil
|
|
381
362
|
@transferd_urls = TRANSFERD_ARCHIVE_LOCATION_URL
|
|
382
363
|
end
|
data/lib/aspera/assert.rb
CHANGED
|
@@ -55,7 +55,7 @@ module Aspera
|
|
|
55
55
|
assert(classes.any?{ |k| value.is_a?(k)}, type: type){"#{"#{yield}: " if block_given?}expecting #{classes.join(', ')}, but have (#{value.class})#{value.inspect}"}
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
# Assert that all value of array are of the same specified type
|
|
58
|
+
# Assert that all value of array are of the same specified type.
|
|
59
59
|
# @param array [Array] The array to check
|
|
60
60
|
# @param klass [Class] The expected type of elements
|
|
61
61
|
# @param type [Exception,Symbol] Exception to raise, or Symbol for Log.log
|
|
@@ -93,7 +93,7 @@ module Aspera
|
|
|
93
93
|
# The value is not one of the expected values
|
|
94
94
|
# @param value [Object] The wrong value
|
|
95
95
|
# @param type [Exception,Symbol] Exception to raise, or Symbol for Log.log
|
|
96
|
-
# @param block
|
|
96
|
+
# @param &block [Proc] Additional description in front of message
|
|
97
97
|
def error_unexpected_value(value, type: InternalError)
|
|
98
98
|
report_error(type, "#{"#{yield}: " if block_given?}unexpected value: #{value.inspect}")
|
|
99
99
|
end
|
data/lib/aspera/cli/formatter.rb
CHANGED
|
@@ -30,10 +30,6 @@ module Aspera
|
|
|
30
30
|
SINGLE_OBJECT_COLUMN_NAMES = %i[field value].freeze
|
|
31
31
|
|
|
32
32
|
private_constant :FIELDS_LESS, :DISPLAY_FORMATS, :DISPLAY_LEVELS, :SINGLE_OBJECT_COLUMN_NAMES
|
|
33
|
-
# prefix to display error messages in user messages (terminal)
|
|
34
|
-
ERROR_FLASH = 'ERROR:'.bg_red.gray.blink.freeze
|
|
35
|
-
WARNING_FLASH = 'WARNING:'.bg_brown.black.blink.freeze
|
|
36
|
-
HINT_FLASH = 'HINT:'.bg_green.gray.blink.freeze
|
|
37
33
|
|
|
38
34
|
class << self
|
|
39
35
|
# nicer display for boolean
|
data/lib/aspera/cli/hints.rb
CHANGED
|
@@ -26,7 +26,7 @@ module Aspera
|
|
|
26
26
|
]
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
|
-
exception: RestCallError,
|
|
29
|
+
exception: Aspera::RestCallError,
|
|
30
30
|
match: /Signature has expired/,
|
|
31
31
|
remediation: [
|
|
32
32
|
'There is too much time difference between your computer and the server',
|
|
@@ -108,6 +108,20 @@ module Aspera
|
|
|
108
108
|
'Transfer user shall have those parameters in aspera.conf set to: token',
|
|
109
109
|
'authorization_transfer_in_value authorization_transfer_out_value'
|
|
110
110
|
]
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
exception: Aspera::RestCallError,
|
|
114
|
+
match: /invalid_grant/,
|
|
115
|
+
remediation: [
|
|
116
|
+
'Check your public key in your AoC user profile.'
|
|
117
|
+
]
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
exception: Aspera::RestCallError,
|
|
121
|
+
match: /Please configure ACLs for this URI/,
|
|
122
|
+
remediation: [
|
|
123
|
+
'server must have: asnodeadmin -mu <node user> --acl-add=internal --internal'
|
|
124
|
+
]
|
|
111
125
|
}
|
|
112
126
|
]
|
|
113
127
|
private_constant :ERROR_HINTS
|
|
@@ -129,9 +143,9 @@ module Aspera
|
|
|
129
143
|
next unless message.match?(m)
|
|
130
144
|
else Aspera.error_unexpected_value(m)
|
|
131
145
|
end
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
146
|
+
hint[:remediation].each do |r|
|
|
147
|
+
Log.log.info{"#{'HINT:'.bg_green.gray.blink.freeze} #{r}"}
|
|
148
|
+
end
|
|
135
149
|
break
|
|
136
150
|
end
|
|
137
151
|
end
|
data/lib/aspera/cli/main.rb
CHANGED
|
@@ -228,7 +228,7 @@ module Aspera
|
|
|
228
228
|
# 1- processing of error condition
|
|
229
229
|
unless exception_info.nil?
|
|
230
230
|
Log.log.warn(exception_info[:e].message) if Log.instance.logger_type.eql?(:syslog) && exception_info[:security]
|
|
231
|
-
|
|
231
|
+
Log.log.error{"#{exception_info[:t]}: #{exception_info[:e].message}"}
|
|
232
232
|
Log.log.debug{(['Backtrace:'] + exception_info[:e].backtrace).join("\n")} if exception_info[:debug]
|
|
233
233
|
@context.formatter.display_message(:error, 'Use option -h to get help.') if exception_info[:usage]
|
|
234
234
|
# Is that a known error condition with proposal for remediation ?
|
|
@@ -237,7 +237,7 @@ module Aspera
|
|
|
237
237
|
# 2- processing of command not processed (due to exception or bad command line)
|
|
238
238
|
if execute_command || @option_show_config
|
|
239
239
|
@context.options.final_errors.each do |msg|
|
|
240
|
-
|
|
240
|
+
Log.log.error{"Argument: #{msg}"}
|
|
241
241
|
# Add code as exception if there is not already an error
|
|
242
242
|
exception_info = {e: Exception.new(msg), t: 'UnusedArg'} if exception_info.nil?
|
|
243
243
|
end
|
|
@@ -291,10 +291,7 @@ module Aspera
|
|
|
291
291
|
@context.formatter.declare_options(@context.options)
|
|
292
292
|
# Compare $0 with expected name
|
|
293
293
|
current_prog_name = File.basename($PROGRAM_NAME)
|
|
294
|
-
|
|
295
|
-
:error,
|
|
296
|
-
"#{Formatter::WARNING_FLASH} Please use '#{Info::CMD_NAME}' instead of '#{current_prog_name}'"
|
|
297
|
-
) unless current_prog_name.eql?(Info::CMD_NAME)
|
|
294
|
+
Aspera.assert(current_prog_name.eql?(Info::CMD_NAME), type: :warn){"Please use '#{Info::CMD_NAME}' instead of '#{current_prog_name}'"}
|
|
298
295
|
# Declare and parse global options
|
|
299
296
|
declare_global_options
|
|
300
297
|
# Do not display config commands if help is asked
|
data/lib/aspera/cli/manager.rb
CHANGED
|
@@ -12,6 +12,37 @@ require 'optparse'
|
|
|
12
12
|
|
|
13
13
|
module Aspera
|
|
14
14
|
module Cli
|
|
15
|
+
module BoolValue
|
|
16
|
+
# boolean options are set to true/false from the following values
|
|
17
|
+
YES_SYM = :yes
|
|
18
|
+
NO_SYM = :no
|
|
19
|
+
FALSE_VALUES = [NO_SYM, false].freeze
|
|
20
|
+
TRUE_VALUES = [YES_SYM, true].freeze
|
|
21
|
+
private_constant :YES_SYM, :NO_SYM, :FALSE_VALUES, :TRUE_VALUES
|
|
22
|
+
# Boolean values
|
|
23
|
+
# @return [Array<true, false, :yes, :no>]
|
|
24
|
+
ALL = (TRUE_VALUES + FALSE_VALUES).freeze
|
|
25
|
+
TYPES = [FalseClass, TrueClass].freeze
|
|
26
|
+
SYMBOLS = [NO_SYM, YES_SYM].freeze
|
|
27
|
+
# @return `true` if value is a value for `true` in ALL
|
|
28
|
+
def true?(enum)
|
|
29
|
+
Aspera.assert_values(enum, ALL){'boolean'}
|
|
30
|
+
return TRUE_VALUES.include?(enum)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @return [:yes, :no]
|
|
34
|
+
def to_sym(enum)
|
|
35
|
+
Aspera.assert_values(enum, ALL){'boolean'}
|
|
36
|
+
return TRUE_VALUES.include?(enum) ? YES_SYM : NO_SYM
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @return `true` if value is a value for `true` or `false` in ALL
|
|
40
|
+
def symbol?(sym)
|
|
41
|
+
return ALL.include?(sym)
|
|
42
|
+
end
|
|
43
|
+
module_function :true?, :to_sym, :symbol?
|
|
44
|
+
end
|
|
45
|
+
|
|
15
46
|
# Constants to be used as parameter `allowed:` for `OptionValue`
|
|
16
47
|
module Allowed
|
|
17
48
|
# This option can be set to a single string or array, multiple times, and gives Array of String
|
|
@@ -20,7 +51,7 @@ module Aspera
|
|
|
20
51
|
TYPES_SYMBOL_ARRAY = [Array, Symbol].freeze
|
|
21
52
|
# Value will be coerced to int
|
|
22
53
|
TYPES_INTEGER = [Integer].freeze
|
|
23
|
-
TYPES_BOOLEAN =
|
|
54
|
+
TYPES_BOOLEAN = BoolValue::TYPES
|
|
24
55
|
# no value at all, it's a switch
|
|
25
56
|
TYPES_NONE = [].freeze
|
|
26
57
|
TYPES_ENUM = [Symbol].freeze
|
|
@@ -35,7 +66,8 @@ module Aspera
|
|
|
35
66
|
attr_accessor :values
|
|
36
67
|
|
|
37
68
|
# @param option [Symbol] Name of option
|
|
38
|
-
# @param
|
|
69
|
+
# @param description [String] Description for help
|
|
70
|
+
# @param allowed [nil,Class,Array<Class>,Array<Symbol>] Allowed values
|
|
39
71
|
# @param handler [Hash] Accessor: keys: :o(object) and :m(method)
|
|
40
72
|
# @param deprecation [String] Deprecation message
|
|
41
73
|
# `allowed`:
|
|
@@ -61,7 +93,7 @@ module Aspera
|
|
|
61
93
|
else
|
|
62
94
|
:setter
|
|
63
95
|
end
|
|
64
|
-
Aspera.assert(@object.respond_to?(@read_method)){"#{@object} does not respond to #{
|
|
96
|
+
Aspera.assert(@object.respond_to?(@read_method)){"#{@object} does not respond to #{@read_method}"} unless @access.eql?(:local)
|
|
65
97
|
@types = nil
|
|
66
98
|
@values = nil
|
|
67
99
|
if !allowed.nil?
|
|
@@ -73,7 +105,7 @@ module Aspera
|
|
|
73
105
|
@values = allowed[Allowed::TYPES_SYMBOL_ARRAY.length..-1]
|
|
74
106
|
elsif allowed.all?(Class)
|
|
75
107
|
@types = allowed
|
|
76
|
-
@values =
|
|
108
|
+
@values = BoolValue::ALL if allowed.eql?(Allowed::TYPES_BOOLEAN)
|
|
77
109
|
# Default value for array
|
|
78
110
|
@object ||= [] if @types.first.eql?(Array) && !@types.include?(NilClass)
|
|
79
111
|
@object ||= {} if @types.first.eql?(Hash) && !@types.include?(NilClass)
|
|
@@ -109,7 +141,7 @@ module Aspera
|
|
|
109
141
|
Aspera.assert(!@deprecation, type: warn){"Option #{@option} is deprecated: #{@deprecation}"}
|
|
110
142
|
new_value = ExtendedValue.instance.evaluate(value, context: "option: #{@option}", allowed: @types)
|
|
111
143
|
Log.log.trace1{"#{where}: #{@option} <- (#{new_value.class})#{new_value}"}
|
|
112
|
-
new_value =
|
|
144
|
+
new_value = BoolValue.true?(new_value) if @types.eql?(Allowed::TYPES_BOOLEAN)
|
|
113
145
|
new_value = Integer(new_value) if @types.eql?(Allowed::TYPES_INTEGER)
|
|
114
146
|
new_value = [new_value] if @types.eql?(Allowed::TYPES_STRING_ARRAY) && new_value.is_a?(String)
|
|
115
147
|
# Setting a Hash to null set an empty hash
|
|
@@ -141,20 +173,7 @@ module Aspera
|
|
|
141
173
|
# arguments options start with '-', others are commands
|
|
142
174
|
# resolves on extended value syntax
|
|
143
175
|
class Manager
|
|
144
|
-
BOOLEAN_SIMPLE = %i[no yes].freeze
|
|
145
176
|
class << self
|
|
146
|
-
# @return `true` if value is a value for `true` in BOOLEAN_VALUES
|
|
147
|
-
def enum_to_bool(enum)
|
|
148
|
-
Aspera.assert_values(enum, BOOLEAN_VALUES){'boolean'}
|
|
149
|
-
return TRUE_VALUES.include?(enum)
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
# @return :yes ot :no
|
|
153
|
-
def enum_to_yes_no(enum)
|
|
154
|
-
Aspera.assert_values(enum, BOOLEAN_VALUES){'boolean'}
|
|
155
|
-
return TRUE_VALUES.include?(enum) ? BOOL_YES : BOOL_NO
|
|
156
|
-
end
|
|
157
|
-
|
|
158
177
|
# Find shortened string value in allowed symbol list
|
|
159
178
|
def get_from_list(short_value, descr, allowed_values)
|
|
160
179
|
Aspera.assert_type(short_value, String)
|
|
@@ -164,7 +183,7 @@ module Aspera
|
|
|
164
183
|
matching = allowed_values.select{ |i| i.to_s.start_with?(short_value)}
|
|
165
184
|
Aspera.assert(!matching.empty?, multi_choice_assert_msg("unknown value for #{descr}: #{short_value}", allowed_values), type: BadArgument)
|
|
166
185
|
Aspera.assert(matching.length.eql?(1), multi_choice_assert_msg("ambiguous shortcut for #{descr}: #{short_value}", matching), type: BadArgument)
|
|
167
|
-
return
|
|
186
|
+
return BoolValue.true?(matching.first) if allowed_values.eql?(BoolValue::ALL)
|
|
168
187
|
return matching.first
|
|
169
188
|
end
|
|
170
189
|
|
|
@@ -278,11 +297,11 @@ module Aspera
|
|
|
278
297
|
case option_attrs.types
|
|
279
298
|
when Allowed::TYPES_ENUM, Allowed::TYPES_BOOLEAN
|
|
280
299
|
# This option value must be a symbol (or array of symbols)
|
|
281
|
-
set_option(option_symbol,
|
|
300
|
+
set_option(option_symbol, BoolValue.true?(default), where: 'default') if option_attrs.values.eql?(BoolValue::ALL) && !default.nil?
|
|
282
301
|
value = get_option(option_symbol)
|
|
283
302
|
help_values =
|
|
284
303
|
if option_attrs.types.eql?(Allowed::TYPES_BOOLEAN)
|
|
285
|
-
highlight_current_in_list(
|
|
304
|
+
highlight_current_in_list(BoolValue::SYMBOLS, BoolValue.to_sym(value))
|
|
286
305
|
else
|
|
287
306
|
highlight_current_in_list(option_attrs.values, value)
|
|
288
307
|
end
|
|
@@ -600,9 +619,12 @@ module Aspera
|
|
|
600
619
|
end
|
|
601
620
|
|
|
602
621
|
# TODO: use formatter
|
|
603
|
-
#
|
|
622
|
+
# Highlight current value in list
|
|
623
|
+
# @param list [Array<Symbol>] List of possible values
|
|
624
|
+
# @param current [Symbol] Current value
|
|
625
|
+
# @return [String] comma separated sorted list of values, with the current value highlighted
|
|
604
626
|
def highlight_current_in_list(list, current)
|
|
605
|
-
list.map do |i|
|
|
627
|
+
list.sort.map do |i|
|
|
606
628
|
if i.eql?(current)
|
|
607
629
|
$stdout.isatty ? i.to_s.red.bold : "[#{i}]"
|
|
608
630
|
else
|
|
@@ -632,12 +654,6 @@ module Aspera
|
|
|
632
654
|
unprocessed_options.delete(k)
|
|
633
655
|
end
|
|
634
656
|
end
|
|
635
|
-
# boolean options are set to true/false from the following values
|
|
636
|
-
BOOL_YES = BOOLEAN_SIMPLE.last
|
|
637
|
-
BOOL_NO = BOOLEAN_SIMPLE.first
|
|
638
|
-
FALSE_VALUES = [BOOL_NO, false].freeze
|
|
639
|
-
TRUE_VALUES = [BOOL_YES, true].freeze
|
|
640
|
-
BOOLEAN_VALUES = (TRUE_VALUES + FALSE_VALUES).freeze
|
|
641
657
|
|
|
642
658
|
# Option name separator on command line, e.g. in --option-blah, third "-"
|
|
643
659
|
OPTION_SEP_LINE = '-'
|
|
@@ -651,7 +667,7 @@ module Aspera
|
|
|
651
667
|
OPTIONS_STOP = '--'
|
|
652
668
|
SOURCE_USER = 'cmdline' # cspell:disable-line
|
|
653
669
|
|
|
654
|
-
private_constant :
|
|
670
|
+
private_constant :OPTION_SEP_LINE, :OPTION_SEP_SYMBOL, :OPTION_VALUE_SEPARATOR, :OPTION_PREFIX, :OPTIONS_STOP, :SOURCE_USER
|
|
655
671
|
end
|
|
656
672
|
end
|
|
657
673
|
end
|