aspera-cli 4.16.0 → 4.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +50 -19
  4. data/CONTRIBUTING.md +3 -1
  5. data/README.md +965 -793
  6. data/bin/asession +29 -21
  7. data/lib/aspera/{fasp/agent_alpha.rb → agent/alpha.rb} +26 -25
  8. data/lib/aspera/{fasp/agent_base.rb → agent/base.rb} +15 -12
  9. data/lib/aspera/{fasp/agent_connect.rb → agent/connect.rb} +13 -11
  10. data/lib/aspera/{fasp/agent_direct.rb → agent/direct.rb} +49 -53
  11. data/lib/aspera/{fasp/agent_httpgw.rb → agent/httpgw.rb} +20 -19
  12. data/lib/aspera/{fasp/agent_node.rb → agent/node.rb} +20 -33
  13. data/lib/aspera/{fasp/agent_trsdk.rb → agent/trsdk.rb} +11 -11
  14. data/lib/aspera/api/aoc.rb +586 -0
  15. data/lib/aspera/api/ats.rb +46 -0
  16. data/lib/aspera/api/cos_node.rb +95 -0
  17. data/lib/aspera/api/node.rb +344 -0
  18. data/lib/aspera/ascmd.rb +46 -10
  19. data/lib/aspera/{fasp → ascp}/installation.rb +5 -5
  20. data/lib/aspera/{fasp → ascp}/management.rb +3 -8
  21. data/lib/aspera/{fasp → ascp}/products.rb +1 -1
  22. data/lib/aspera/assert.rb +30 -30
  23. data/lib/aspera/cli/basic_auth_plugin.rb +11 -10
  24. data/lib/aspera/cli/extended_value.rb +1 -1
  25. data/lib/aspera/cli/formatter.rb +13 -13
  26. data/lib/aspera/cli/hints.rb +5 -5
  27. data/lib/aspera/cli/main.rb +35 -28
  28. data/lib/aspera/cli/manager.rb +25 -24
  29. data/lib/aspera/cli/plugin.rb +22 -15
  30. data/lib/aspera/cli/plugin_factory.rb +61 -0
  31. data/lib/aspera/cli/plugins/alee.rb +7 -7
  32. data/lib/aspera/cli/plugins/aoc.rb +83 -77
  33. data/lib/aspera/cli/plugins/ats.rb +32 -33
  34. data/lib/aspera/cli/plugins/bss.rb +3 -4
  35. data/lib/aspera/cli/plugins/config.rb +169 -186
  36. data/lib/aspera/cli/plugins/console.rb +8 -6
  37. data/lib/aspera/cli/plugins/cos.rb +19 -18
  38. data/lib/aspera/cli/plugins/faspex.rb +61 -54
  39. data/lib/aspera/cli/plugins/faspex5.rb +150 -103
  40. data/lib/aspera/cli/plugins/node.rb +68 -73
  41. data/lib/aspera/cli/plugins/orchestrator.rb +34 -44
  42. data/lib/aspera/cli/plugins/preview.rb +31 -31
  43. data/lib/aspera/cli/plugins/server.rb +31 -33
  44. data/lib/aspera/cli/plugins/shares.rb +13 -11
  45. data/lib/aspera/cli/sync_actions.rb +8 -8
  46. data/lib/aspera/cli/transfer_agent.rb +32 -19
  47. data/lib/aspera/cli/transfer_progress.rb +1 -1
  48. data/lib/aspera/cli/version.rb +1 -1
  49. data/lib/aspera/colors.rb +5 -0
  50. data/lib/aspera/command_line_builder.rb +14 -14
  51. data/lib/aspera/coverage.rb +1 -2
  52. data/lib/aspera/data_repository.rb +1 -1
  53. data/lib/aspera/environment.rb +2 -3
  54. data/lib/aspera/faspex_gw.rb +5 -6
  55. data/lib/aspera/faspex_postproc.rb +1 -1
  56. data/lib/aspera/id_generator.rb +2 -2
  57. data/lib/aspera/json_rpc.rb +5 -5
  58. data/lib/aspera/keychain/encrypted_hash.rb +6 -6
  59. data/lib/aspera/keychain/macos_security.rb +27 -22
  60. data/lib/aspera/log.rb +2 -2
  61. data/lib/aspera/nagios.rb +3 -3
  62. data/lib/aspera/node_simulator.rb +5 -6
  63. data/lib/aspera/oauth/base.rb +143 -0
  64. data/lib/aspera/oauth/factory.rb +124 -0
  65. data/lib/aspera/oauth/generic.rb +34 -0
  66. data/lib/aspera/oauth/jwt.rb +51 -0
  67. data/lib/aspera/oauth/url_json.rb +31 -0
  68. data/lib/aspera/oauth/web.rb +50 -0
  69. data/lib/aspera/oauth.rb +5 -331
  70. data/lib/aspera/open_application.rb +7 -7
  71. data/lib/aspera/persistency_action_once.rb +4 -4
  72. data/lib/aspera/persistency_folder.rb +2 -2
  73. data/lib/aspera/preview/generator.rb +5 -5
  74. data/lib/aspera/preview/terminal.rb +3 -2
  75. data/lib/aspera/preview/utils.rb +3 -3
  76. data/lib/aspera/proxy_auto_config.rb +4 -4
  77. data/lib/aspera/rest.rb +175 -144
  78. data/lib/aspera/rest_errors_aspera.rb +3 -3
  79. data/lib/aspera/resumer.rb +77 -0
  80. data/lib/aspera/ssh.rb +6 -1
  81. data/lib/aspera/{fasp → transfer}/error.rb +3 -3
  82. data/lib/aspera/{fasp → transfer}/error_info.rb +1 -1
  83. data/lib/aspera/{fasp → transfer}/faux_file.rb +1 -1
  84. data/lib/aspera/{fasp → transfer}/parameters.rb +58 -89
  85. data/lib/aspera/{fasp/transfer_spec.rb → transfer/spec.rb} +18 -16
  86. data/lib/aspera/{fasp/parameters.yaml → transfer/spec.yaml} +4 -99
  87. data/lib/aspera/{fasp → transfer}/sync.rb +32 -32
  88. data/lib/aspera/{fasp → transfer}/uri.rb +9 -8
  89. data/lib/aspera/web_server_simple.rb +11 -3
  90. data.tar.gz.sig +0 -0
  91. metadata +36 -63
  92. metadata.gz.sig +0 -0
  93. data/lib/aspera/aoc.rb +0 -601
  94. data/lib/aspera/ats_api.rb +0 -47
  95. data/lib/aspera/cos_node.rb +0 -94
  96. data/lib/aspera/fasp/resume_policy.rb +0 -79
  97. data/lib/aspera/node.rb +0 -339
