aspera-cli 4.18.0 → 4.18.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,23 +14,28 @@ module Aspera
14
14
  module Api
15
15
  # Provides additional functions using node API with gen4 extensions (access keys)
16
16
  class Node < Aspera::Rest
17
- # node api permissions
18
- ACCESS_LEVELS = %w[delete list mkdir preview read rename write].freeze
19
- HEADER_X_ASPERA_ACCESS_KEY = 'X-Aspera-AccessKey'
20
17
  SCOPE_SEPARATOR = ':'
21
- SCOPE_USER = 'user:all'
22
- SCOPE_ADMIN = 'admin:all'
23
18
  SCOPE_NODE_PREFIX = 'node.'
24
19
  # prefix for ruby code for filter (deprecated)
25
20
  MATCH_EXEC_PREFIX = 'exec:'
26
21
  MATCH_TYPES = [String, Proc, Regexp, NilClass].freeze
27
- PATH_SEPARATOR = '/'
28
22
  SIGNATURE_DELIMITER = '==SIGNATURE=='
29
23
  BEARER_TOKEN_VALIDITY_DEFAULT = 86400
30
- BEARER_TOKEN_SCOPE_DEFAULT = SCOPE_USER
31
- private_constant :MATCH_EXEC_PREFIX, :MATCH_TYPES,
32
- :SIGNATURE_DELIMITER, :BEARER_TOKEN_VALIDITY_DEFAULT, :BEARER_TOKEN_SCOPE_DEFAULT,
33
- :SCOPE_SEPARATOR, :SCOPE_NODE_PREFIX
24
+ # fields in @app_info
25
+ REQUIRED_APP_INFO_FIELDS = %i[api app node_info workspace_id workspace_name].freeze
26
+ # methods of @app_info[:api]
27
+ REQUIRED_APP_API_METHODS = %i[node_api_from add_ts_tags].freeze
28
+ private_constant :SCOPE_SEPARATOR, :SCOPE_NODE_PREFIX, :MATCH_EXEC_PREFIX, :MATCH_TYPES,
29
+ :SIGNATURE_DELIMITER, :BEARER_TOKEN_VALIDITY_DEFAULT,
30
+ :REQUIRED_APP_INFO_FIELDS, :REQUIRED_APP_API_METHODS
31
+
32
+ # node api permissions
33
+ ACCESS_LEVELS = %w[delete list mkdir preview read rename write].freeze
34
+ HEADER_X_ASPERA_ACCESS_KEY = 'X-Aspera-AccessKey'
35
+ HEADER_X_TOTAL_COUNT = 'X-Total-Count'
36
+ SCOPE_USER = 'user:all'
37
+ SCOPE_ADMIN = 'admin:all'
38
+ PATH_SEPARATOR = '/'
34
39
 
35
40
  # register node special token decoder
36
41
  OAuth::Factory.instance.register_decoder(lambda{|token|Node.decode_bearer_token(token)})
@@ -59,7 +64,7 @@ module Aspera
59
64
  end
60
65
 
61
66
  def file_matcher_from_argument(options)
62
- return file_matcher(options.get_next_argument('filter', type: MATCH_TYPES, mandatory: false))
67
+ return file_matcher(options.get_next_argument('filter', validation: MATCH_TYPES, mandatory: false))
63
68
  end
64
69
 
65
70
  # node API scopes
@@ -86,7 +91,7 @@ module Aspera
86
91
  # manage convenience parameters
87
92
  expiration_sec = payload['_validity'] || BEARER_TOKEN_VALIDITY_DEFAULT
88
93
  payload.delete('_validity')
89
- scope = payload['_scope'] || BEARER_TOKEN_SCOPE_DEFAULT
94
+ scope = payload['_scope'] || SCOPE_USER
90
95
  payload.delete('_scope')
91
96
  payload['scope'] ||= token_scope(access_key, scope)
92
97
  payload['auth_type'] ||= 'access_key'
