aspera-cli 4.4.0 → 4.7.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. data/README.md +2095 -1503
  3. data/bin/ascli +2 -1
  4. data/bin/asession +4 -5
  5. data/docs/test_env.conf +3 -0
  6. data/examples/aoc.rb +4 -3
  7. data/examples/faspex4.rb +25 -25
  8. data/examples/proxy.pac +1 -1
  9. data/examples/transfer.rb +17 -17
  10. data/lib/aspera/aoc.rb +238 -185
  11. data/lib/aspera/ascmd.rb +93 -83
  12. data/lib/aspera/ats_api.rb +11 -10
  13. data/lib/aspera/cli/basic_auth_plugin.rb +13 -14
  14. data/lib/aspera/cli/extended_value.rb +42 -33
  15. data/lib/aspera/cli/formater.rb +142 -108
  16. data/lib/aspera/cli/info.rb +17 -0
  17. data/lib/aspera/cli/listener/line_dump.rb +3 -2
  18. data/lib/aspera/cli/listener/logger.rb +2 -1
  19. data/lib/aspera/cli/listener/progress.rb +16 -18
  20. data/lib/aspera/cli/listener/progress_multi.rb +18 -21
  21. data/lib/aspera/cli/main.rb +173 -149
  22. data/lib/aspera/cli/manager.rb +163 -168
  23. data/lib/aspera/cli/plugin.rb +43 -31
  24. data/lib/aspera/cli/plugins/alee.rb +6 -6
  25. data/lib/aspera/cli/plugins/aoc.rb +405 -370
  26. data/lib/aspera/cli/plugins/ats.rb +86 -79
  27. data/lib/aspera/cli/plugins/bss.rb +14 -16
  28. data/lib/aspera/cli/plugins/config.rb +580 -362
  29. data/lib/aspera/cli/plugins/console.rb +23 -19
  30. data/lib/aspera/cli/plugins/cos.rb +18 -18
  31. data/lib/aspera/cli/plugins/faspex.rb +201 -158
  32. data/lib/aspera/cli/plugins/faspex5.rb +80 -57
  33. data/lib/aspera/cli/plugins/node.rb +183 -166
  34. data/lib/aspera/cli/plugins/orchestrator.rb +71 -67
  35. data/lib/aspera/cli/plugins/preview.rb +92 -96
  36. data/lib/aspera/cli/plugins/server.rb +79 -75
  37. data/lib/aspera/cli/plugins/shares.rb +35 -19
  38. data/lib/aspera/cli/plugins/sync.rb +20 -22
  39. data/lib/aspera/cli/transfer_agent.rb +76 -113
  40. data/lib/aspera/cli/version.rb +2 -1
  41. data/lib/aspera/colors.rb +35 -27
  42. data/lib/aspera/command_line_builder.rb +48 -34
  43. data/lib/aspera/cos_node.rb +29 -21
  44. data/lib/aspera/data_repository.rb +3 -2
  45. data/lib/aspera/environment.rb +50 -45
  46. data/lib/aspera/fasp/{manager.rb → agent_base.rb} +28 -25
  47. data/lib/aspera/fasp/{connect.rb → agent_connect.rb} +52 -43
  48. data/lib/aspera/fasp/{local.rb → agent_direct.rb} +58 -72
  49. data/lib/aspera/fasp/{http_gw.rb → agent_httpgw.rb} +37 -43
  50. data/lib/aspera/fasp/{node.rb → agent_node.rb} +35 -16
  51. data/lib/aspera/fasp/agent_trsdk.rb +104 -0
  52. data/lib/aspera/fasp/error.rb +2 -1
  53. data/lib/aspera/fasp/error_info.rb +68 -52
  54. data/lib/aspera/fasp/installation.rb +152 -124
  55. data/lib/aspera/fasp/listener.rb +1 -0
  56. data/lib/aspera/fasp/parameters.rb +87 -92
  57. data/lib/aspera/fasp/parameters.yaml +305 -249
  58. data/lib/aspera/fasp/resume_policy.rb +11 -14
  59. data/lib/aspera/fasp/transfer_spec.rb +26 -0
  60. data/lib/aspera/fasp/uri.rb +22 -21
  61. data/lib/aspera/faspex_gw.rb +55 -89
  62. data/lib/aspera/hash_ext.rb +4 -3
  63. data/lib/aspera/id_generator.rb +8 -7
  64. data/lib/aspera/keychain/encrypted_hash.rb +121 -0
  65. data/lib/aspera/keychain/macos_security.rb +90 -0
  66. data/lib/aspera/log.rb +55 -37
  67. data/lib/aspera/nagios.rb +13 -12
  68. data/lib/aspera/node.rb +30 -25
  69. data/lib/aspera/oauth.rb +175 -226
  70. data/lib/aspera/open_application.rb +4 -3
  71. data/lib/aspera/persistency_action_once.rb +6 -6
  72. data/lib/aspera/persistency_folder.rb +5 -9
  73. data/lib/aspera/preview/file_types.rb +6 -5
  74. data/lib/aspera/preview/generator.rb +25 -24
  75. data/lib/aspera/preview/options.rb +16 -14
  76. data/lib/aspera/preview/utils.rb +98 -98
  77. data/lib/aspera/{proxy_auto_config.erb.js → proxy_auto_config.js} +23 -31
  78. data/lib/aspera/proxy_auto_config.rb +111 -20
  79. data/lib/aspera/rest.rb +154 -135
  80. data/lib/aspera/rest_call_error.rb +2 -2
  81. data/lib/aspera/rest_error_analyzer.rb +23 -25
  82. data/lib/aspera/rest_errors_aspera.rb +15 -14
  83. data/lib/aspera/ssh.rb +12 -10
  84. data/lib/aspera/sync.rb +42 -41
  85. data/lib/aspera/temp_file_manager.rb +18 -14
  86. data/lib/aspera/timer_limiter.rb +2 -1
  87. data/lib/aspera/uri_reader.rb +7 -5
  88. data/lib/aspera/web_auth.rb +79 -76
  89. metadata +116 -29
  90. data/docs/Makefile +0 -66
  91. data/docs/README.erb.md +0 -3973
  92. data/docs/README.md +0 -13
  93. data/docs/diagrams.txt +0 -49
  94. data/docs/doc_tools.rb +0 -58
  95. data/lib/aspera/api_detector.rb +0 -60
  96. data/lib/aspera/cli/plugins/shares2.rb +0 -114
  97. data/lib/aspera/secrets.rb +0 -20
