aspera-cli 4.13.0 → 4.14.0

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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +28 -5
  4. data/CONTRIBUTING.md +17 -1
  5. data/README.md +782 -401
  6. data/examples/dascli +1 -1
  7. data/examples/rubyc +24 -0
  8. data/lib/aspera/aoc.rb +21 -32
  9. data/lib/aspera/ascmd.rb +1 -0
  10. data/lib/aspera/cli/basic_auth_plugin.rb +6 -6
  11. data/lib/aspera/cli/formatter.rb +17 -25
  12. data/lib/aspera/cli/main.rb +21 -27
  13. data/lib/aspera/cli/manager.rb +128 -114
  14. data/lib/aspera/cli/plugin.rb +87 -38
  15. data/lib/aspera/cli/plugins/alee.rb +2 -2
  16. data/lib/aspera/cli/plugins/aoc.rb +216 -102
  17. data/lib/aspera/cli/plugins/ats.rb +16 -18
  18. data/lib/aspera/cli/plugins/bss.rb +3 -3
  19. data/lib/aspera/cli/plugins/config.rb +177 -367
  20. data/lib/aspera/cli/plugins/console.rb +4 -6
  21. data/lib/aspera/cli/plugins/cos.rb +12 -13
  22. data/lib/aspera/cli/plugins/faspex.rb +17 -18
  23. data/lib/aspera/cli/plugins/faspex5.rb +332 -216
  24. data/lib/aspera/cli/plugins/node.rb +171 -142
  25. data/lib/aspera/cli/plugins/orchestrator.rb +15 -18
  26. data/lib/aspera/cli/plugins/preview.rb +38 -60
  27. data/lib/aspera/cli/plugins/server.rb +22 -15
  28. data/lib/aspera/cli/plugins/shares.rb +24 -33
  29. data/lib/aspera/cli/plugins/sync.rb +3 -3
  30. data/lib/aspera/cli/transfer_agent.rb +29 -26
  31. data/lib/aspera/cli/version.rb +1 -1
  32. data/lib/aspera/colors.rb +9 -7
  33. data/lib/aspera/data/6 +0 -0
  34. data/lib/aspera/environment.rb +7 -3
  35. data/lib/aspera/fasp/agent_connect.rb +5 -0
  36. data/lib/aspera/fasp/agent_direct.rb +5 -5
  37. data/lib/aspera/fasp/agent_httpgw.rb +138 -60
  38. data/lib/aspera/fasp/agent_trsdk.rb +2 -0
  39. data/lib/aspera/fasp/error_info.rb +2 -0
  40. data/lib/aspera/fasp/installation.rb +18 -19
  41. data/lib/aspera/fasp/parameters.rb +18 -17
  42. data/lib/aspera/fasp/parameters.yaml +2 -1
  43. data/lib/aspera/fasp/resume_policy.rb +3 -3
  44. data/lib/aspera/fasp/transfer_spec.rb +6 -5
  45. data/lib/aspera/fasp/uri.rb +23 -21
  46. data/lib/aspera/faspex_postproc.rb +1 -1
  47. data/lib/aspera/hash_ext.rb +12 -2
  48. data/lib/aspera/keychain/macos_security.rb +13 -13
  49. data/lib/aspera/log.rb +1 -0
  50. data/lib/aspera/node.rb +62 -80
  51. data/lib/aspera/oauth.rb +1 -1
  52. data/lib/aspera/persistency_action_once.rb +1 -1
  53. data/lib/aspera/preview/terminal.rb +61 -15
  54. data/lib/aspera/preview/utils.rb +3 -3
  55. data/lib/aspera/proxy_auto_config.js +2 -2
  56. data/lib/aspera/rest.rb +37 -0
  57. data/lib/aspera/secret_hider.rb +6 -1
  58. data/lib/aspera/ssh.rb +1 -1
  59. data/lib/aspera/sync.rb +2 -0
  60. data.tar.gz.sig +0 -0
  61. metadata +3 -4
  62. metadata.gz.sig +0 -0
  63. data/docs/test_env.conf +0 -186
  64. data/lib/aspera/data/7 +0 -0
data/examples/dascli CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bash
2
2
  # set env var image to specify another docker image
3
- : "${image:=martinlaurent/ascli}"
3
+ : "${image:=docker.io/martinlaurent/ascli}"
4
4
  # set env var version to specify another image version (default: latest version)
5
5
  : "${version:=latest}"
6
6
  # set env var imgtag to specify a specific image/version