@@ -117,19 +122,13 @@ module Aspera
117
122
  end
118
123
  end
119
124
 
120
- # fields in @app_info
121
- REQUIRED_APP_INFO_FIELDS = %i[api app node_info workspace_id workspace_name].freeze
122
- # methods of @app_info[:api]
123
- REQUIRED_APP_API_METHODS = %i[node_api_from add_ts_tags].freeze
124
- private_constant :REQUIRED_APP_INFO_FIELDS, :REQUIRED_APP_API_METHODS
125
-
126
125
  attr_reader :app_info
127
126
 
127
+ # @param app_info [Hash,NilClass] Special processing for AoC
128
+ # @param add_tspec [Hash,NilClass] Additional transfer spec
128
129
  # @param base_url [String] Rest parameters
129
130
  # @param auth [String,NilClass] Rest parameters
130
131
  # @param headers [String,NilClass] Rest parameters
131
- # @param app_info [Hash,NilClass] Special processing for AoC
132
- # @param add_tspec [Hash,NilClass] Additional transfer spec
133
132
  def initialize(app_info: nil, add_tspec: nil, **rest_args)
134
133
  # init Rest
135
134
  super(**rest_args)
@@ -162,25 +161,42 @@ module Aspera
162
161
  workspace_id: @app_info[:workspace_id],
163
162
  workspace_name: @app_info[:workspace_name])
164
163
  end
165
- Log.log.warn{"cannot resolve link with node id #{node_id}"}
164
+ Log.log.warn{"Cannot resolve link with node id #{node_id}, no resolver"}
166
165
  return nil
167
166
  end
168
167
 
168
+ # Check if a link entry in folder has target information
169
+ # @param entry [Hash] entry in folder
170
+ # @return [Boolean] true if target information is available
171
+ def entry_has_link_information(entry)
172
+ # if target information is missing in folder, try to get it on entry
173
+ if entry['target_node_id'].nil? || entry['target_id'].nil?
174
+ link_entry = read("files/#{entry['id']}")[:data]
175
+ entry['target_node_id'] = link_entry['target_node_id']
176
+ entry['target_id'] = link_entry['target_id']
177
+ end
178
+ return true unless entry['target_node_id'].nil? || entry['target_id'].nil?
179
+ Log.log.warn{"Missing target information for link: #{entry['name']}"}
180
+ return false
181
+ end
182
+
169
183
  # Recursively browse in a folder (with non-recursive method)
170
184
  # sub folders are processed if the processing method returns true
185
+ # links are processed on the respective node
171
186
  # @param state [Object] state object sent to processing method
172
187
  # @param top_file_id [String] file id to start at (default = access key root file id)
173
188
  # @param top_file_path [String] path of top folder (default = /)
174
189
  # @param block [Proc] processing method, arguments: entry, path, state
175
- def process_folder_tree(state:, top_file_id:, top_file_path: '/', &block)
190
+ def process_folder_tree(method_sym:, state:, top_file_id:, top_file_path: '/')
176
191
  Aspera.assert(!top_file_path.nil?){'top_file_path not set'}
177
- Aspera.assert(block){'Missing block'}
192
+ Log.log.debug{"process_folder_tree: node=#{@app_info ? @app_info[:node_info]['id'] : 'nil'}, file id=#{top_file_id}, path=#{top_file_path}"}
178
193
  # start at top folder
179
194
  folders_to_explore = [{id: top_file_id, path: top_file_path}]
180
195
  Log.log.debug{Log.dump(:folders_to_explore, folders_to_explore)}
181
196
  until folders_to_explore.empty?
197
+ # consume first in job list
182
198
  current_item = folders_to_explore.shift
183
- Log.log.debug{"searching #{current_item[:path]}".bg_green}
199
+ Log.log.debug{"Exploring #{current_item[:path]}".bg_green}
184
200
  # get folder content
185
201
  folder_contents =
186
202
  begin