@@ -1,119 +1,179 @@
1
+ # frozen_string_literal: true
1
2
  require 'aspera/cli/manager'
2
3
  require 'aspera/cli/formater'
3
4
  require 'aspera/cli/plugins/config'
4
5
  require 'aspera/cli/extended_value'
5
6
  require 'aspera/cli/transfer_agent'
6
7
  require 'aspera/cli/version'
8
+ require 'aspera/cli/info'
9
+ require 'aspera/fasp/error'
7
10
  require 'aspera/open_application'
8
11
  require 'aspera/temp_file_manager'
9
12
  require 'aspera/persistency_folder'
10
13
  require 'aspera/log'
11
14
  require 'aspera/rest'
12
15
  require 'aspera/nagios'
13
- require 'aspera/secrets'
16
+ require 'aspera/colors'
14
17
 
15
18
  module Aspera
16
19
  module Cli
17
20
  # The main CLI class
18
21
  class Main
22
+ # prefix to display error messages
23
+ ERROR_FLASH='ERROR:'.bg_red.gray.blink.freeze
24
+ private_constant :ERROR_FLASH
19
25
 
20
- attr_reader :plugin_env
21
- private
22
- # name of application, also foldername where config is stored
23
- PROGRAM_NAME = 'ascli'
24
- # name of the containing gem, same as in <gem name>.gemspec
25
- GEM_NAME = 'aspera-cli'
26
- HELP_URL = "http://www.rubydoc.info/gems/#{GEM_NAME}"
27
- GEM_URL = "https://rubygems.org/gems/#{GEM_NAME}"
28
- SRC_URL = "https://github.com/IBM/aspera-cli"
26
+ # store transfer result using this key and use result_transfer_multiple
29
27
  STATUS_FIELD = 'status'
30
28
 