data/examples/rubyc ADDED
@@ -0,0 +1,24 @@
1
+ #!/bin/bash
2
+ # https://github.com/you54f/ruby-packer
3
+ # https://github.com/YOU54F/ruby-packer/releases
4
+ set -e
5
+ FOLDER="$(dirname $0)/../tmp"
6
+ RUBYC="$FOLDER/rubyc"
7
+ if test ! -e "$RUBYC"; then
8
+ mkdir -p "$FOLDER"
9
+ case $(uname -sm|tr ' ' -) in
10
+ Darwin-arm64)
11
+ curl -L https://github.com/YOU54F/ruby-packer/releases/download/rel-20230812/rubyc-Darwin-arm64.tar.gz | tar -xz -C "$FOLDER"
12
+ mv "$FOLDER/rubyc-Darwin-arm64" "$RUBYC"
13
+ ;;
14
+ Linux-x86_64)
15
+ curl -L https://github.com/YOU54F/ruby-packer/releases/download/rel-20230812/rubyc-Linux-x86_64.tar.gz | tar -xz -C "$FOLDER"
16
+ mv "$FOLDER/rubyc-Linux-x86_64" "$RUBYC"
17
+ ;;
18
+ *)
19
+ echo "This architecture is not supported." >&2
20
+ exit 1
21
+ ;;
22
+ esac
23
+ fi
24
+ exec "$RUBYC" "$@"
data/lib/aspera/aoc.rb CHANGED
@@ -42,6 +42,9 @@ module Aspera
42
42
  OAUTH_API_SUBPATH = 'api/v1/oauth2'
43
43
  # minimum fields for user info if retrieval fails
44
44
  USER_INFO_FIELDS_MIN = %w[name email id default_workspace_id organization_id].freeze
45
+ # types of events for shared folder creation
46
+ # Node events: permission.created permission.modified permission.deleted
47
+ PERMISSIONS_CREATED = ['permission.created'].freeze
45
48
 
46
49
  private_constant :MAX_REDIRECT,
47
50
  :GLOBAL_CLIENT_APPS,
@@ -50,7 +53,8 @@ module Aspera
50
53
  :PUBLIC_LINK_PATHS,
51
54
  :JWT_AUDIENCE,
52
55
  :OAUTH_API_SUBPATH,
53
- :USER_INFO_FIELDS_MIN
56
+ :USER_INFO_FIELDS_MIN,
57
+ :PERMISSIONS_CREATED
54
58
 
55
59
  # various API scopes supported
56
60
  SCOPE_FILES_SELF = 'self'
@@ -63,8 +67,6 @@ module Aspera
63
67
  FILES_APP = 'files'
64
68
  PACKAGES_APP = 'packages'
65
69
  API_V1 = 'api/v1'
66
- # error message when entity not found
67
- ENTITY_NOT_FOUND = 'No such'
68
70
 
69
71
  # class static methods
70
72
  class << self
@@ -294,28 +296,6 @@ module Aspera
294
296
  return Node.new(params: node_rest_params, app_info: app_info)
295
297
  end
296
298
 