@@ -192,19 +208,21 @@ module Aspera
192
208
  Log.log.debug{Log.dump(:folder_contents, folder_contents)}
193
209
  folder_contents.each do |entry|
194
210
  relative_path = File.join(current_item[:path], entry['name'])
195
- Log.log.debug{"process_folder_tree checking #{relative_path}"}
196
- # continue only if method returns true
197
- next unless yield(entry, relative_path, state)
211
+ Log.log.debug{"process_folder_tree: checking #{relative_path}"}
212
+ # call block, continue only if method returns true
213
+ next unless send(method_sym, entry, relative_path, state)
198
214
  # entry type is file, folder or link
199
215
  case entry['type']
200
216
  when 'folder'
201
217
  folders_to_explore.push({id: entry['id'], path: relative_path})
202
218
  when 'link'
203
- node_id_to_node(entry['target_node_id'])&.process_folder_tree(
204
- state: state,
205
- top_file_id: entry['target_id'],
206
- top_file_path: relative_path,
207
- &block)
219
+ if entry_has_link_information(entry)
220
+ node_id_to_node(entry['target_node_id'])&.process_folder_tree(
221
+ method_sym: method_sym,
222
+ state: state,
223
+ top_file_id: entry['target_id'],
224
+ top_file_path: relative_path)
225
+ end
208
226
  end
209
227
  end
210
228
  end
@@ -216,60 +234,23 @@ module Aspera
216
234
  # @return [Hash] {.api,.file_id}
217
235
  def resolve_api_fid(top_file_id, path)
218
236
  Aspera.assert_type(top_file_id, String)
237
+ Aspera.assert_type(path, String)
238
+ # if last element is a link and followed by "/", we list the content of that folder, else we return the link
219
239
  process_last_link = path.end_with?(PATH_SEPARATOR)
240
+ # keep only non-empty elements
220
241
  path_elements = path.split(PATH_SEPARATOR).reject(&:empty?)
221
242
  return {api: self, file_id: top_file_id} if path_elements.empty?
222
- resolve_state = {path: path_elements, result: nil}
223
- process_folder_tree(state: resolve_state, top_file_id: top_file_id) do |entry, _path, state|
224
- # this block is called recursively for each entry in folder
225
- # stop digging here if not in right path
226
- next false unless entry['name'].eql?(state[:path].first)
227
- # ok it matches, so we remove the match
228
- state[:path].shift
229
- case entry['type']
230
- when 'file'
231
- # file must be terminal
232
- raise "#{entry['name']} is a file, expecting folder to find: #{state[:path]}" unless state[:path].empty?
233
- # it's terminal, we found it
234
- state[:result] = {api: self, file_id: entry['id']}
235
- next false
236
- when 'folder'
237
- if state[:path].empty?
238
- # we found it
239
- state[:result] = {api: self, file_id: entry['id']}
240
- next false
241
- end
242
- when 'link'
243
- if state[:path].empty?
244
- if process_last_link
245
- # we found it
246
- other_node = node_id_to_node(entry['target_node_id'])
247
- raise 'cannot resolve link' if other_node.nil?
248
- state[:result] = {api: other_node, file_id: entry['target_id']}
249
- else
250
- # we found it but we do not process the link
251
- state[:result] = {api: self, file_id: entry['id']}
252
- end
253
- next false
254
- end
255
- else
256
- Log.log.warn{"Unknown element type: #{entry['type']}"}
257
- end
258
- # continue to dig folder
259
- next true
260
- end
243
+ resolve_state = {path: path_elements, result: nil, process_last_link: process_last_link}
244
+ process_folder_tree(method_sym: :process_api_fid, state: resolve_state, top_file_id: top_file_id)
261
245
  raise "entry not found: #{resolve_state[:path]}" if resolve_state[:result].nil?
246
+ Log.log.debug{"resolve_api_fid: #{path} -> #{resolve_state[:result][:api].base_url} #{resolve_state[:result][:file_id]}"}
262
247
  return resolve_state[:result]