31
- private_constant :PROGRAM_NAME,:GEM_NAME,:HELP_URL,:GEM_URL
29
+ class << self
30
+ # expect some list, but nothing to display
31
+ def result_empty; return {type: :empty, data: :nil}; end
32
+
33
+ # nothing expected
34
+ def result_nothing; return {type: :nothing, data: :nil}; end
35
+
36
+ def result_status(status); return {type: :status, data: status}; end
37
+
38
+ def result_success; return result_status('complete'); end
39
+
40
+ # Process statuses of finished transfer sessions
41
+ # raise exception if there is one error
42
+ # else returns an empty status
43
+ def result_transfer(statuses)
44
+ worst=TransferAgent.session_status(statuses)
45
+ raise worst unless worst.eql?(:success)
46
+ return Main.result_nothing
47
+ end
48
+
49
+ # used when one command executes several transfer jobs (each job being possibly multi session)
50
+ # @param status_table [Array] [{STATUS_FIELD=>[status array],...},...]
51
+ # @return a status object suitable as command result
52
+ # each element has a key STATUS_FIELD which contains the result of possibly multiple sessions
53
+ def result_transfer_multiple(status_table)
54
+ global_status=:success
55
+ # transform status array into string and find if there was problem
56
+ status_table.each do |item|
57
+ worst=TransferAgent.session_status(item[STATUS_FIELD])
58
+ global_status=worst unless worst.eql?(:success)
59
+ item[STATUS_FIELD]=item[STATUS_FIELD].map(&:to_s).join(',')
60
+ end
61
+ raise global_status unless global_status.eql?(:success)
62
+ return {type: :object_list,data: status_table}
63
+ end
64
+ end
65
+
66
+ private
67
+
32
68
  # =============================================================
33
69
  # Parameter handlers
34
70
  #
35
- def option_insecure; Rest.insecure ; end
36
-
37
- def option_insecure=(value); Rest.insecure = value; end
71
+ attr_accessor :option_insecure, :option_http_options, :option_cache_tokens
38
72
 
39
73
  def option_ui; OpenApplication.instance.url_method; end
40
74
 
41
75
  def option_ui=(value); OpenApplication.instance.url_method=value; end
42
76
 
77
+ # called everytime a new REST HTTP session is opened
78
+ # @param http [Net::HTTP] the newly created http session object
79
+ def http_parameters=(http)
80
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @option_insecure
81
+ http.set_debug_output($stdout) if @option_rest_debug
82
+ raise 'http_options expects Hash' unless @option_http_options.is_a?(Hash)
83
+
84
+ @option_http_options.each do |k,v|
85
+ method="#{k}=".to_sym
86
+ # check if accessor is a method of Net::HTTP
87
+ # continue_timeout= read_timeout= write_timeout=
88
+ if http.respond_to?(method)
89
+ http.send(method,v)
90
+ else
91
+ Log.log.error("no such attribute: #{k}")
92
+ end
93
+ end
94
+ end
95
+
43
96
  # minimum initialization
44
97
  def initialize(argv)
45
98
  # first thing : manage debug level (allows debugging of option parser)
46
99
  early_debug_setup(argv)
47
100
  # compare $0 with expected name
48
101
  current_prog_name=File.basename($PROGRAM_NAME)
49
- unless current_prog_name.eql?(PROGRAM_NAME)
50
- @plugin_env[:formater].display_message(:error,"#{"WARNING".bg_red.blink.gray} Please use '#{PROGRAM_NAME}' instead of '#{current_prog_name}', '#{current_prog_name}' will be removed in a future version")
51
- end
102
+ @plugin_env[:formater].display_message(:error,"#{'WARNING'.bg_red.blink.gray} Please use '#{PROGRAM_NAME}' instead of '#{current_prog_name}'") unless current_prog_name.eql?(PROGRAM_NAME)
52
103
  @option_help=false
53
104
  @bash_completion=false
54
105
  @option_show_config=false
106
+ @option_insecure=false
107
+ @option_rest_debug=false
108
+ @option_cache_tokens=true
109
+ @option_http_options={}
55
110
  # environment provided to plugin for various capabilities
56
111
  @plugin_env={}
57
- # find out application main folder
58
- app_main_folder=ENV[conf_dir_env_var]
59
- # if env var undefined or empty
60
- if app_main_folder.nil? or app_main_folder.empty?
61
- user_home_folder=Dir.home
62
- raise CliError,"Home folder does not exist: #{user_home_folder}. Check your user environment or use #{conf_dir_env_var}." unless Dir.exist?(user_home_folder)
63
- app_main_folder=File.join(user_home_folder,Plugins::Config::ASPERA_HOME_FOLDER_NAME,PROGRAM_NAME)
64
- end
65
- # give command line arguments to option manager (no parsing)
66
- @plugin_env[:options]=@opt_mgr=Manager.new(PROGRAM_NAME,argv,app_banner())
112
+ # give command line arguments to option manager
113
+ @plugin_env[:options]=@opt_mgr=Manager.new(PROGRAM_NAME,argv)
114
+ # formatter adds options
67
115
  @plugin_env[:formater]=Formater.new(@plugin_env[:options])