297
- # Query entity type by name and returns the id if a single entry only
298
- # @param entity_type path of entity in API
299
- # @param entity_name name of searched entity
300
- # @param options additional search options
301
- def lookup_entity_by_name(entity_type, entity_name, options={})
302
- # returns entities whose name contains value (case insensitive)
303
- matching_items = read(entity_type, options.merge({'q' => CGI.escape(entity_name)}))[:data]
304
- case matching_items.length
305
- when 1 then return matching_items.first
306
- when 0 then raise %Q{#{ENTITY_NOT_FOUND} #{entity_type}: "#{entity_name}"}
307
- else
308
- # multiple case insensitive partial matches, try case insensitive full match
309
- # (anyway AoC does not allow creation of 2 entities with same case insensitive name)
310
- name_matches = matching_items.select{|i|i['name'].casecmp?(entity_name)}
311
- case name_matches.length
312
- when 1 then return name_matches.first
313
- when 0 then raise %Q(#{entity_type}: multiple case insensitive partial match for: "#{entity_name}": #{matching_items.map{|i|i['name']}} but no case insensitive full match. Please be more specific or give exact name.) # rubocop:disable Layout/LineLength
314
- else raise "Two entities cannot have the same case insensitive name: #{name_matches.map{|i|i['name']}}"
315
- end
316
- end
317
- end
318
-
319
299
  # Check metadata: remove when validation is done server side
320
300
  def validate_metadata(pkg_data)
321
301
  # validate only for shared inboxes
@@ -367,7 +347,7 @@ module Aspera
367
347
  # email: user, else dropbox
368
348
  entity_type = short_recipient_info.include?('@') ? 'contacts' : 'dropboxes'
369
349
  begin
370
- full_recipient_info = lookup_entity_by_name(entity_type, short_recipient_info, {'current_workspace_id' => ws_id})
350
+ full_recipient_info = lookup_by_name(entity_type, short_recipient_info, {'current_workspace_id' => ws_id})
371
351
  rescue RuntimeError => e
372
352
  raise e unless e.message.start_with?(ENTITY_NOT_FOUND)
373
353
  # dropboxes cannot be created on the fly
@@ -496,7 +476,10 @@ module Aspera
496
476
 
497
477
  ID_AK_ADMIN = 'ASPERA_ACCESS_KEY_ADMIN'
498
478
  # Callback from Plugins::Node
499
- def permissions_create_params(create_param:, app_info:)
479
+ # add application specific tags to permissions creation
480
+ # @param create_param [Hash] parameters for creating permissions
481
+ # @param app_info [Hash] application information
482
+ def permissions_set_create_params(create_param:, app_info:)
500
483
  # workspace shared folder:
501
484
  # access_id = "#{ID_AK_ADMIN}_WS_#{app_info[:workspace_id]}"
502
485
  default_params = {
@@ -517,7 +500,7 @@ module Aspera
517
500
  'node' => app_info[:node_info]['name']}}}}}
518
501
  create_param.deep_merge!(default_params)
519
502
  if create_param.key?('with')