263
248
  end
264
249
 
265
250
  def find_files(top_file_id, test_block)
266
251
  Log.log.debug{"find_files: file id=#{top_file_id}"}
267
252
  find_state = {found: [], test_block: test_block}
268
- process_folder_tree(state: find_state, top_file_id: top_file_id) do |entry, path, state|
269
- state[:found].push(entry.merge({'path' => path})) if state[:test_block].call(entry)
270
- # test all files deeply
271
- true
272
- end
253
+ process_folder_tree(method_sym: :process_find_files, state: find_state, top_file_id: top_file_id)
273
254
  return find_state[:found]
274
255
  end
275
256
 
@@ -306,7 +287,7 @@ module Aspera
306
287
  ak_name = params[:headers][HEADER_X_ASPERA_ACCESS_KEY]
307
288
  # TODO: token_generation_lambda = lambda{|do_refresh|oauth.token(refresh: do_refresh)}
308
289
  # get bearer token, possibly use cache
309
- ak_token = oauth.token(refresh: false)
290
+ ak_token = oauth.token
310
291
  else Aspera.error_unexpected_value(auth_params[:type])
311
292
  end
312
293
  transfer_spec = {
@@ -352,6 +333,58 @@ module Aspera
352
333
  unless transfer_spec['remote_user'].eql?(Transfer::Spec::ACCESS_KEY_TRANSFER_USER)
353
334
  return transfer_spec
354
335
  end
336
+
337
+ private
338
+
339
+ def process_api_fid(entry, path, state)
340
+ # this block is called recursively for each entry in folder
341
+ # stop digging here if not in right path
342
+ return false unless entry['name'].eql?(state[:path].first)
343
+ # ok it matches, so we remove the match, and continue digging
344
+ state[:path].shift
345
+ path_fully_consumed = state[:path].empty?
346
+ case entry['type']
347
+ when 'file'
348
+ # file must be terminal
349
+ raise "#{entry['name']} is a file, expecting folder to find: #{state[:path]}" unless path_fully_consumed
350
+ # it's terminal, we found it
351
+ Log.log.debug{"resolve_api_fid: found #{path} -> #{entry['id']}"}
352
+ state[:result] = {api: self, file_id: entry['id']}
353
+ return false
354
+ when 'folder'
355
+ if path_fully_consumed
356
+ # we found it
357
+ state[:result] = {api: self, file_id: entry['id']}
358
+ return false
359
+ end
360
+ when 'link'
361
+ if path_fully_consumed
362
+ if state[:process_last_link]
363
+ # we found it
364
+ other_node = nil
365
+ if entry_has_link_information(entry)
366
+ other_node = node_id_to_node(entry['target_node_id'])
367
+ end
368
+ raise 'Cannot resolve link' if other_node.nil?
369
+ state[:result] = {api: other_node, file_id: entry['target_id']}
370
+ else
371
+ # we found it but we do not process the link
372
+ state[:result] = {api: self, file_id: entry['id']}
373
+ end
374
+ return false
375
+ end
376
+ else
377
+ Log.log.warn{"Unknown element type: #{entry['type']}"}
378
+ end
379
+ # continue to dig folder
380
+ return true
381
+ end
382
+
383
+ def process_find_files(entry, _path, state)
384
+ state[:found].push(entry.merge({'path' => path})) if state[:test_block].call(entry)
385
+ # test all files deeply
386
+ return true
387
+ end
355
388
  end
356
389
  end
357
390
  end
@@ -44,7 +44,7 @@ module Aspera
44
44
  app_root: File.join('C:', 'Program Files', 'Aspera', 'Enterprise Server'),
45
45
  log_root: File.join('C:', 'Program Files', 'Aspera', 'Enterprise Server', 'var', 'log')
46
46
  }]