68
116
  Rest.user_agent=PROGRAM_NAME
117
+ Rest.session_cb=lambda{|http|self.http_parameters=http}
69
118
  # declare and parse global options
70
119
  init_global_options()
71
- # secret manager
72
- @plugin_env[:secret]=Aspera::Secrets.new
73
- # the Config plugin adds the @preset parser
74
- @plugin_env[:config]=Plugins::Config.new(@plugin_env,PROGRAM_NAME,HELP_URL,Aspera::Cli::VERSION,app_main_folder)
120
+ # the Config plugin adds the @preset parser, so declare before TransferAgent which may use it
121
+ @plugin_env[:config]=Plugins::Config.new(@plugin_env, gem: GEM_NAME, name: PROGRAM_NAME, help: DOC_URL, version: Aspera::Cli::VERSION)
75
122
  # the TransferAgent plugin may use the @preset parser
76
- @plugin_env[:transfer]=TransferAgent.new(@plugin_env)
77
- # set application folder for modules
123
+ @plugin_env[:transfer]=TransferAgent.new(@plugin_env[:options],@plugin_env[:config])
124
+ # data persistency
78
125
  @plugin_env[:persistency]=PersistencyFolder.new(File.join(@plugin_env[:config].main_folder,'persist_store'))
79
126
  Log.log.debug('plugin env created'.red)
80
- Oauth.persist_mgr=@plugin_env[:persistency]
127
+ Oauth.persist_mgr=@plugin_env[:persistency] if @option_cache_tokens
81
128
  Fasp::Parameters.file_list_folder=File.join(@plugin_env[:config].main_folder,'filelists')
82
129
  Aspera::RestErrorAnalyzer.instance.log_file=File.join(@plugin_env[:config].main_folder,'rest_exceptions.log')
83
130
  # register aspera REST call error handlers
84
- Aspera::RestErrorsAspera.registerHandlers
131
+ Aspera::RestErrorsAspera.register_handlers
132
+ # set banner when all environment is created so that additional extended value modifiers are known, e.g. @preset
133
+ @opt_mgr.parser.banner=app_banner
85
134
  end
86
135
 
87
136
  def app_banner
88
- banner = "NAME\n\t#{PROGRAM_NAME} -- a command line tool for Aspera Applications (v#{Aspera::Cli::VERSION})\n\n"
89
- banner << "SYNOPSIS\n"
90
- banner << "\t#{PROGRAM_NAME} COMMANDS [OPTIONS] [ARGS]\n"
91
- banner << "\nDESCRIPTION\n"
92
- banner << "\tUse Aspera application to perform operations on command line.\n"
93
- banner << "\tDocumentation and examples: #{GEM_URL}\n"
94
- banner << "\texecute: #{PROGRAM_NAME} conf doc\n"
95
- banner << "\tor visit: #{HELP_URL}\n"
96
- banner << "\nENVIRONMENT VARIABLES\n"
97
- banner << "\t#{conf_dir_env_var} config folder, default: $HOME/#{Plugins::Config::ASPERA_HOME_FOLDER_NAME}/#{PROGRAM_NAME}\n"
98
- banner << "\t#any option can be set as an environment variable, refer to the manual\n"
99
- banner << "\nCOMMANDS\n"
100
- banner << "\tTo list first level commands, execute: #{PROGRAM_NAME}\n"
101
- banner << "\tNote that commands can be written shortened (provided it is unique).\n"
102
- banner << "\nOPTIONS\n"
103
- banner << "\tOptions begin with a '-' (minus), and value is provided on command line.\n"
104
- banner << "\tSpecial values are supported beginning with special prefix, like: #{ExtendedValue.instance.modifiers.map{|m|"@#{m}:"}.join(' ')}.\n"
105
- banner << "\tDates format is 'DD-MM-YY HH:MM:SS', or 'now' or '-<num>h'\n\n"
106
- banner << "ARGS\n"
107
- banner << "\tSome commands require mandatory arguments, e.g. a path.\n"
137
+ return <<~END_OF_BANNER
138
+ NAME
139
+ \t#{PROGRAM_NAME} -- a command line tool for Aspera Applications (v#{Aspera::Cli::VERSION})
140
+
141
+ SYNOPSIS
142
+ \t#{PROGRAM_NAME} COMMANDS [OPTIONS] [ARGS]
143
+
144
+ DESCRIPTION
145
+ \tUse Aspera application to perform operations on command line.
146
+ \tDocumentation and examples: #{GEM_URL}
147
+ \texecute: #{PROGRAM_NAME} conf doc
148
+ \tor visit: #{DOC_URL}
149
+ \tsource repo: #{SRC_URL}
150
+
151
+ ENVIRONMENT VARIABLES
152
+ \t#{@plugin_env[:config].conf_dir_env_var} config folder, default: $HOME/#{Plugins::Config::ASPERA_HOME_FOLDER_NAME}/#{PROGRAM_NAME}
153
+ \tAny option can be set as an environment variable, refer to the manual
154
+
155
+ COMMANDS
156
+ \tTo list first level commands, execute: #{PROGRAM_NAME}
157
+ \tNote that commands can be written shortened (provided it is unique).
158
+
159
+ OPTIONS
160
+ \tOptions begin with a '-' (minus), and value is provided on command line.
161
+ \tSpecial values are supported beginning with special prefix @pfx:, where pfx is one of:
162
+ \t#{ExtendedValue.instance.modifiers.map(&:to_s).join(', ')}
163
+ \tDates format is 'DD-MM-YY HH:MM:SS', or 'now' or '-<num>h'
164
+
165
+ ARGS
166
+ \tSome commands require mandatory arguments, e.g. a path.
167
+ END_OF_BANNER
108
168
  end