data/lib/aspera/assert.rb CHANGED
@@ -6,40 +6,40 @@ module Aspera
6
6
 
7
7
  class AssertError < StandardError
8
8
  end
9
- end
10
-
11
- class Object
12
- def assert(assertion, info = nil, level: 2, exception_class: Aspera::AssertError)
13
- raise Aspera::InternalError, 'bad assert: both info and block given' unless info.nil? || !block_given?
14
- return if assertion
15
- message = 'assertion failed'
16
- info = yield if block_given?
17
- message = "#{message}: #{info}" if info
18
- message = "#{message}: #{caller(level..level).first}"
19
- raise exception_class, message
20
- end
9
+ class << self
10
+ # the block is executed in the context of the Aspera module
11
+ def assert(assertion, info = nil, level: 2, exception_class: AssertError)
12
+ raise InternalError, 'bad assert: both info and block given' unless info.nil? || !block_given?
13
+ return if assertion
14
+ message = 'assertion failed'
15
+ info = yield if block_given?
16
+ message = "#{message}: #{info}" if info
17
+ message = "#{message}: #{caller(level..level).first}"
18
+ raise exception_class, message
19
+ end
21
20
 
22
- # assert that value has the given type
23
- # @param value [Object] the value to check
24
- # @param type [Class] the expected type
25
- def assert_type(value, type, exception_class: Aspera::AssertError)
26
- assert(value.is_a?(type), level: 3, exception_class: exception_class){"#{block_given? ? "#{yield}: " : nil}expecting #{type}, but have #{value.inspect}"}
27
- end
21
+ # assert that value has the given type
22
+ # @param value [Object] the value to check
23
+ # @param type [Class] the expected type
24
+ def assert_type(value, type, exception_class: AssertError)
25
+ assert(value.is_a?(type), level: 3, exception_class: exception_class){"#{block_given? ? "#{yield}: " : nil}expecting #{type}, but have #{value.inspect}"}
26
+ end
28
27
 
29
- # assert that value is one of the given values
30
- def assert_values(value, values, exception_class: Aspera::AssertError)
31
- assert(values.include?(value), level: 3, exception_class: exception_class) do
32
- "#{block_given? ? "#{yield}: " : nil}expecting one of #{values.inspect}, but have #{value.inspect}"
28
+ # assert that value is one of the given values
29
+ def assert_values(value, values, exception_class: AssertError)
30
+ assert(values.include?(value), level: 3, exception_class: exception_class) do
31
+ "#{block_given? ? "#{yield}: " : nil}expecting one of #{values.inspect}, but have #{value.inspect}"
32
+ end
33
33
  end
34
- end
35
34
 
36
- # the line with this shall never be reached
37
- def error_unreachable_line
38
- raise Aspera::InternalError, "unreachable line reached: #{caller(2..2).first}"
39
- end
35
+ # the line with this shall never be reached
36
+ def error_unreachable_line
37
+ raise InternalError, "unreachable line reached: #{caller(2..2).first}"
38
+ end
40
39
 
41
- # the value is not one of the expected values
42
- def error_unexpected_value(value, exception_class: Aspera::InternalError)
43
- raise exception_class, "#{block_given? ? "#{yield}: " : nil}unexpected value: #{value.inspect}"
40
+ # the value is not one of the expected values
41
+ def error_unexpected_value(value, exception_class: InternalError)
42
+ raise exception_class, "#{block_given? ? "#{yield}: " : nil}unexpected value: #{value.inspect}"
43
+ end
44
44
  end
45
45
  end
@@ -6,22 +6,23 @@ require 'aspera/cli/plugin'
6
6
  module Aspera
7
7
  module Cli
8
8
  # base class for applications supporting basic authentication
9
- class BasicAuthPlugin < Aspera::Cli::Plugin
9
+ class BasicAuthPlugin < Cli::Plugin
10
10
  class << self
11
- @@basic_options_declared = false # rubocop:disable Style/ClassVars
12
- def declare_options(options, force: false)
13
- return if @@basic_options_declared && !force
14
- @@basic_options_declared = true # rubocop:disable Style/ClassVars
11
+ #@@basic_options_declared = false # rubocop:disable Style/ClassVars
12
+ def declare_options(options) # , force: false
13
+ #return if @@basic_options_declared && !force
14
+ #@@basic_options_declared = true # rubocop:disable Style/ClassVars
15
15
  options.declare(:url, 'URL of application, e.g. https://faspex.example.com/aspera/faspex')
16
- options.declare(:username, 'Username to log in')
16
+ options.declare(:username, "User's name to log in")
17
17
  options.declare(:password, "User's password")
18
18
  options.parse_options!
19
19
  end
20
20
  end
21
21
 
22
- def initialize(env)
23
- super(env)
24
- BasicAuthPlugin.declare_options(options, force: env[:all_manuals])
22
+ def initialize(basic_options: true, **env)
23
+ super(**env)
24
+ # , force: env[:all_manuals]
25
+ BasicAuthPlugin.declare_options(options) if basic_options
25
26
  end
26
27
 
27
28
  # returns a Rest object with basic auth
@@ -38,7 +39,7 @@ module Aspera
38
39
  end
39
40
 
40
41
  def basic_auth_api(subpath=nil)
41
- return Rest.new(basic_auth_params(subpath))
42
+ return Rest.new(**basic_auth_params(subpath))
42
43
  end
43
44
  end # BasicAuthPlugin
44
45
  end # Cli
@@ -78,7 +78,7 @@ module Aspera
78
78
  # add a new handler
79
79
  def set_handler(name, method)
80
80
  Log.log.debug{"setting handler for #{name}"}
81
- assert_type(name, Symbol){'name'}
81
+ Aspera.assert_type(name, Symbol){'name'}
82
82
  @handlers[name] = method
83
83
  end
84
84
 
@@ -20,7 +20,7 @@ module Aspera
20
20
 
21
21
  # General method
22
22
  def flatten(something)
23
- assert_type(something, Hash)
23
+ Aspera.assert_type(something, Hash)
24
24
  @result = {}
25
25
  flatten_any(something, '')
26
26
  return @result
@@ -107,7 +107,7 @@ module Aspera
107
107
  class << self
108
108
  # Highlight special values
109
109
  def special(what, use_colors: $stdout.isatty)
110
- result = "<#{what}>"
110
+ result = $stdout.isatty ? "<#{what}>" : "&lt;#{what}&gt;"
111
111
  if use_colors
112
112
  result = if %w[null empty].any?{|s|what.include?(s)}
113
113
  result.dim
@@ -158,7 +158,7 @@ module Aspera
158
158
  end
159
159
 
160
160
  def option_handler(option_symbol, operation, value=nil)
161
- assert_values(operation, %i[set get])
161
+ Aspera.assert_values(operation, %i[set get])
162
162
  case operation
163
163
  when :set
164
164
  @options[option_symbol] = value
@@ -170,7 +170,7 @@ module Aspera
170
170
  end
171
171
  end
172
172
  when :get then return @options[option_symbol]
173
- else error_unreachable_line
173
+ else Aspera.error_unreachable_line
174
174
  end
175
175
  nil
176
176
  end
@@ -199,7 +199,7 @@ module Aspera
199
199
  when :data then $stdout.puts(message) unless @options[:display].eql?(:error)
200
200
  when :info then $stdout.puts(message) if @options[:display].eql?(:info)
201
201
  when :error then $stderr.puts(message)
202
- else error_unexpected_value(message_level)
202
+ else Aspera.error_unexpected_value(message_level)
203
203
  end
204
204
  end
205
205
 
@@ -232,7 +232,7 @@ module Aspera
232
232
  when Array then @options[:fields]
233
233
  when Regexp then return all_fields(data).select{|i|i.match(@options[:fields])}
234
234
  when Proc then return all_fields(data).select{|i|@options[:fields].call(i)}
235
- else error_unexpected_value(@options[:fields])
235
+ else Aspera.error_unexpected_value(@options[:fields])
236
236
  end
237
237
  result = []
238
238
  until request.empty?
@@ -265,7 +265,7 @@ module Aspera
265
265
  # object_array: array of hash
266
266
  # fields: list of column names
267
267
  def display_table(object_array, fields)
268
- assert(!fields.nil?){'missing fields parameter'}
268
+ Aspera.assert(!fields.nil?){'missing fields parameter'}
269
269
  case @options[:select]
270
270
  when Proc
271
271
  object_array.select!{|i|@options[:select].call(i)}
@@ -309,10 +309,10 @@ module Aspera
309
309
 
310
310
  # this method displays the results, especially the table format
311
311
  def display_results(results)
312
- assert_type(results, Hash)
313
- assert((results.keys - RESULT_PARAMS).empty?){"result unsupported key: #{results.keys - RESULT_PARAMS}"}
314
- assert(results.key?(:type)){"result must have type (#{results})"}
315
- assert(results.key?(:data) || %i[empty nothing].include?(results[:type])){'result must have data'}
312
+ Aspera.assert_type(results, Hash)
313
+ Aspera.assert((results.keys - RESULT_PARAMS).empty?){"result unsupported key: #{results.keys - RESULT_PARAMS}"}
314
+ Aspera.assert(results.key?(:type)){"result must have type (#{results})"}
315
+ Aspera.assert(results.key?(:data) || %i[empty nothing].include?(results[:type])){'result must have data'}
316
316
  Log.log.debug{"display_results: #{results[:data].class} #{results[:type]}"}
317
317
  display_item_count(results[:data].length, results[:total]) if results.key?(:total)
318
318
  SecretHider.deep_remove_secret(results[:data]) unless @options[:show_secrets] || @options[:display].eql?(:data)
@@ -336,8 +336,8 @@ module Aspera
336
336
  when :object_list, :single_object
337
337
  obj_list = results[:data]
338
338
  obj_list = [obj_list] if results[:type].eql?(:single_object)
339
- assert_type(obj_list, Array)
340
- assert(obj_list.all?(Hash)){"expecting Array of Hash: #{obj_list.inspect}"}
339
+ Aspera.assert_type(obj_list, Array)
340
+ Aspera.assert(obj_list.all?(Hash)){"expecting Array of Hash: #{obj_list.inspect}"}
341
341
  # :object_list is an array of hash tables, where key=colum name
342
342
  obj_list = obj_list.map{|obj|Flattener.new.flatten(obj)} if @options[:flat_hash]
343
343
  display_table(obj_list, compute_fields(obj_list, results[:fields]))
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'aspera/fasp/error'
3
+ require 'aspera/transfer/error'
4
4
  require 'aspera/rest'
5
5
  require 'aspera/log'
6
6
  require 'aspera/assert'
@@ -14,7 +14,7 @@ module Aspera
14
14
  # Well know issues that users may get
15
15
  ERROR_HINTS = [
16
16
  {
17
- exception: Fasp::Error,
17
+ exception: Transfer::Error,
18
18
  match: 'Remote host is not who we expected',
19
19
  remediation: [
20
20
  'For this specific error, refer to:',
@@ -24,7 +24,7 @@ module Aspera
24
24
  ]
25
25
  },
26
26
  {
27
- exception: Aspera::RestCallError,
27
+ exception: RestCallError,
28
28
  match: /Signature has expired/,
29
29
  remediation: [
30
30
  'There is too much time difference between your computer and the server',
@@ -60,13 +60,13 @@ module Aspera
60
60
  matches = hint[:match]
61
61
  matches = [matches] unless matches.is_a?(Array)
62
62
  matches.each do |m|
63
- assert_values(m.class, [String, Regexp])
63
+ Aspera.assert_values(m.class, [String, Regexp])
64
64
  case m
65
65
  when String
66
66
  next unless message.eql?(m)
67
67
  when Regexp
68
68
  next unless message.match?(m)
69
- else error_unexpected_value(m)
69
+ else Aspera.error_unexpected_value(m)
70
70
  end
71
71
  remediation = hint[:remediation]
72
72
  remediation = [remediation] unless remediation.is_a?(Array)
@@ -4,6 +4,7 @@ require 'aspera/cli/manager'
4
4
  require 'aspera/cli/formatter'
5
5
  require 'aspera/cli/plugins/config'
6
6
  require 'aspera/cli/extended_value'
7
+ require 'aspera/cli/plugin_factory'
7
8
  require 'aspera/cli/transfer_agent'
8
9
  require 'aspera/cli/version'
9
10
  require 'aspera/cli/info'
@@ -19,6 +20,9 @@ module Aspera
19
20
  class Main
20
21
  # Plugins store transfer result using this key and use result_transfer_multiple()
21
22
  STATUS_FIELD = 'status'
23
+ CONF_PLUGIN_SYM = :config
24
+
25
+ private_constant :CONF_PLUGIN_SYM
22
26
 
23
27
  class << self
24
28
  # expect some list, but nothing to display
@@ -69,7 +73,7 @@ module Aspera
69
73
 
70
74
  # shortcuts helpers like in plugins
71
75
  %i[options transfer config formatter persistency].each do |name|
72
- define_method(name){@agents[name]}
76
+ define_method(name){@plug_init[name]}
73
77
  end
74
78
 
75
79
  # =============================================================
@@ -80,7 +84,7 @@ module Aspera
80
84
  def initialize(argv)
81
85
  @argv = argv
82
86
  # environment provided to plugin for various capabilities
83
- @agents = {}
87
+ @plug_init = Plugin::INIT_PARAMS.each_with_object({}) { |key, hash| hash[key] = nil }
84
88
  @option_help = false
85
89
  @option_show_config = false
86
90
  @bash_completion = false
@@ -88,11 +92,12 @@ module Aspera
88
92
 
89
93
  # This can throw exception if there is a problem with the environment, needs to be caught by execute method
90
94
  def init_agents_and_options
95
+ @plug_init[:only_manual] = false
91
96
  # create formatter, in case there is an exception, it is used to display.
92
- @agents[:formatter] = Formatter.new
97
+ @plug_init[:formatter] = Formatter.new
93
98
  # second : manage debug level (allows debugging of option parser)
94
99
  early_debug_setup
95
- @agents[:options] = Manager.new(PROGRAM_NAME)
100
+ @plug_init[:options] = Manager.new(PROGRAM_NAME)
96
101
  # give command line arguments to option manager
97
102
  options.parse_command_line(@argv)
98
103
  # formatter adds options
@@ -105,11 +110,14 @@ module Aspera
105
110
  # declare and parse global options
106
111
  declare_global_options
107
112
  # the Config plugin adds the @preset parser, so declare before TransferAgent which may use it
108
- @agents[:config] = Plugins::Config.new(@agents, gem: GEM_NAME, name: PROGRAM_NAME, help: DOC_URL, version: Aspera::Cli::VERSION)
113
+ @plug_init[:config] = Plugins::Config.new(**@plug_init, gem: GEM_NAME, name: PROGRAM_NAME, help: DOC_URL, version: Cli::VERSION)
114
+ @plug_init[:persistency] = @plug_init[:config].persistency
109
115
  # data persistency
110
- assert(@agents[:persistency]){'missing persistency object'}
116
+ Aspera.assert(@plug_init[:persistency]){'missing persistency object'}
111
117
  # the TransferAgent plugin may use the @preset parser
112
- @agents[:transfer] = TransferAgent.new(options, config)
118
+ @plug_init[:config].transfer = @plug_init[:transfer] = TransferAgent.new(options, config)
119
+ nil_keys = @plug_init.select{|_, value|value.nil?}.keys
120
+ Aspera.assert(nil_keys.empty?){"nil : #{nil_keys}"}
113
121
  Log.log.debug('plugin env created'.red)
114
122
  # set banner when all environment is created so that additional extended value modifiers are known, e.g. @preset
115
123
  options.parser.banner = app_banner
@@ -119,7 +127,7 @@ module Aspera
119
127
  t = ' ' * 8
120
128
  return <<~END_OF_BANNER
121
129
  NAME
122
- #{t}#{PROGRAM_NAME} -- a command line tool for Aspera Applications (v#{Aspera::Cli::VERSION})
130
+ #{t}#{PROGRAM_NAME} -- a command line tool for Aspera Applications (v#{Cli::VERSION})
123
131
 
124
132
  SYNOPSIS
125
133
  #{t}#{PROGRAM_NAME} COMMANDS [OPTIONS] [ARGS]
@@ -155,7 +163,7 @@ module Aspera
155
163
  options.declare(:help, 'Show this message', values: :none, short: 'h') { @option_help = true }
156
164
  options.declare(:bash_comp, 'Generate bash completion for command', values: :none) { @bash_completion = true }
157
165
  options.declare(:show_config, 'Display parameters used for the provided action', values: :none) { @option_show_config = true }
158
- options.declare(:version, 'Display version', values: :none, short: 'v') { formatter.display_message(:data, Aspera::Cli::VERSION); Process.exit(0) } # rubocop:disable Style/Semicolon, Layout/LineLength
166
+ options.declare(:version, 'Display version', values: :none, short: 'v') { formatter.display_message(:data, Cli::VERSION); Process.exit(0) } # rubocop:disable Style/Semicolon, Layout/LineLength
159
167
  options.declare(:warnings, 'Check for language warnings', values: :none, short: 'w') { $VERBOSE = true }
160
168
  options.declare(
161
169
  :ui, 'Method to start browser',
@@ -177,20 +185,19 @@ module Aspera
177
185
  # also loads the plugin options, and default values from conf file
178
186
  # @param plugin_name_sym : symbol for plugin name
179
187
  def get_plugin_instance_with_options(plugin_name_sym, env=nil)
180
- env ||= @agents
188
+ env ||= @plug_init
181
189
  Log.log.debug{"get_plugin_instance_with_options(#{plugin_name_sym})"}
182
- require config.plugins[plugin_name_sym][:require_stanza]
190
+ require PluginFactory.instance.plugins[plugin_name_sym][:require_stanza]
183
191
  # load default params only if no param already loaded before plugin instantiation
184
192
  env[:config].add_plugin_default_preset(plugin_name_sym)
185
- command_plugin = Plugins::Config.plugin_class(plugin_name_sym).new(env)
193
+ command_plugin = PluginFactory.instance.create(plugin_name_sym, **env)
186
194
  Log.log.debug{"got #{command_plugin.class}"}
187
- # TODO: check that ancestor is Plugin?
188
195
  return command_plugin
189
196
  end
190
197
 
191
198
  def generate_bash_completion
192
199
  if options.get_next_argument('', expected: :multiple, mandatory: false).nil?
193
- config.plugins.each_key{|p|puts p.to_s}
200
+ PluginFactory.instance.plugins.each_key{|p|puts p}
194
201
  else
195
202
  Log.log.warn('only first level completion so far')
196
203
  end
@@ -203,11 +210,11 @@ module Aspera
203
210
  formatter.display_message(:error, options.parser)
204
211
  if all_plugins
205
212
  # list plugins that have a "require" field, i.e. all but main plugin
206
- config.plugins.each_key do |plugin_name_sym|
207
- next if plugin_name_sym.eql?(Plugins::Config::CONF_PLUGIN_SYM)
213
+ PluginFactory.instance.plugins.each_key do |plugin_name_sym|
214
+ next if plugin_name_sym.eql?(CONF_PLUGIN_SYM)
208
215
  # override main option parser with a brand new, to avoid having global options
209
- plugin_env = @agents.clone
210
- plugin_env[:all_manuals] = true # force declaration of all options
216
+ plugin_env = @plug_init.clone
217
+ plugin_env[:only_manual] = true # force declaration of all options
211
218
  plugin_env[:options] = Manager.new(PROGRAM_NAME)
212
219
  plugin_env[:options].parser.banner = '' # remove default banner
213
220
  get_plugin_instance_with_options(plugin_name_sym, plugin_env)
@@ -223,12 +230,12 @@ module Aspera
223
230
  # early debug for parser
224
231
  # Note: does not accept shortcuts
225
232
  def early_debug_setup
226
- Aspera::Log.instance.program_name = PROGRAM_NAME
233
+ Log.instance.program_name = PROGRAM_NAME
227
234
  @argv.each do |arg|
228
235
  case arg
229
236
  when '--' then break
230
- when /^--log-level=(.*)/ then Aspera::Log.instance.level = Regexp.last_match(1).to_sym
231
- when /^--logger=(.*)/ then Aspera::Log.instance.logger_type = Regexp.last_match(1).to_sym
237
+ when /^--log-level=(.*)/ then Log.instance.level = Regexp.last_match(1).to_sym
238
+ when /^--logger=(.*)/ then Log.instance.logger_type = Regexp.last_match(1).to_sym
232
239
  end
233
240
  rescue => e
234
241
  $stderr.puts("Error: #{e}")
@@ -247,16 +254,16 @@ module Aspera
247
254
  begin
248
255
  init_agents_and_options
249
256
  # find plugins, shall be after parse! ?
250
- config.add_plugins_from_lookup_folders
257
+ PluginFactory.instance.add_plugins_from_lookup_folders
251
258
  # help requested without command ? (plugins must be known here)
252
259
  exit_with_usage(true) if @option_help && options.command_or_arg_empty?
253
260
  generate_bash_completion if @bash_completion
254
261
  config.periodic_check_newer_gem_version
255
262
  command_sym =
256
263
  if @option_show_config && options.command_or_arg_empty?
257
- Plugins::Config::CONF_PLUGIN_SYM
264
+ CONF_PLUGIN_SYM
258
265
  else
259
- options.get_next_command(config.plugins.keys.dup.unshift(:help))
266
+ options.get_next_command(PluginFactory.instance.plugins.keys.dup.unshift(:help))
260
267
  end
261
268
  # command will not be executed, but we need manual
262
269
  options.fail_on_missing_mandatory = false if @option_help || @option_show_config
@@ -264,7 +271,7 @@ module Aspera
264
271
  case command_sym
265
272
  when :help
266
273
  exit_with_usage(true)
267
- when Plugins::Config::CONF_PLUGIN_SYM
274
+ when CONF_PLUGIN_SYM
268
275
  command_plugin = config
269
276
  else
270
277
  # get plugin, set options, etc
@@ -307,8 +314,8 @@ module Aspera
307
314
  rescue Cli::BadArgument => e; exception_info = {e: e, t: 'Argument', usage: true}
308
315
  rescue Cli::NoSuchIdentifier => e; exception_info = {e: e, t: 'Identifier'}
309
316
  rescue Cli::Error => e; exception_info = {e: e, t: 'Tool', usage: true}
310
- rescue Fasp::Error => e; exception_info = {e: e, t: 'Transfer'}
311
- rescue Aspera::RestCallError => e; exception_info = {e: e, t: 'Rest'}
317
+ rescue Transfer::Error => e; exception_info = {e: e, t: 'Transfer'}
318
+ rescue RestCallError => e; exception_info = {e: e, t: 'Rest'}
312
319
  rescue SocketError => e; exception_info = {e: e, t: 'Network'}
313
320
  rescue StandardError => e; exception_info = {e: e, t: "Other(#{e.class.name})", debug: true}
314
321
  rescue Interrupt => e; exception_info = {e: e, t: 'Interruption', debug: true}
@@ -317,7 +324,7 @@ module Aspera
317
324
  TempFileManager.instance.cleanup
318
325
  # 1- processing of error condition
319
326
  unless exception_info.nil?
320
- Log.log.warn(exception_info[:e].message) if Aspera::Log.instance.logger_type.eql?(:syslog) && exception_info[:security]
327
+ Log.log.warn(exception_info[:e].message) if Log.instance.logger_type.eql?(:syslog) && exception_info[:security]
321
328
  formatter.display_message(:error, "#{Formatter::ERROR_FLASH} #{exception_info[:t]}: #{exception_info[:e].message}")
322
329
  formatter.display_message(:error, 'Use option -h to get help.') if exception_info[:usage]
323
330
  # Is that a known error condition with proposal for remediation ?
@@ -21,7 +21,7 @@ module Aspera
21
21
  @option_name = option_name
22
22
  @has_writer = @object.respond_to?(writer_method)
23
23
  Log.log.debug{"AttrAccessor: #{@option_name}: #{@object.class}.#{@method}: writer=#{@has_writer}"}
24
- assert(@object.respond_to?(@method)) {"#{object} does not respond to #{method_name}"}
24
+ Aspera.assert(@object.respond_to?(@method)) {"#{object} does not respond to #{method_name}"}
25
25
  end
26
26
 
27
27
  def value
@@ -61,7 +61,7 @@ module Aspera
61
61
 
62
62
  class << self
63
63
  def enum_to_bool(enum)
64
- assert_values(enum, BOOLEAN_VALUES){'boolean'}
64
+ Aspera.assert_values(enum, BOOLEAN_VALUES){'boolean'}
65
65
  return TRUE_VALUES.include?(enum)
66
66
  end
67
67
 
@@ -75,8 +75,8 @@ module Aspera
75
75
  matching_exact = allowed_values.select{|i| i.to_s.eql?(short_value)}
76
76
  return matching_exact.first if matching_exact.length == 1
77
77
  matching = allowed_values.select{|i| i.to_s.start_with?(short_value)}
78
- multi_choice_assert(!matching.empty?,"unknown value for #{descr}: #{short_value}", allowed_values)
79
- multi_choice_assert(matching.length.eql?(1),"ambiguous shortcut for #{descr}: #{short_value}", matching)
78
+ multi_choice_assert(!matching.empty?, "unknown value for #{descr}: #{short_value}", allowed_values)
79
+ multi_choice_assert(matching.length.eql?(1), "ambiguous shortcut for #{descr}: #{short_value}", matching)
80
80
  return enum_to_bool(matching.first) if allowed_values.eql?(BOOLEAN_VALUES)
81
81
  return matching.first
82
82
  end
@@ -84,8 +84,8 @@ module Aspera
84
84
  # Generates error message with list of allowed values
85
85
  # @param error_msg [String] error message
86
86
  # @param choices [Array] list of allowed values
87
- def multi_choice_assert(assertion,error_msg, choices)
88
- raise Cli::BadArgument, [error_msg, 'Use:'].concat(choices.map{|c|"- #{c}"}.sort).join("\n") unless assertion
87
+ def multi_choice_assert(assertion, error_msg, choices)
88
+ raise Cli::BadArgument, [error_msg, 'Use:'].concat(choices.map{|c|"- #{c}"}.sort).join("\n") unless assertion
89
89
  end
90
90
 
91
91
  # change option name with dash to name with underscore
@@ -103,7 +103,7 @@ module Aspera
103
103
  # @param type_list [NilClass, Class, Array[Class]] accepted value type(s)
104
104
  def validate_type(what, descr, value, type_list)
105
105
  return nil if type_list.nil?
106
- assert(type_list.is_a?(Array) && type_list.all?(Class)){'types must be a Class Array'}
106
+ Aspera.assert(type_list.is_a?(Array) && type_list.all?(Class)){'types must be a Class Array'}
107
107
  raise Cli::BadArgument,
108
108
  "#{what.to_s.capitalize} #{descr} is a #{value.class} but must be #{type_list.length > 1 ? 'one of ' : ''}#{type_list.map(&:name).join(',')}" unless \
109
109
  type_list.any?{|t|value.is_a?(t)}
@@ -181,14 +181,15 @@ module Aspera
181
181
  # @param default [Object] default value
182
182
  # @return value, list or nil
183
183
  def get_next_argument(descr, expected: :single, mandatory: true, type: nil, aliases: nil, default: nil)
184
- assert(%i[single multiple].include?(expected) || (expected.is_a?(Array) && expected.all?(Symbol))){'expected must be single, multiple, or array of symbol'}
185
- assert(type.nil? || type.is_a?(Class) || (type.is_a?(Array) && type.all?(Class))){'type must be Class or Array of Class'}
186
- assert(aliases.nil? || (aliases.is_a?(Hash) && aliases.keys.all?(Symbol) && aliases.values.all?(Symbol))){'aliases must be Hash'}
184
+ Aspera.assert(%i[single multiple].include?(expected) || (expected.is_a?(Array) && expected.all?(Symbol))) do
185
+ 'expected must be single, multiple, or array of symbol'
186
+ end
187
+ Aspera.assert(type.nil? || type.is_a?(Class) || (type.is_a?(Array) && type.all?(Class))){'type must be Class or Array of Class'}
188
+ Aspera.assert(aliases.nil? || (aliases.is_a?(Hash) && aliases.keys.all?(Symbol) && aliases.values.all?(Symbol))){'aliases must be Hash'}
187
189
  allowed_types = type
188
190
  unless allowed_types.nil?
189
191
  allowed_types = [allowed_types] unless allowed_types.is_a?(Array)
190
192
  descr = "#{descr} (#{allowed_types.join(', ')})"
191
- Log.log.debug{">>>> #{descr}=#{allowed_types}"}
192
193
  end
193
194
  result =
194
195
  if !@unprocessed_cmd_line_arguments.empty?
@@ -207,7 +208,7 @@ module Aspera
207
208
  allowed_values = [].concat(expected)
208
209
  allowed_values.concat(aliases.keys) unless aliases.nil?
209
210
  self.class.get_from_list(@unprocessed_cmd_line_arguments.shift, descr, allowed_values)
210
- else error_unexpected_value(expected)
211
+ else Aspera.error_unexpected_value(expected)
211
212
  end
212
213
  elsif !default.nil? then default
213
214
  # no value provided, either get value interactively, or exception
@@ -232,7 +233,7 @@ module Aspera
232
233
  # @param mandatory [Boolean] if true, raise error if option not set
233
234
  def get_option(option_symbol, mandatory: false, default: nil)
234
235
  attributes = @declared_options[option_symbol]
235
- assert(attributes){"option not declared: #{option_symbol}"}
236
+ Aspera.assert(attributes){"option not declared: #{option_symbol}"}
236
237
  result = nil
237
238
  case attributes[:read_write]
238
239
  when :accessor
@@ -295,10 +296,10 @@ module Aspera
295
296
  # @param types [Class, Array] accepted value type(s)
296
297
  # @param block [Proc] block to execute when option is found
297
298
  def declare(option_symbol, description, handler: nil, default: nil, values: nil, short: nil, coerce: nil, types: nil, deprecation: nil, &block)
298
- assert(!@declared_options.key?(option_symbol)){"#{option_symbol} already declared"}
299
- assert(description[-1] != '.'){"#{option_symbol} ends with dot"}
300
- assert(description[0] == description[0].upcase){"#{option_symbol} description does not start with capital"}
301
- assert(!['hash', 'extended value'].any?{|s|description.downcase.include?(s) }){"#{option_symbol} shall use :types"}
299
+ Aspera.assert(!@declared_options.key?(option_symbol)){"#{option_symbol} already declared"}
300
+ Aspera.assert(description[-1] != '.'){"#{option_symbol} ends with dot"}
301
+ Aspera.assert(description[0] == description[0].upcase){"#{option_symbol} description does not start with capital"}
302
+ Aspera.assert(!['hash', 'extended value'].any?{|s|description.downcase.include?(s) }){"#{option_symbol} shall use :types"}
302
303
  opt = @declared_options[option_symbol] = {
303
304
  read_write: handler.nil? ? :value : :accessor,
304
305
  # by default passwords and secrets are sensitive, else specify when declaring the option
@@ -306,7 +307,7 @@ module Aspera
306
307
  }
307
308
  if !types.nil?
308
309
  types = [types] unless types.is_a?(Array)
309
- assert(types.all?(Class)){"types must be Array of Class: #{types}"}
310
+ Aspera.assert(types.all?(Class)){"types must be Array of Class: #{types}"}
310
311
  opt[:types] = types
311
312
  description = "#{description} (#{types.map(&:name).join(', ')})"
312
313
  end
@@ -316,8 +317,8 @@ module Aspera
316
317
  end
317
318
  Log.log.debug{"declare: #{option_symbol}: #{opt[:read_write]}".green}
318
319
  if opt[:read_write].eql?(:accessor)
319
- assert_type(handler, Hash)
320
- assert(handler.keys.sort.eql?(%i[m o]))
320
+ Aspera.assert_type(handler, Hash)
321
+ Aspera.assert(handler.keys.sort.eql?(%i[m o]))
321
322
  Log.log.debug{"set attr obj #{option_symbol} (#{handler[:o]},#{handler[:m]})"}
322
323
  opt[:accessor] = AttrAccessor.new(handler[:o], handler[:m], option_symbol)
323
324
  end
@@ -356,11 +357,11 @@ module Aspera
356
357
  set_option(option_symbol, time_string, SOURCE_USER)
357
358
  end
358
359
  when :none
359
- assert(!block.nil?){"missing block for #{option_symbol}"}
360
+ Aspera.assert(!block.nil?){"missing block for #{option_symbol}"}
360
361
  on_args.push(symbol_to_option(option_symbol, nil))
361
362
  on_args.push("-#{short}") if short.is_a?(String)
362
363
  @parser.on(*on_args, &block)
363
- else error_unexpected_value(values)
364
+ else Aspera.error_unexpected_value(values)
364
365
  end
365
366
  Log.log.debug{"on_args=#{on_args}"}
366
367
  end
@@ -368,7 +369,7 @@ module Aspera
368
369
  # Adds each of the keys of specified hash as an option
369
370
  # @param preset_hash [Hash] hash of options to add
370
371
  def add_option_preset(preset_hash, op: :push)
371
- assert_type(preset_hash, Hash)
372
+ Aspera.assert_type(preset_hash, Hash)
372
373
  Log.log.debug{"add_option_preset=#{preset_hash}"}
373
374
  # incremental override
374
375
  preset_hash.each{|k, v|@unprocessed_defaults.send(op, [k.to_sym, v])}
@@ -470,7 +471,7 @@ module Aspera
470
471
  def get_interactive(type, descr, expected: :single)
471
472
  if !@ask_missing_mandatory
472
473
  raise Cli::BadArgument, "missing argument (#{expected}): #{descr}" unless expected.is_a?(Array)
473
- self.class.multi_choice_assert(false,"missing: #{descr}", expected)
474
+ self.class.multi_choice_assert(false, "missing: #{descr}", expected)
474
475
  end
475
476
  result = nil
476
477
  sensitive = type.eql?(:option) && @declared_options[descr.to_sym].is_a?(Hash) && @declared_options[descr.to_sym][:sensitive]