47
- when Aspera::Environment::OS_X then [{
47
+ when Aspera::Environment::OS_MACOS then [{
48
48
  expected: CONNECT,
49
49
  app_root: File.join(Dir.home, 'Applications', 'Aspera Connect.app'),
50
50
  log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera_Connect'),
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # cspell:ignore csvt jsonpp
3
+ # cspell:ignore csvt jsonpp stdbin
4
4
  require 'aspera/uri_reader'
5
5
  require 'aspera/environment'
6
6
  require 'aspera/log'
@@ -17,11 +17,6 @@ module Aspera
17
17
  class ExtendedValue
18
18
  include Singleton
19
19
 
20
- # special values
21
- INIT = 'INIT'
22
- ALL = 'ALL'
23
- DEF = 'DEF'
24
-
25
20
  MARKER_START = '@'
26
21
  MARKER_END = ':'
27
22
  MARKER_IN_END = '@'
@@ -74,10 +69,22 @@ module Aspera
74
69
  zlib: lambda{|v|Zlib::Inflate.inflate(v)},
75
70
  extend: lambda{|v|ExtendedValue.instance.evaluate_all(v)}
76
71
  }
72
+ @default_decoder = nil
73
+ end
74
+
75
+ # Regex to match an extended value
76
+ def handler_regex_string
77
+ "#{MARKER_START}(#{modifiers.join('|')})#{MARKER_END}"
77
78
  end
78
79
 
79
80
  public
80
81
 
82
+ def default_decoder=(value)
83
+ Log.log.debug{"setting default decoder to #{value} (#{value.class})"}
84
+ Aspera.assert(value.nil? || @handlers.key?(value))
85
+ @default_decoder = value
86
+ end
87
+
81
88
  def modifiers; @handlers.keys; end
82
89
 
83
90
  # add a new handler
@@ -87,16 +94,13 @@ module Aspera
87
94
  @handlers[name] = method
88
95
  end
89
96
 
90
- # Regex to match an extended value
91
- def ext_re
92
- "#{MARKER_START}(#{modifiers.join('|')})#{MARKER_END}"
93
- end
94
-
95
- # parse an option value if it is a String using supported extended value modifiers
97
+ # parse an string value to extended value, if it is a String using supported extended value modifiers
96
98
  # other value types are returned as is
99
+ # @param value [String] the value to parse
100
+ # @param expect [Class,Array] one or a list of expected types
97
101
  def evaluate(value)
98
102
  return value unless value.is_a?(String)
99
- regex = Regexp.new("^#{ext_re}(.*)$", Regexp::MULTILINE)
103
+ regex = Regexp.new("^#{handler_regex_string}(.*)$", Regexp::MULTILINE)
100
104
  # first determine decoders, in reversed order
101
105
  handlers_reversed = []
102
106
  while (m = value.match(regex))
@@ -113,9 +117,18 @@ module Aspera
113
117
  return value
114
118
  end
115
119
 
120
+ # parse string value as extended value
121
+ # use default decoder if none is specified
122
+ def evaluate_with_default(value)
123
+ if value.is_a?(String) && value.match(/^#{handler_regex_string}.*$/).nil? && !@default_decoder.nil?
124
+ value = [MARKER_START, @default_decoder, MARKER_END, value].join
125
+ end
126
+ return evaluate(value)
127
+ end
128
+
116
129
  # find inner extended values
117
130
  def evaluate_all(value)
118
- regex = Regexp.new("^(.*)#{ext_re}([^#{MARKER_IN_END}]*)#{MARKER_IN_END}(.*)$", Regexp::MULTILINE)
131
+ regex = Regexp.new("^(.*)#{handler_regex_string}([^#{MARKER_IN_END}]*)#{MARKER_IN_END}(.*)$", Regexp::MULTILINE)
119
132
  while (m = value.match(regex))
120
133
  sub_value = "@#{m[2]}:#{m[3]}"
121
134
  Log.log.debug{"evaluating #{sub_value}"}
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # cspell:ignore jsonpp
4
+ require 'aspera/cli/special_values'
4
5
  require 'aspera/preview/terminal'
5
6
  require 'aspera/secret_hider'
6
7
  require 'aspera/environment'
@@ -110,7 +111,7 @@ module Aspera
110
111
  class << self
111
112
  def all_but(list)
112
113
  list = [list] unless list.is_a?(Array)
113
- return list.map{|i|"#{FIELDS_LESS}#{i}"}.unshift(ExtendedValue::ALL)
114
+ return list.map{|i|"#{FIELDS_LESS}#{i}"}.unshift(SpecialValues::ALL)
114
115
  end
115
116
 
116
117
  def tick(yes)
@@ -207,9 +208,9 @@ module Aspera
207
208
  options.declare(:output, 'Destination for results', types: String, handler: {o: self, m: :option_handler})
208
209
  options.declare(:display, 'Output only some information', values: DISPLAY_LEVELS, handler: {o: self, m: :option_handler}, default: :info)
209
210
  options.declare(
210
- :fields, "Comma separated list of: fields, or #{ExtendedValue::ALL}, or #{ExtendedValue::DEF}", handler: {o: self, m: :option_handler},
211
+ :fields, "Comma separated list of: fields, or #{SpecialValues::ALL}, or #{SpecialValues::DEF}", handler: {o: self, m: :option_handler},
211
212
  types: [String, Array, Regexp, Proc],
212
- default: ExtendedValue::DEF)
213
+ default: SpecialValues::DEF)
213
214
  options.declare(:select, 'Select only some items in lists: column, value', types: [Hash, Proc], handler: {o: self, m: :option_handler})
214
215
  options.declare(:table_style, 'Table display style', types: [Hash], handler: {o: self, m: :option_handler}, default: default_table_style)
215
216
  options.declare(:flat_hash, 'Display deep values as additional keys', values: :bool, handler: {o: self, m: :option_handler}, default: true)
@@ -256,7 +257,7 @@ module Aspera
256
257
  # the requested list of fields, but if can contain special values
257
258
  request =
258
259
  case @options[:fields]
259
- # when NilClass then [ExtendedValue::DEF]
260
+ # when NilClass then [SpecialValues::DEF]
260
261
  when String then @options[:fields].split(',')
261
262
  when Array then @options[:fields]
262
263
  when Regexp then return all_fields(data).select{|i|i.match(@options[:fields])}
@@ -272,10 +273,10 @@ module Aspera
272
273
  item = item[1..-1]
273
274
  end
274
275
  case item
275
- when ExtendedValue::ALL
276
+ when SpecialValues::ALL
276
277
  # get the list of all column names used in all lines, not just first one, as all lines may have different columns
277
278
  request.unshift(*all_fields(data))
278
- when ExtendedValue::DEF
279
+ when SpecialValues::DEF
279
280
  default = all_fields(data).select{|i|default.call(i)} if default.is_a?(Proc)
280
281
  default = all_fields(data) if default.nil?
281
282
  request.unshift(*default)
@@ -293,11 +294,11 @@ module Aspera
293
294
  # filter the list of items on the fields option
294
295
  def filter_list_on_fields(data)
295
296
  # by default, keep all data intact
296
- return data if @options[:fields].eql?(ExtendedValue::DEF) && @options[:select].nil?
297
+ return data if @options[:fields].eql?(SpecialValues::DEF) && @options[:select].nil?
297
298
  Aspera.assert_type(data, Array){'Filtering fields or select requires result is an Array of Hash'}
298
299
  Aspera.assert(data.all?(Hash)){'Filtering fields or select requires result is an Array of Hash'}
299
300
  filter_columns_on_select(data)
300
- return data if @options[:fields].eql?(ExtendedValue::DEF)
301
+ return data if @options[:fields].eql?(SpecialValues::DEF)
301
302
  selected_fields = compute_fields(data, @options[:fields])
302
303
  return data.map{|i|i[selected_fields.first]} if selected_fields.length == 1
303
304
  return data.map{|i|i.select{|k, _|selected_fields.include?(k)}}
@@ -358,8 +359,8 @@ module Aspera
358
359
  raise URI::InvalidURIError, 'not uri' if !(blob =~ /\A#{URI::DEFAULT_PARSER.make_regexp}\z/)
359
360
  # it's a url
360
361
  url = blob
361
- unless OpenApplication.instance.url_method.eql?(:text)
362
- OpenApplication.instance.uri(url)
362
+ unless Environment.instance.url_method.eql?(:text)
363
+ Environment.instance.open_uri(url)
363
364
  return ''
364
365
  end
365
366
  # remote_image = Rest.new(base_url: url).read('')
@@ -93,11 +93,11 @@ module Aspera
93
93
  @plug_init[:only_manual] = false
94
94
  # create formatter, in case there is an exception, it is used to display.
95
95
  @plug_init[:formatter] = Formatter.new
96
- @plug_init[:options] = Manager.new(PROGRAM_NAME)
97
- # give command line arguments to option manager
98
- options.parse_command_line(@argv)
96
+ # create command line manager with arguments
97
+ @plug_init[:options] = Manager.new(PROGRAM_NAME, @argv)
99
98
  # formatter adds options
100
- formatter.declare_options(options)
99
+ @plug_init[:formatter].declare_options(options)
100
+ ExtendedValue.instance.default_decoder = options.get_option(:struct_parser)
101
101
  # compare $0 with expected name
102
102
  current_prog_name = File.basename($PROGRAM_NAME)
103
103
  formatter.display_message(
@@ -162,9 +162,9 @@ module Aspera
162
162
  options.declare(:version, 'Display version', values: :none, short: 'v') { formatter.display_message(:data, Cli::VERSION); Process.exit(0) } # rubocop:disable Style/Semicolon, Layout/LineLength
163
163
  options.declare(
164
164
  :ui, 'Method to start browser',
165
- values: OpenApplication::USER_INTERFACES,
166
- handler: {o: OpenApplication.instance, m: :url_method},
167
- default: OpenApplication.default_gui_mode)
165
+ values: Environment::USER_INTERFACES,
166
+ handler: {o: Environment.instance, m: :url_method},
167
+ default: Environment.default_gui_mode)
168
168
  options.declare(:log_level, 'Log level', values: Log.levels, handler: {o: Log.instance, m: :level})
169
169
  options.declare(:logger, 'Logging method', values: Log::LOG_TYPES, handler: {o: Log.instance, m: :logger_type})
170
170
  options.declare(:lock_port, 'Prevent dual execution of a command, e.g. in cron', coerce: Integer, types: Integer)
@@ -189,7 +189,7 @@ module Aspera
189
189
  end
190
190
 
191
191
  def generate_bash_completion
192
- if options.get_next_argument('', expected: :multiple, mandatory: false).nil?
192
+ if options.get_next_argument('', multiple: true, mandatory: false).nil?
193
193
  PluginFactory.instance.plugin_list.each{|p|puts p}
194
194
  else
195
195
  Log.log.warn('only first level completion so far')
@@ -197,11 +197,11 @@ module Aspera
197
197
  Process.exit(0)
198
198
  end
199
199
 
200
- def exit_with_usage(all_plugins)
201
- Log.log.debug('exit_with_usage'.bg_red)
200
+ def exit_with_usage(include_all_plugins)
201
+ Log.log.debug{"exit_with_usage(#{include_all_plugins})".bg_red}
202
202
  # display main plugin options
203
203
  formatter.display_message(:error, options.parser)
204
- if all_plugins
204
+ if include_all_plugins
205
205
  # list plugins that have a "require" field, i.e. all but main plugin
206
206
  PluginFactory.instance.plugin_list.each do |plugin_name_sym|
207
207
  next if plugin_name_sym.eql?(COMMAND_CONFIG)