109
169
 
110
170
  # define header for manual
111
171
  def init_global_options
112
- Log.log.debug("init_global_options")
113
- @opt_mgr.add_opt_switch(:help,"-h","Show this message.") { @option_help=true }
114
- @opt_mgr.add_opt_switch(:bash_comp,"generate bash completion for command") { @bash_completion=true }
115
- @opt_mgr.add_opt_switch(:show_config, "Display parameters used for the provided action.") { @option_show_config=true }
116
- @opt_mgr.add_opt_switch(:rest_debug,"-r","more debug for HTTP calls") { Rest.debug=true }
172
+ Log.log.debug('init_global_options')
173
+ @opt_mgr.add_opt_switch(:help,'-h','Show this message.') { @option_help=true }
174
+ @opt_mgr.add_opt_switch(:bash_comp,'generate bash completion for command') { @bash_completion=true }
175
+ @opt_mgr.add_opt_switch(:show_config, 'Display parameters used for the provided action.') { @option_show_config=true }
176
+ @opt_mgr.add_opt_switch(:rest_debug,'-r','more debug for HTTP calls') { @option_rest_debug=true }
117
177
  @opt_mgr.add_opt_switch(:version,'-v','display version') { @plugin_env[:formater].display_message(:data,Aspera::Cli::VERSION);Process.exit(0) }
118
178
  @opt_mgr.add_opt_switch(:warnings,'-w','check for language warnings') { $VERBOSE=true }
119
179
  # handler must be set before declaration
@@ -121,15 +181,21 @@ module Aspera
121
181
  @opt_mgr.set_obj_attr(:logger,Log.instance,:logger_type)
122
182
  @opt_mgr.set_obj_attr(:insecure,self,:option_insecure,:no)
123
183
  @opt_mgr.set_obj_attr(:ui,self,:option_ui)
184
+ @opt_mgr.set_obj_attr(:http_options,self,:option_http_options)
185
+ @opt_mgr.set_obj_attr(:log_secrets,Log.instance,:log_secrets)
186
+ @opt_mgr.set_obj_attr(:cache_tokens,self,:option_cache_tokens)
124
187
  @opt_mgr.add_opt_list(:ui,OpenApplication.user_interfaces,'method to start browser')