520
- contact_info = lookup_entity_by_name(
503
+ contact_info = lookup_by_name(
521
504
  'contacts',
522
505
  create_param['with'],
523
506
  {'current_workspace_id' => app_info[:workspace_id], 'context' => 'share_folder'})
@@ -531,14 +514,20 @@ module Aspera
531
514
  end
532
515
 
533
516
  # Callback from Plugins::Node
534
- def permissions_create_event(created_data:, app_info:)
517
+ # send shared folder event to AoC
518
+ # @param created_data [Hash] response from permission creation
519
+ # @param app_info [Hash] hash with app info
520
+ # @param types [Array] event types
521
+ def permissions_send_event(created_data:, app_info:, types: PERMISSIONS_CREATED)
522
+ raise "INTERNAL: (assert) Invalid event types: #{types}" unless types.is_a?(Array) && !types.empty?
535
523
  event_creation = {
536
- 'types' => ['permission.created'],
524
+ 'types' => types,
537
525
  'node_id' => app_info[:node_info]['id'],
538
526
  'workspace_id' => app_info[:workspace_id],
539
- 'data' => created_data # Response from previous step
527
+ 'data' => created_data
540
528
  }
541
- # (optional). The name of the folder to be displayed to the destination user. Use it if its value is different from the "share_as" field.
529
+ # (optional). The name of the folder to be displayed to the destination user.
530
+ # Use it if its value is different from the "share_as" field.
542
531
  event_creation['link_name'] = app_info[:opt_link_name] unless app_info[:opt_link_name].nil?
543
532
  create('events', event_creation)
544
533
  end
data/lib/aspera/ascmd.rb CHANGED
@@ -127,6 +127,7 @@ module Aspera
127
127
  byte_array = buffer.shift(num_bytes)
128
128
  byte_array = [byte_array] unless byte_array.is_a?(Array)
129
129
  result = byte_array.pack('C*').unpack1(type_descr[:unpack])
130
+ result.force_encoding('UTF-8') if type_name.eql?(:zstr)
130
131
  Log.log.debug{"#{' .' * indent_level}-> base:#{byte_array} -> #{result}"}
131
132
  result = Time.at(result) if type_name.eql?(:epoch)
132
133
  when :buffer_list
@@ -9,9 +9,9 @@ module Aspera
9
9
  class BasicAuthPlugin < Aspera::Cli::Plugin
10
10
  class << self
11
11
  def register_options(env)
12
- env[:options].add_opt_simple(:url, 'URL of application, e.g. https://org.asperafiles.com')
13
- env[:options].add_opt_simple(:username, 'username to log in')
14
- env[:options].add_opt_simple(:password, "user's password")
12
+ env[:options].declare(:url, 'URL of application, e.g. https://org.asperafiles.com')
13
+ env[:options].declare(:username, 'Username to log in')
14
+ env[:options].declare(:password, "User's password")
15
15
  env[:options].parse_options!
16
16
  end
17
17
  end
@@ -23,14 +23,14 @@ module Aspera
23
23
 
24
24
  # returns a Rest object with basic auth
25
25
  def basic_auth_params(subpath=nil)
26
- api_url = options.get_option(:url, is_type: :mandatory)
26
+ api_url = options.get_option(:url, mandatory: true)
27
27
  api_url = api_url + '/' + subpath unless subpath.nil?
28
28
  return {
29
29
  base_url: api_url,
30
30
  auth: {
31
31
  type: :basic,
32
- username: options.get_option(:username, is_type: :mandatory),
33
- password: options.get_option(:password, is_type: :mandatory)
32
+ username: options.get_option(:username, mandatory: true),
33
+ password: options.get_option(:password, mandatory: true)
34
34
  }}
35
35
  end
36
36
 
@@ -18,9 +18,10 @@ module Aspera
18
18
  # user output levels
19
19
  DISPLAY_LEVELS = %i[info data error].freeze
20
20
  CONF_OVERVIEW_KEYS = %w[config parameter value].freeze
21
+ KEY_VALUE = %w[key value].freeze
21
22
 
22
23
  private_constant :FIELDS_ALL, :FIELDS_DEFAULT, :DISPLAY_FORMATS, :DISPLAY_LEVELS, :CSV_RECORD_SEPARATOR, :CSV_FIELD_SEPARATOR,
23
- :CONF_OVERVIEW_KEYS
24
+ :CONF_OVERVIEW_KEYS, :KEY_VALUE
24
25
 
25
26
  class << self
26
27
  # special for Aspera on Cloud display node
@@ -81,22 +82,14 @@ module Aspera
81
82
  @option_flat_hash = true
82
83
  @option_transpose_single = true
83
84
  @option_show_secrets = false
84
- opt_mgr.set_obj_attr(:format, self, :option_format)
85
- opt_mgr.set_obj_attr(:display, self, :option_display)
86
- opt_mgr.set_obj_attr(:fields, self, :option_fields)
87
- opt_mgr.set_obj_attr(:select, self, :option_select)
88
- opt_mgr.set_obj_attr(:table_style, self, :option_table_style)
89
- opt_mgr.set_obj_attr(:flat_hash, self, :option_flat_hash)
90
- opt_mgr.set_obj_attr(:transpose_single, self, :option_transpose_single)
91
- opt_mgr.set_obj_attr(:show_secrets, self, :option_show_secrets)
92
- opt_mgr.add_opt_list(:format, DISPLAY_FORMATS, 'output format')
93
- opt_mgr.add_opt_list(:display, DISPLAY_LEVELS, 'output only some information')
94
- opt_mgr.add_opt_simple(:fields, "comma separated list of fields, or #{FIELDS_ALL}, or #{FIELDS_DEFAULT}")
95
- opt_mgr.add_opt_simple(:select, 'select only some items in lists, extended value: hash (column, value)')
96
- opt_mgr.add_opt_simple(:table_style, 'table display style')
97
- opt_mgr.add_opt_boolean(:flat_hash, 'display hash values as additional keys')
98
- opt_mgr.add_opt_boolean(:transpose_single, 'single object fields output vertically')
99
- opt_mgr.add_opt_boolean(:show_secrets, 'show secrets on command output')
85
+ opt_mgr.declare(:format, 'Output format', values: DISPLAY_FORMATS, handler: {o: self, m: :option_format})
86
+ opt_mgr.declare(:display, 'Output only some information', values: DISPLAY_LEVELS, handler: {o: self, m: :option_display})
87
+ opt_mgr.declare(:fields, "Comma separated list of fields, or #{FIELDS_ALL}, or #{FIELDS_DEFAULT}", handler: {o: self, m: :option_fields})
88
+ opt_mgr.declare(:select, 'Select only some items in lists: column, value', types: Hash, handler: {o: self, m: :option_select})
89
+ opt_mgr.declare(:table_style, 'Table display style', handler: {o: self, m: :option_table_style})
90
+ opt_mgr.declare(:flat_hash, 'Display deep values as additional keys', values: :bool, handler: {o: self, m: :option_flat_hash})
91
+ opt_mgr.declare(:transpose_single, 'Single object fields output vertically', values: :bool, handler: {o: self, m: :option_transpose_single})
92
+ opt_mgr.declare(:show_secrets, 'Show secrets on command output', values: :bool, handler: {o: self, m: :option_show_secrets})
100
93
  end
101
94
 
102
95
  # main output method
@@ -195,7 +188,7 @@ module Aspera
195
188
  when :single_object # goes to table display
196
189
  # :single_object is a simple hash table (can be nested)
197
190
  raise "internal error: expecting Hash: got #{res_data.class}: #{res_data}" unless res_data.is_a?(Hash)
198
- final_table_columns = results[:columns] || %w[key value]
191
+ final_table_columns = results[:columns] || KEY_VALUE
199
192
  if @option_flat_hash
200
193
  res_data = self.class.flattened_object(res_data, expand_last: results[:option_expand_last])
201
194
  self.class.flatten_name_value_list(res_data)
@@ -207,6 +200,11 @@ module Aspera
207
200
  else user_asked_fields_list_str.split(',')
208
201
  end
209
202
  table_rows_hash_val = asked_fields.map { |i| { final_table_columns.first => i, final_table_columns.last => res_data[i] } }
203
+ # if only one row, and columns are key/value, then display the value only
204
+ if table_rows_hash_val.length == 1 && final_table_columns.eql?(KEY_VALUE)
205
+ display_message(:data, res_data.values.first)
206
+ return
207
+ end
210
208
  when :value_list # goes to table display
211
209
  # :value_list is a simple array of values, name of column provided in the :name
212
210
  final_table_columns = [results[:name]]
@@ -235,7 +233,7 @@ module Aspera
235
233
  # here we expect: table_rows_hash_val and final_table_columns
236
234
  raise 'no field specified' if final_table_columns.nil?
237
235
  if table_rows_hash_val.empty?
238
- display_message(:info, 'empty'.gray) unless @option_format.eql?(:csv)
236
+ display_message(:info, 'empty'.gray) if @option_format.eql?(:table)
239
237
  return
240
238
  end
241
239
  # convert to string with special function. here table_rows_hash_val is an array of hash
@@ -252,12 +250,6 @@ module Aspera
252
250
  when :table
253
251
  style = @option_table_style.chars
254
252
  # display the table !
255
- # display_message(:data,Text::Table.new(
256
- # head: final_table_columns,
257
- # rows: final_table_rows,
258
- # horizontal_boundary: style[0],
259
- # vertical_boundary: style[1],
260
- # boundary_intersection: style[2]))
261
253
  display_message(:data, Terminal::Table.new(
262
254
  headings: final_table_columns,
263
255
  rows: final_table_rows,
@@ -31,7 +31,7 @@ module Aspera
31
31
  STATUS_FIELD = 'status'
32
32
 
33
33
  # for testing only
34
- SELF_SIGNED_CERT = OpenSSL::SSL.const_get(:enon_yfirev.to_s.upcase.reverse)
34
+ SELF_SIGNED_CERT = OpenSSL::SSL.const_get(:enon_yfirev.to_s.upcase.reverse) # cspell: disable-line
35
35
 
36
36
  class << self
37
37
  # expect some list, but nothing to display
@@ -87,7 +87,7 @@ module Aspera
87
87
  if @option_insecure
88
88
  url = http.inspect.gsub(/^[^ ]* /, 'https://').gsub(/ [^ ]*$/, '')
89
89
  if !@ssl_warned_urls.include?(url)
90
- @formatter.display_message(:error, "#{WARNING_FLASH} ignoring certificate for: #{url}. Do not use unsafe certificates in production.")
90
+ @formatter.display_message(:error, "#{WARNING_FLASH} ignoring certificate for: #{url}. Do not deactivate certificate verification in production.")
91
91
  @ssl_warned_urls.push(url)
92
92
  end
93
93
  http.verify_mode = SELF_SIGNED_CERT
@@ -187,31 +187,25 @@ module Aspera
187
187
  # define header for manual
188
188
  def init_global_options
189
189
  Log.log.debug('init_global_options')
190
- @opt_mgr.add_opt_switch(:help, '-h', 'Show this message.') { @option_help = true }
191
- @opt_mgr.add_opt_switch(:bash_comp, 'generate bash completion for command') { @bash_completion = true }
192
- @opt_mgr.add_opt_switch(:show_config, 'Display parameters used for the provided action.') { @option_show_config = true }
193
- @opt_mgr.add_opt_switch(:rest_debug, '-r', 'more debug for HTTP calls') { @option_rest_debug = true }
194
- @opt_mgr.add_opt_switch(:version, '-v', 'display version') { @formatter.display_message(:data, Aspera::Cli::VERSION); Process.exit(0) } # rubocop:disable Style/Semicolon, Layout/LineLength
195
- @opt_mgr.add_opt_switch(:warnings, '-w', 'check for language warnings') { $VERBOSE = true }
196
- # handler must be set before declaration
197
- @opt_mgr.set_obj_attr(:log_level, Log.instance, :level)
198
- @opt_mgr.set_obj_attr(:logger, Log.instance, :logger_type)
199
- @opt_mgr.set_obj_attr(:insecure, self, :option_insecure, :no)
200
- @opt_mgr.set_obj_attr(:ui, self, :option_ui)
201
- @opt_mgr.set_obj_attr(:http_options, self, :option_http_options)
202
- @opt_mgr.set_obj_attr(:log_secrets, SecretHider, :log_secrets)
203
- @opt_mgr.set_obj_attr(:cache_tokens, self, :option_cache_tokens)
204
- @opt_mgr.add_opt_list(:ui, OpenApplication.user_interfaces, 'method to start browser')
205
- @opt_mgr.add_opt_list(:log_level, Log.levels, 'Log level')
206
- @opt_mgr.add_opt_list(:logger, Log::LOG_TYPES, 'logging method')
207
- @opt_mgr.add_opt_simple(:lock_port, 'prevent dual execution of a command, e.g. in cron')
208
- @opt_mgr.add_opt_simple(:http_options, 'options for http socket (extended value)')
209
- @opt_mgr.add_opt_boolean(:insecure, 'do not validate HTTPS certificate')
210
- @opt_mgr.add_opt_boolean(:once_only, 'process only new items (some commands)')
211
- @opt_mgr.add_opt_boolean(:log_secrets, 'show passwords in logs')
212
- @opt_mgr.add_opt_boolean(:cache_tokens, 'save and reuse Oauth tokens')
213
- @opt_mgr.set_option(:ui, OpenApplication.default_gui_mode)
214
- @opt_mgr.set_option(:once_only, false)
190
+ @opt_mgr.declare(:help, 'Show this message', values: :none, short: 'h') { @option_help = true }
191
+ @opt_mgr.declare(:bash_comp, 'Generate bash completion for command', values: :none) { @bash_completion = true }
192
+ @opt_mgr.declare(:show_config, 'Display parameters used for the provided action', values: :none) { @option_show_config = true }
193
+ @opt_mgr.declare(:rest_debug, 'More debug for HTTP calls (REST)', values: :none, short: 'r') { @option_rest_debug = true }
194
+ @opt_mgr.declare(:version, 'Display version', values: :none, short: 'v') { @formatter.display_message(:data, Aspera::Cli::VERSION); Process.exit(0) } # rubocop:disable Style/Semicolon, Layout/LineLength
195
+ @opt_mgr.declare(:warnings, 'Check for language warnings', values: :none, short: 'w') { $VERBOSE = true }
196
+ @opt_mgr.declare(
197
+ :ui, 'Method to start browser',
198
+ values: OpenApplication.user_interfaces,
199
+ handler: {o: self, m: :option_ui},
200
+ default: OpenApplication.default_gui_mode)
201
+ @opt_mgr.declare(:log_level, 'Log level', values: Log.levels, handler: {o: Log.instance, m: :level})
202
+ @opt_mgr.declare(:logger, 'Logging method', values: Log::LOG_TYPES, handler: {o: Log.instance, m: :logger_type})
203
+ @opt_mgr.declare(:lock_port, 'Prevent dual execution of a command, e.g. in cron')
204
+ @opt_mgr.declare(:http_options, 'Options for http socket', types: Hash, handler: {o: self, m: :option_http_options})
205
+ @opt_mgr.declare(:insecure, 'Do not validate HTTPS certificate', values: :bool, handler: {o: self, m: :option_insecure}, default: :no)
206
+ @opt_mgr.declare(:once_only, 'Process only new items (some commands)', values: :bool, default: false)
207
+ @opt_mgr.declare(:log_secrets, 'Show passwords in logs', values: :bool, handler: {o: SecretHider, m: :log_secrets})
208
+ @opt_mgr.declare(:cache_tokens, 'Save and reuse Oauth tokens', values: :bool, handler: {o: self, m: :option_cache_tokens})
215
209
  # parse declared options
216
210
  @opt_mgr.parse_options!
217
211
  end