125
- @opt_mgr.add_opt_list(:log_level,Log.levels,"Log level")
126
- @opt_mgr.add_opt_list(:logger,Log.logtypes,"log method")
127
- @opt_mgr.add_opt_simple(:lock_port,"prevent dual execution of a command, e.g. in cron")
128
- @opt_mgr.add_opt_simple(:query,"additional filter for API calls (extended value) (some commands)")
129
- @opt_mgr.add_opt_boolean(:insecure,"do not validate HTTPS certificate")
130
- @opt_mgr.add_opt_boolean(:once_only,"process only new items (some commands)")
188
+ @opt_mgr.add_opt_list(:log_level,Log.levels,'Log level')
189
+ @opt_mgr.add_opt_list(:logger,Log.logtypes,'log method')
190
+ @opt_mgr.add_opt_simple(:lock_port,'prevent dual execution of a command, e.g. in cron')
191
+ @opt_mgr.add_opt_simple(:query,'additional filter for API calls (extended value) (some commands)')
192
+ @opt_mgr.add_opt_simple(:http_options,'options for http socket (extended value)')
193
+ @opt_mgr.add_opt_boolean(:insecure,'do not validate HTTPS certificate')
194
+ @opt_mgr.add_opt_boolean(:once_only,'process only new items (some commands)')
195
+ @opt_mgr.add_opt_boolean(:log_secrets,'show passwords in logs')
196
+ @opt_mgr.add_opt_boolean(:cache_tokens,'save and reuse Oauth tokens')
131
197
  @opt_mgr.set_option(:ui,OpenApplication.default_gui_mode)
132
- @opt_mgr.set_option(:once_only,:false)
198
+ @opt_mgr.set_option(:once_only,false)
133
199
  # parse declared options
134
200
  @opt_mgr.parse_options!
135
201
  end
@@ -143,33 +209,23 @@ module Aspera
143
209
  require @plugin_env[:config].plugins[plugin_name_sym][:require_stanza]
144
210
  # load default params only if no param already loaded before plugin instanciation
145
211
  env[:config].add_plugin_default_preset(plugin_name_sym)
146
- command_plugin=Plugins::Config.plugin_new(plugin_name_sym,env)
212
+ command_plugin=Plugins::Config.plugin_class(plugin_name_sym).new(env)
147
213
  Log.log.debug("got #{command_plugin.class}")
148
214
  # TODO: check that ancestor is Plugin?
149
215
  return command_plugin
150
216
  end
151
217
 
152
218
  def generate_bash_completion
153
- if @opt_mgr.get_next_argument("",:multiple,:optional).nil?
219
+ if @opt_mgr.get_next_argument('',:multiple,:optional).nil?
154
220
  @plugin_env[:config].plugins.keys.each{|p|puts p.to_s}
155
221
  else
156
- Log.log.warn("only first level completion so far")
222
+ Log.log.warn('only first level completion so far')
157
223
  end
158
224
  Process.exit(0)
159
225
  end
160
226
 
161
- # expect some list, but nothing to display
162
- def self.result_empty; return {:type => :empty, :data => :nil }; end
163
-
164
- # nothing expected
165
- def self.result_nothing; return {:type => :nothing, :data => :nil }; end
166
-
167
- def self.result_status(status); return {:type => :status, :data => status }; end
168
-
169
- def self.result_success; return result_status('complete'); end
170
-
171
227
  def exit_with_usage(all_plugins)
172
- Log.log.debug("exit_with_usage".bg_red)
228
+ Log.log.debug('exit_with_usage'.bg_red)
173
229
  # display main plugin options
174
230
  @plugin_env[:formater].display_message(:error,@opt_mgr.parser)
175
231
  if all_plugins
@@ -179,10 +235,11 @@ module Aspera
179
235
  # override main option parser with a brand new, to avoid having global options
180
236
  plugin_env=@plugin_env.clone
181
237
  plugin_env[:man_only]=true
182
- plugin_env[:options]=Manager.new(PROGRAM_NAME,[],'')
238
+ plugin_env[:options]=Manager.new(PROGRAM_NAME)
239
+ plugin_env[:options].parser.banner='' # remove default banner
183
240
  get_plugin_instance_with_options(plugin_name_sym,plugin_env)
184
241
  # display generated help for plugin options
185
- @plugin_env[:formater].display_message(:error,plugin_env[:options].parser.to_s)
242
+ @plugin_env[:formater].display_message(:error,plugin_env[:options].parser.help)
186
243
  end
187
244
  end
188
245
  Process.exit(0)
@@ -190,54 +247,21 @@ module Aspera
190
247
 
191
248
  protected
192
249
 
193
- # env var name to override the app's main folder
194
- # default main folder is $HOME/<vendor main app folder>/<program name>
195
- def conf_dir_env_var
196
- return "#{PROGRAM_NAME}_home".upcase
197
- end
198
-
199
250
  # early debug for parser
200
251
  # Note: does not accept shortcuts
201
252
  def early_debug_setup(argv)
202
253
  Log.instance.program_name=PROGRAM_NAME
203
254
  argv.each do |arg|
204
255
  case arg
205
- when '--'
206
- return
207
- when /^--log-level=(.*)/
208
- Log.instance.level = $1.to_sym
209
- when /^--logger=(.*)/
210
- Log.instance.logger_type=$1.to_sym
256
+ when '--' then break
257
+ when /^--log-level=(.*)/ then Log.instance.level = Regexp.last_match(1).to_sym
258
+ when /^--logger=(.*)/ then Log.instance.logger_type=Regexp.last_match(1).to_sym
211
259
  end
212
260
  end
213
261
  end
214
262
 
215
263
  public
216
264
 
217
- # Process statuses of finished transfer sessions
218
- # raise exception if there is one error
219
- # else returns an empty status
220
- def self.result_transfer(statuses)
221
- worst=TransferAgent.session_status(statuses)
222
- raise worst unless worst.eql?(:success)
223
- return Main.result_nothing
224
- end
225
-
226
- # used when one command executes several transfer jobs (each job being possibly multi session)
227
- # @param status_table [Array] [{STATUS_FIELD=>[status array],...},...]
228
- # each element has a key STATUS_FIELD which contains the result of possibly mulmtiple sessions
229
- def self.result_transfer_multiple(status_table)
230
- global_status=:success
231
- # transform status into string and find if there was problem
232
- status_table.each do |item|
233
- worst=TransferAgent.session_status(item[STATUS_FIELD])
234
- global_status=worst unless worst.eql?(:success)
235
- item[STATUS_FIELD]=item[STATUS_FIELD].map{|i|i.to_s}.join(',')
236
- end
237
- raise global_status unless global_status.eql?(:success)
238
- return {:type=>:object_list,:data=>status_table}
239
- end
240
-
241
265
  # this is the main function called by initial script just after constructor
242
266
  def process_command_line
243
267
  Log.log.debug('process_command_line')
@@ -249,17 +273,17 @@ module Aspera
249
273
  # find plugins, shall be after parse! ?
250
274
  @plugin_env[:config].add_plugins_from_lookup_folders
251
275
  # help requested without command ? (plugins must be known here)
252
- exit_with_usage(true) if @option_help and @opt_mgr.command_or_arg_empty?
276
+ exit_with_usage(true) if @option_help && @opt_mgr.command_or_arg_empty?
253
277
  generate_bash_completion if @bash_completion
254
- # load global default options and process
255
- @plugin_env[:config].add_plugin_default_preset(Plugins::Config::CONF_GLOBAL_SYM)
256
- @opt_mgr.parse_options!
257
278
  @plugin_env[:config].periodic_check_newer_gem_version
258
- if @option_show_config and @opt_mgr.command_or_arg_empty?
259
- command_sym=Plugins::Config::CONF_PLUGIN_SYM
279
+ command_sym=
280
+ if @option_show_config && @opt_mgr.command_or_arg_empty?
281
+ Plugins::Config::CONF_PLUGIN_SYM
260
282
  else
261
- command_sym=@opt_mgr.get_next_command(@plugin_env[:config].plugins.keys.dup.unshift(:help))
283
+ @opt_mgr.get_next_command(@plugin_env[:config].plugins.keys.dup.unshift(:help))
262
284
  end
285
+ # command will not be executed, but we need manual
286
+ @opt_mgr.fail_on_missing_mandatory=false if @option_help || @option_show_config
263
287
  # main plugin is not dynamically instanciated
264
288
  case command_sym
265
289
  when :help
@@ -275,8 +299,8 @@ module Aspera
275
299
  # help requested for current plugin
276
300
  exit_with_usage(false) if @option_help
277
301
  if @option_show_config
278
- @plugin_env[:formater].display_results({:type=>:single_object,:data=>@opt_mgr.declared_options(false)})
279
- Process.exit(0)
302
+ @plugin_env[:formater].display_results({type: :single_object,data: @opt_mgr.declared_options(only_defined: true)})
303
+ execute_command=false
280
304
  end
281
305
  # locking for single execution (only after "per plugin" option, in case lock port is there)
282
306
  lock_port=@opt_mgr.get_option(:lock_port,:optional)
@@ -285,7 +309,7 @@ module Aspera
285
309
  # no need to close later, will be freed on process exit. must save in member else it is garbage collected
286
310
  Log.log.debug("Opening lock port #{lock_port.to_i}")
287
311
  @tcp_server=TCPServer.new('127.0.0.1',lock_port.to_i)
288
- rescue => e
312
+ rescue StandardError => e
289
313
  execute_command=false
290
314
  Log.log.warn("Another instance is already running (#{e.message}).")
291
315
  end
@@ -294,40 +318,40 @@ module Aspera
294
318
  @plugin_env[:formater].display_results(command_plugin.execute_action) if execute_command
295
319
  # finish
296
320
  @plugin_env[:transfer].shutdown
297
- rescue CliBadArgument => e; exception_info=[e,'Argument',:usage]
298
- rescue CliNoSuchId => e; exception_info=[e,'Identifier']
299
- rescue CliError => e; exception_info=[e,'Tool',:usage]
300
- rescue Fasp::Error => e; exception_info=[e,'FASP(ascp)']
301
- rescue Aspera::RestCallError => e; exception_info=[e,'Rest']
302
- rescue SocketError => e; exception_info=[e,'Network']
303
- rescue StandardError => e; exception_info=[e,'Other',:debug]
304
- rescue Interrupt => e; exception_info=[e,'Interruption',:debug]
321
+ rescue CliBadArgument => e; exception_info={e: e,t: 'Argument',usage: true}
322
+ rescue CliNoSuchId => e; exception_info={e: e,t: 'Identifier'}
323
+ rescue CliError => e; exception_info={e: e,t: 'Tool',usage: true}
324
+ rescue Fasp::Error => e; exception_info={e: e,t: 'FASP(ascp)'}
325
+ rescue Aspera::RestCallError => e; exception_info={e: e,t: 'Rest'}
326
+ rescue SocketError => e; exception_info={e: e,t: 'Network'}
327
+ rescue StandardError => e; exception_info={e: e,t: 'Other',debug: true}
328
+ rescue Interrupt => e; exception_info={e: e,t: 'Interruption',debug: true}
305
329
  end
306
330
  # cleanup file list files
307
331
  TempFileManager.instance.cleanup
308
332
  # 1- processing of error condition
309
333
  unless exception_info.nil?
310
- @plugin_env[:formater].display_message(:error,"ERROR:".bg_red.gray.blink+" "+exception_info[1]+": "+exception_info[0].message)
311
- @plugin_env[:formater].display_message(:error,"Use '-h' option to get help.") if exception_info[2].eql?(:usage)
312
- if exception_info.first.is_a?(Fasp::Error) and exception_info.first.message.eql?('Remote host is not who we expected')
334
+ @plugin_env[:formater].display_message(:error,"#{ERROR_FLASH} #{exception_info[:t]}: #{exception_info[:e].message}")
335
+ @plugin_env[:formater].display_message(:error,'Use option -h to get help.') if exception_info[:usage]
336
+ if exception_info[:e].is_a?(Fasp::Error) && exception_info[:e].message.eql?('Remote host is not who we expected')
313
337
  @plugin_env[:formater].display_message(:error,"For this specific error, refer to:\n#{SRC_URL}#error-remote-host-is-not-who-we-expected\nAdd this to arguments:\n--ts=@json:'{\"sshfp\":null}'")
314
338
  end
315
339
  end
316
340
  # 2- processing of command not processed (due to exception or bad command line)
317
- if execute_command
341
+ if execute_command || @option_show_config
318
342
  @opt_mgr.final_errors.each do |msg|
319
- @plugin_env[:formater].display_message(:error,"ERROR:".bg_red.gray.blink+" Argument: "+msg)
343
+ @plugin_env[:formater].display_message(:error,"#{ERROR_FLASH} Argument: #{msg}")
344
+ # add code as exception if there is not already an error
345
+ exception_info={e: Exception.new(msg),t: 'UnusedArg'} if exception_info.nil?
320
346
  end
321
347
  end
322
348
  # 3- in case of error, fail the process status
323
349
  unless exception_info.nil?
324
- if Log.instance.level.eql?(:debug)
325
- # will force to show stack trace
326
- raise exception_info[0]
327
- else
328
- @plugin_env[:formater].display_message(:error,"Use '--log-level=debug' to get more details.") if exception_info[2].eql?(:debug)
329
- Process.exit(1)
330
- end
350
+ # show stack trace in debug mode
351
+ raise exception_info[:e] if Log.instance.level.eql?(:debug)
352
+ # else give hint and exit
353
+ @plugin_env[:formater].display_message(:error,'Use --log-level=debug to get more details.') if exception_info[:debug]
354
+ Process.exit(1)
331
355
  end
332
356
  return nil
333
357
  end # process_command_line