hammer_cli 2.5.0 → 3.1.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/bin/hammer +1 -1
  3. data/doc/commands_extension.md +8 -6
  4. data/doc/creating_commands.md +17 -0
  5. data/doc/release_notes.md +23 -0
  6. data/lib/hammer_cli/abstract.rb +75 -60
  7. data/lib/hammer_cli/apipie/command.rb +1 -1
  8. data/lib/hammer_cli/apipie/option_builder.rb +16 -11
  9. data/lib/hammer_cli/apipie/option_definition.rb +1 -8
  10. data/lib/hammer_cli/command_extensions.rb +47 -34
  11. data/lib/hammer_cli/help/builder.rb +10 -6
  12. data/lib/hammer_cli/options/normalizers.rb +126 -18
  13. data/lib/hammer_cli/options/option_definition.rb +17 -22
  14. data/lib/hammer_cli/options/option_family.rb +44 -8
  15. data/lib/hammer_cli/output/adapter/abstract.rb +6 -0
  16. data/lib/hammer_cli/output/adapter/base.rb +1 -1
  17. data/lib/hammer_cli/output/adapter/tree_structure.rb +1 -1
  18. data/lib/hammer_cli/output/definition.rb +1 -1
  19. data/lib/hammer_cli/output/field_filter.rb +2 -2
  20. data/lib/hammer_cli/utils.rb +6 -0
  21. data/lib/hammer_cli/version.rb +1 -1
  22. data/locale/ca/LC_MESSAGES/hammer-cli.mo +0 -0
  23. data/locale/de/LC_MESSAGES/hammer-cli.mo +0 -0
  24. data/locale/en/LC_MESSAGES/hammer-cli.mo +0 -0
  25. data/locale/en_GB/LC_MESSAGES/hammer-cli.mo +0 -0
  26. data/locale/es/LC_MESSAGES/hammer-cli.mo +0 -0
  27. data/locale/fr/LC_MESSAGES/hammer-cli.mo +0 -0
  28. data/locale/it/LC_MESSAGES/hammer-cli.mo +0 -0
  29. data/locale/ja/LC_MESSAGES/hammer-cli.mo +0 -0
  30. data/locale/ko/LC_MESSAGES/hammer-cli.mo +0 -0
  31. data/locale/pt_BR/LC_MESSAGES/hammer-cli.mo +0 -0
  32. data/locale/ru/LC_MESSAGES/hammer-cli.mo +0 -0
  33. data/locale/zh_CN/LC_MESSAGES/hammer-cli.mo +0 -0
  34. data/locale/zh_TW/LC_MESSAGES/hammer-cli.mo +0 -0
  35. data/man/hammer.1.gz +0 -0
  36. data/test/unit/abstract_test.rb +7 -0
  37. data/test/unit/apipie/option_builder_test.rb +8 -3
  38. data/test/unit/command_extensions_test.rb +10 -2
  39. data/test/unit/help/builder_test.rb +20 -2
  40. data/test/unit/options/option_definition_test.rb +12 -1
  41. data/test/unit/output/definition_test.rb +3 -3
  42. metadata +22 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a632fb8b3ddc1914f0110af4371d152d31e0efe042453512c55dd1384b8bafc
4
- data.tar.gz: 76029ef771f18e0096ffdc18f897b1758d09c58277065dce55907f625f13d77e
3
+ metadata.gz: 510f07df29c39c069ae58e923507361a276e12ef50cc38628868361794a7754c
4
+ data.tar.gz: 13790a4114574688531978c11a9bb479062381d1b5196168f6d0e70deddc6a43
5
5
  SHA512:
6
- metadata.gz: 6777ff43f35fb9b29332e3f02ed68320a5a0f526da5c1a0256f714223ceed72c6d09f3982d0df252be82e2e7ea754fd6105d202f68eebac030d9e6fc6a3db6b6
7
- data.tar.gz: 0e7ddb3ea2aaf2080ab8b796c9eb0f68d747a0d290a57bb84e53386de86e17cb51dfbf266fccce3bee71c38123ce0aa67773aaca963fa8001840a56a8a03d467
6
+ metadata.gz: a8bd5241448ccae9b7bd27f4260ebe5cbc8d75f2a79dcf76fb710c13e7bba42275cda6332acd6b67c33125572393b17e1f2d1575166ce8edfc76c7a81cdb9854
7
+ data.tar.gz: 9656ed10f1c8d44f35f0d321e1568d82a9607dc82b5ecf3e03999ec471eb67aa5dc119fcc31c90b1f540bab4a3d5abc5eff444d498eb275a7e0b061c61426fcf
data/bin/hammer CHANGED
@@ -1,4 +1,4 @@
1
- #! /usr/bin/env ruby
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  require 'rubygems'
4
4
  require 'clamp'
@@ -16,11 +16,11 @@ Each command can be easily extended with one ore more `HammerCLI::CommandExtensi
16
16
  child option_params
17
17
  end
18
18
  # Extend hash with data returned from server before it is printed
19
- before_print do |data|
19
+ before_print do |data, command_object, command_class|
20
20
  # data modifications
21
21
  end
22
22
  # Extend command's output definition
23
- output do |definition|
23
+ output do |definition, command_object, command_class|
24
24
  # output definition modifications
25
25
  end
26
26
  # Extend command's help definition
@@ -28,19 +28,19 @@ Each command can be easily extended with one ore more `HammerCLI::CommandExtensi
28
28
  # help modifications
29
29
  end
30
30
  # Extend hash with headers before request is sent
31
- request_headers do |headers|
31
+ request_headers do |headers, command_object, command_class|
32
32
  # headers modifications
33
33
  end
34
34
  # Extend hash with options before request is sent
35
- request_options do |options|
35
+ request_options do |options, command_object, command_class|
36
36
  # options modifications
37
37
  end
38
38
  # Extend hash with params before request is sent
39
- request_params do |params|
39
+ request_params do |params, command_object, command_class|
40
40
  # params modifications
41
41
  end
42
42
  # Extend option sources
43
- option_sources do |sources, command|
43
+ option_sources do |sources, command_object, command_class|
44
44
  # no need to call super method
45
45
  # simply add your sources to sources variable
46
46
  end
@@ -63,6 +63,8 @@ __NOTE:__
63
63
  - `request_*` extensions are applied before sending a request to the server
64
64
  - `option`, `output`, `help` extensions are applied right away after the command is extended with `extend_with`
65
65
  - `before_print` extensions are applied right away after the server returns the data
66
+ - `request_*`, `output`, `before_print` extensions have access to the command object
67
+ after the command with the extension was initialized
66
68
 
67
69
  #### Example
68
70
  ```ruby
@@ -190,6 +190,23 @@ To define an option family, use the following DSL:
190
190
  end
191
191
  ```
192
192
 
193
+ You can also add additional options for automatically built ones:
194
+ ```ruby
195
+ # ...
196
+ build_options
197
+ # If --resource-id option comes from the API params and you want to add options
198
+ # with searchables such as --resource-name, --resource-label
199
+ option_family(associate: 'resource') do
200
+ child '--resource-name', 'RESOURCE', _('Resource desc'), attribute_name: :option_resource_name
201
+ child '--resource-label', 'RESOURCE', _('Resource desc'), attribute_name: :option_resource_label
202
+ end
203
+ # $ hammer command --help:
204
+ # ...
205
+ # Options:
206
+ # --resource[-id|-name|-label] Resource desc
207
+ # ...
208
+ ```
209
+
193
210
  ##### Example
194
211
 
195
212
  ```ruby
data/doc/release_notes.md CHANGED
@@ -1,5 +1,28 @@
1
1
  Release notes
2
2
  =============
3
+ ### 3.1.0 (2021-11-10)
4
+ * Remove a space in hammer's shebang, [#33810](http://projects.theforeman.org/issues/33810)
5
+ * Revert fix rake version
6
+ * Fix rake version
7
+ * Wrap option descriptions to 80 chars, [#33129](http://projects.theforeman.org/issues/33129)
8
+ * Don't store @context in field params, [#33259](http://projects.theforeman.org/issues/33259)
9
+ * Change from superficial copy to deep copy of fields ([PR #348](https://github.com/theforeman/hammer-cli/pull/348)), [#29093](http://projects.theforeman.org/issues/29093)
10
+ * Make api docs params to be the main options, [#33226](http://projects.theforeman.org/issues/33226)
11
+ * Show depr warning only on option usage, [#33225](http://projects.theforeman.org/issues/33225)
12
+ * Extract descs to option details section, [#32783](http://projects.theforeman.org/issues/32783)
13
+ * Bump to 3.1.0-develop
14
+
15
+ ### 3.0.0 (2021-08-04)
16
+ * Update rel-eng notebook ([PR #347](https://github.com/theforeman/hammer-cli/pull/347))
17
+ * Bump version to 3.0-develop
18
+ * Revert "change from superficial copy to deep copy of fields", [#29093](http://projects.theforeman.org/issues/29093)
19
+ * Change from superficial copy to deep copy of fields, [#29093](http://projects.theforeman.org/issues/29093)
20
+ * Add full comparison for fields option, [#31984](http://projects.theforeman.org/issues/31984)
21
+ * Force capitalized field names in help, [#32444](http://projects.theforeman.org/issues/32444)
22
+ * Unescape enum validator description, [#32570](http://projects.theforeman.org/issues/32570)
23
+ * Make cmd object be available in command extensions, [#32568](http://projects.theforeman.org/issues/32568)
24
+ * Bump to 2.6.0-develop
25
+
3
26
  ### 2.5.0 (2021-05-04)
4
27
  * Better family assignment for options, [#30996](http://projects.theforeman.org/issues/30996)
5
28
  * Bump to 2.5.0-develop
@@ -20,9 +20,23 @@ module HammerCLI
20
20
  class AbstractCommand < Clamp::Command
21
21
  include HammerCLI::Subcommand
22
22
 
23
+ attr_reader :context
24
+
23
25
  class << self
24
26
  attr_accessor :validation_blocks
25
27
 
28
+ def family_registry
29
+ @family_registry ||= HammerCLI::Options::OptionFamilyRegistry.new
30
+ end
31
+
32
+ def option_families
33
+ ancestors.inject([]) do |registry, ancestor|
34
+ next registry unless ancestor <= HammerCLI::AbstractCommand
35
+
36
+ registry + ancestor.family_registry
37
+ end
38
+ end
39
+
26
40
  def help_extension_blocks
27
41
  @help_extension_blocks ||= []
28
42
  end
@@ -41,25 +55,37 @@ module HammerCLI
41
55
  extensions
42
56
  end
43
57
 
44
- def extend_options_help(option)
58
+ def add_option_schema(option)
45
59
  extend_help do |h|
60
+ option_details = h.find_item(:s_option_details)
46
61
  begin
47
- h.find_item(:s_option_details)
62
+ option_details.definition.find_item(:t_schema_help)
48
63
  rescue ArgumentError
49
- option_details = HammerCLI::Help::Section.new(_('Option details'), nil, id: :s_option_details, richtext: true)
50
64
  option_details.definition << HammerCLI::Help::Text.new(
51
65
  _('Following parameters accept format defined by its schema ' \
52
- '(bold are required; <> contain acceptable type; [] contain acceptable value):')
66
+ '(bold are required; <> contains acceptable type; [] contains acceptable value):'),
67
+ id: :t_schema_help
53
68
  )
54
- h.definition.unshift(option_details)
55
- ensure
56
- h.find_item(:s_option_details).definition << HammerCLI::Help::List.new([
57
- [option.switches.last, option.value_formatter.schema.description]
58
- ])
59
69
  end
70
+ option_details.definition << HammerCLI::Help::List.new([
71
+ [option.switches.last, option.value_formatter.schema.description]
72
+ ])
60
73
  end
61
74
  end
62
75
 
76
+ def add_option_details_section(help)
77
+ option_details = HammerCLI::Help::Section.new(_('Option details'), nil, id: :s_option_details, richtext: true)
78
+ option_details.definition << HammerCLI::Help::Text.new(
79
+ _('Here you can find option types and the value an option can accept:')
80
+ )
81
+ type_list = HammerCLI::Options::Normalizers.available.each_with_object([]) do |n, l|
82
+ l << [n.completion_type.to_s.upcase, n.common_description]
83
+ end.uniq(&:first).sort
84
+
85
+ option_details.definition << HammerCLI::Help::List.new(type_list)
86
+ help.definition.unshift(option_details)
87
+ end
88
+
63
89
  def add_sets_help(help)
64
90
  sets_details = HammerCLI::Help::Section.new(_('Predefined field sets'), nil, id: :s_sets_details, richtext: true)
65
91
  sets_details.definition << HammerCLI::Help::Text.new(output_definition.sets_table)
@@ -75,7 +101,7 @@ module HammerCLI
75
101
  begin
76
102
  begin
77
103
  exit_code = super
78
- context.delete(:fields)
104
+ clean_up_context
79
105
  raise "exit code must be integer" unless exit_code.is_a? Integer
80
106
  rescue => e
81
107
  exit_code = handle_exception(e)
@@ -97,6 +123,10 @@ module HammerCLI
97
123
  HammerCLI::EX_OK
98
124
  end
99
125
 
126
+ def clean_up_context
127
+ context.delete(:fields)
128
+ end
129
+
100
130
  def self.validate_options(mode=:append, target_name=nil, validator: nil, &block)
101
131
  validator ||= HammerCLI::Options::Validators::DSLBlockValidator.new(&block)
102
132
  self.validation_blocks ||= []
@@ -115,6 +145,9 @@ module HammerCLI
115
145
  super
116
146
  context[:path] ||= []
117
147
  context[:path] << self
148
+ self.class.command_extensions.each do |extension|
149
+ extension.command_object(self)
150
+ end
118
151
  end
119
152
 
120
153
  def parent_command
@@ -129,6 +162,7 @@ module HammerCLI
129
162
  super(invocation_path, builder)
130
163
  help_extension = HammerCLI::Help::TextBuilder.new(builder.richtext)
131
164
  fields_switch = HammerCLI::Options::Predefined::OPTIONS[:fields].first[0]
165
+ add_option_details_section(help_extension) if recognised_options.size > 1
132
166
  add_sets_help(help_extension) if find_option(fields_switch)
133
167
  unless help_extension_blocks.empty?
134
168
  help_extension_blocks.each do |extension_block|
@@ -185,18 +219,29 @@ module HammerCLI
185
219
  @option_builder
186
220
  end
187
221
 
222
+ def self.option(switches, type, description, opts = {}, &block)
223
+ option = HammerCLI::Options::OptionDefinition.new(switches, type, description, opts).tap do |option|
224
+ declared_options << option
225
+ block ||= option.default_conversion_block
226
+ define_accessors_for(option, &block)
227
+ add_option_schema(option) if option.value_formatter.is_a?(HammerCLI::Options::Normalizers::ListNested)
228
+ completion_type_for(option, opts)
229
+ end
230
+ option
231
+ end
232
+
188
233
  def self.build_options(builder_params={})
189
234
  builder_params = yield(builder_params) if block_given?
235
+ builder_params[:command] = self
190
236
 
191
237
  option_builder.build(builder_params).each do |option|
192
238
  # skip switches that are already defined
193
- next if option.nil? || option.switches.any? { |s| find_option(s) }
239
+ next if option.nil? || option.family || option.switches.any? { |s| find_option(s) }
194
240
 
195
- adjust_family(option) if option.respond_to?(:family)
196
241
  declared_options << option
197
242
  block ||= option.default_conversion_block
198
243
  define_accessors_for(option, &block)
199
- extend_options_help(option) if option.value_formatter.is_a?(HammerCLI::Options::Normalizers::ListNested)
244
+ add_option_schema(option) if option.value_formatter.is_a?(HammerCLI::Options::Normalizers::ListNested)
200
245
  completion_type_for(option)
201
246
  end
202
247
  end
@@ -207,11 +252,12 @@ module HammerCLI
207
252
  raise ArgumentError, _('Command extensions should be inherited from %s.') % HammerCLI::CommandExtensions
208
253
  end
209
254
  extension.delegatee(self)
210
- extension.extend_predefined_options(self)
211
- extension.extend_options(self)
212
- extension.extend_option_family(self)
213
- extension.extend_output(self)
214
- extension.extend_help(self)
255
+ extension.command_class(self)
256
+ extension.extend_predefined_options
257
+ extension.extend_options
258
+ extension.extend_option_family
259
+ extension.extend_output
260
+ extension.extend_help
215
261
  logger('Extensions').info "Applied #{extension.details} on #{self}."
216
262
  command_extensions << extension
217
263
  end
@@ -223,14 +269,20 @@ module HammerCLI
223
269
  end
224
270
  end
225
271
 
226
- protected
227
-
228
272
  def self.option_family(options = {}, &block)
229
273
  options[:creator] ||= self
230
- family = HammerCLI::Options::OptionFamily.new(options)
231
- family.instance_eval(&block)
274
+ family = if options[:associate]
275
+ option_families.find { |f| f.root.to_s == options[:associate].to_s }
276
+ else
277
+ HammerCLI::Options::OptionFamily.new(options)
278
+ end
279
+ return family.instance_eval(&block) if family
280
+
281
+ logger('Option Family').debug "No family found for #{options[:associate]}, skipping"
232
282
  end
233
283
 
284
+ protected
285
+
234
286
  def self.find_options(switch_filter, other_filters={})
235
287
  filters = other_filters
236
288
  if switch_filter.is_a? Hash
@@ -329,17 +381,6 @@ module HammerCLI
329
381
  end
330
382
  end
331
383
 
332
- def self.option(switches, type, description, opts = {}, &block)
333
- option = HammerCLI::Options::OptionDefinition.new(switches, type, description, opts).tap do |option|
334
- declared_options << option
335
- block ||= option.default_conversion_block
336
- define_accessors_for(option, &block)
337
- completion_type_for(option, opts)
338
- end
339
- extend_options_help(option) if option.value_formatter.is_a?(HammerCLI::Options::Normalizers::ListNested)
340
- option
341
- end
342
-
343
384
  def all_options
344
385
  option_collector.all_options
345
386
  end
@@ -359,7 +400,7 @@ module HammerCLI
359
400
 
360
401
  sources = HammerCLI::Options::ProcessorList.new([sources])
361
402
  self.class.command_extensions.each do |extension|
362
- extension.extend_option_sources(sources, self)
403
+ extension.extend_option_sources(sources)
363
404
  end
364
405
  sources
365
406
  end
@@ -402,32 +443,6 @@ module HammerCLI
402
443
 
403
444
  private
404
445
 
405
- def self.adjust_family(option)
406
- # Collect options that should share the same family
407
- # If those options have family, adopt the current one
408
- # Else adopt those options to the family of the current option
409
- # NOTE: this shouldn't rewrite any options,
410
- # although options from similar family could be adopted (appended)
411
- options = find_options(
412
- aliased_resource: option.aliased_resource.to_s
413
- ).select { |o| o.family.nil? || o.family.formats.include?(option.value_formatter.class) }.group_by do |o|
414
- next :to_skip if option.family.children.include?(o)
415
- next :to_adopt if o.family.nil? || o.family.head.nil?
416
- next :to_skip if o.family.children.include?(option)
417
- # If both family heads handle the same switch
418
- # then `option` is probably from similar family and can be adopted
419
- next :adopt_by if option.family.head.nil? || o.family.head.handles?(option.family.head.long_switch)
420
-
421
- :to_skip
422
- end
423
- options[:to_adopt]&.each do |child|
424
- option.family&.adopt(child)
425
- end
426
- options[:adopt_by]&.map(&:family)&.uniq&.each do |family|
427
- family.adopt(option)
428
- end
429
- end
430
-
431
446
  def self.inherited_output_definition
432
447
  od = nil
433
448
  if superclass.respond_to? :output_definition
@@ -86,9 +86,9 @@ module HammerCLI::Apipie
86
86
  declared_options << option
87
87
  block ||= option.default_conversion_block
88
88
  define_accessors_for(option, &block)
89
+ add_option_schema(option) if option.value_formatter.is_a?(HammerCLI::Options::Normalizers::ListNested)
89
90
  completion_type_for(option, opts)
90
91
  end
91
- extend_options_help(option) if option.value_formatter.is_a?(HammerCLI::Options::Normalizers::ListNested)
92
92
  option
93
93
  end
94
94
 
@@ -9,11 +9,11 @@ module HammerCLI::Apipie
9
9
  @require_options = options[:require_options].nil? ? true : options[:require_options]
10
10
  end
11
11
 
12
- def build(builder_params={})
12
+ def build(builder_params = {})
13
13
  filter = Array(builder_params[:without])
14
14
  resource_name_map = builder_params[:resource_mapping] || {}
15
15
 
16
- options_for_params(@action.params, filter, resource_name_map)
16
+ options_for_params(@action.params, filter, resource_name_map, command: builder_params[:command])
17
17
  end
18
18
 
19
19
  attr_writer :require_options
@@ -27,21 +27,24 @@ module HammerCLI::Apipie
27
27
  HammerCLI::Apipie::OptionDefinition.new(*args)
28
28
  end
29
29
 
30
- def options_for_params(params, filter, resource_name_map)
31
- opts = []
30
+ def options_for_params(params, filter, resource_name_map, opts = {})
31
+ options = []
32
32
  params.each do |p|
33
- next if filter.include?(p.name) || filter.include?(p.name.to_sym)
33
+ exists = opts[:command].find_option(option_switch(p, resource_name_map))
34
+ next if filter.include?(p.name) || filter.include?(p.name.to_sym) || exists
35
+
34
36
  if p.expected_type == :hash
35
- opts += options_for_params(p.params, filter, resource_name_map)
37
+ options += options_for_params(p.params, filter, resource_name_map, opts)
36
38
  else
37
- opts << create_option(p, resource_name_map)
39
+ options << create_option(p, resource_name_map, opts)
38
40
  end
39
41
  end
40
- opts
42
+ options
41
43
  end
42
44
 
43
- def create_option(param, resource_name_map)
44
- family = HammerCLI::Options::OptionFamily.new
45
+ def create_option(param, resource_name_map, opts = {})
46
+ family = HammerCLI::Options::OptionFamily.new(creator: opts[:command])
47
+ # APIdoc params are considered to be the main options (parent) by default
45
48
  family.parent(option_switch(param, resource_name_map),
46
49
  option_type(param, resource_name_map),
47
50
  option_desc(param),
@@ -72,7 +75,9 @@ module HammerCLI::Apipie
72
75
  elsif param.expected_type.to_s == 'boolean' || param.validator.to_s == 'boolean'
73
76
  opts[:format] = HammerCLI::Options::Normalizers::Bool.new
74
77
  elsif param.expected_type.to_s == 'string' && param.validator =~ /Must be one of: (.*)\./
75
- allowed = $1.split(/,\ ?/).map { |val| val.gsub(/<[^>]*>/i,'') }
78
+ allowed = $1.split(/,\ ?/).map { |val| val.gsub(/<[^>]*>/i, '') }.map do |item|
79
+ CGI.unescapeHTML(item)
80
+ end
76
81
  opts[:format] = HammerCLI::Options::Normalizers::Enum.new(allowed)
77
82
  elsif param.expected_type.to_s == 'numeric'
78
83
  opts[:format] = HammerCLI::Options::Normalizers::Number.new
@@ -2,22 +2,15 @@ require File.join(File.dirname(__FILE__), 'options')
2
2
 
3
3
  module HammerCLI::Apipie
4
4
  class OptionDefinition < HammerCLI::Options::OptionDefinition
5
- attr_accessor :referenced_resource, :aliased_resource, :family
5
+ attr_accessor :referenced_resource, :aliased_resource
6
6
 
7
7
  def initialize(switches, type, description, options = {})
8
8
  @referenced_resource = options[:referenced_resource].to_s if options[:referenced_resource]
9
9
  @aliased_resource = options[:aliased_resource].to_s if options[:aliased_resource]
10
- @family = options[:family]
11
10
  super
12
11
  # Apipie currently sends descriptions as escaped HTML once this is changed this should be removed.
13
12
  # See #15198 on Redmine.
14
13
  @description = CGI::unescapeHTML(description)
15
14
  end
16
-
17
- def child?
18
- return unless @family
19
-
20
- @family.children.include?(self)
21
- end
22
15
  end
23
16
  end
@@ -87,86 +87,97 @@ module HammerCLI
87
87
  end
88
88
 
89
89
  def self.option_family(options = {}, &block)
90
- @option_family_opts = options
91
- @option_family_block = block
90
+ @option_family_extensions ||= []
91
+ @option_family_extensions << {
92
+ options: options,
93
+ block: block
94
+ }
92
95
  end
93
96
 
94
97
  # Object
95
98
 
96
- def extend_options(command_class)
99
+ def extend_options
97
100
  allowed = @only & %i[command_options option]
98
101
  return if allowed.empty? || (allowed & @except).any?
99
102
 
100
- self.class.extend_options(command_class)
103
+ self.class.extend_options(@command_class)
101
104
  end
102
105
 
103
- def extend_predefined_options(command_class)
106
+ def extend_predefined_options
104
107
  allowed = @only & %i[predefined_options use_option]
105
108
  return if allowed.empty? || (allowed & @except).any?
106
109
 
107
- self.class.extend_predefined_options(command_class)
110
+ self.class.extend_predefined_options(@command_class)
108
111
  end
109
112
 
110
113
  def extend_before_print(data)
111
114
  allowed = @only & %i[before_print data]
112
115
  return if allowed.empty? || (allowed & @except).any?
113
116
 
114
- self.class.extend_before_print(data)
117
+ self.class.extend_before_print(data, @command_object, @command_class)
115
118
  end
116
119
 
117
- def extend_output(command_class)
120
+ def extend_output
118
121
  allowed = @only & %i[output]
119
122
  return if allowed.empty? || (allowed & @except).any?
120
123
 
121
- self.class.extend_output(command_class)
124
+ self.class.extend_output(@command_class, @command_object)
122
125
  end
123
126
 
124
- def extend_help(command_class)
127
+ def extend_help
125
128
  allowed = @only & %i[help]
126
129
  return if allowed.empty? || (allowed & @except).any?
127
130
 
128
- self.class.extend_help(command_class)
131
+ self.class.extend_help(@command_class)
129
132
  end
130
133
 
131
134
  def extend_request_headers(headers)
132
135
  allowed = @only & %i[request_headers headers request]
133
136
  return if allowed.empty? || (allowed & @except).any?
134
137
 
135
- self.class.extend_request_headers(headers)
138
+ self.class.extend_request_headers(headers, @command_object, @command_class)
136
139
  end
137
140
 
138
141
  def extend_request_options(options)
139
142
  allowed = @only & %i[request_options options request]
140
143
  return if allowed.empty? || (allowed & @except).any?
141
144
 
142
- self.class.extend_request_options(options)
145
+ self.class.extend_request_options(options, @command_object, @command_class)
143
146
  end
144
147
 
145
148
  def extend_request_params(params)
146
149
  allowed = @only & %i[request_params params request]
147
150
  return if allowed.empty? || (allowed & @except).any?
148
151
 
149
- self.class.extend_request_params(params)
152
+ self.class.extend_request_params(params, @command_object, @command_class)
150
153
  end
151
154
 
152
- def extend_option_sources(sources, command = nil)
155
+ def extend_option_sources(sources)
153
156
  allowed = @only & %i[option_sources]
154
157
  return if allowed.empty? || (allowed & @except).any?
155
158
 
156
- self.class.extend_option_sources(sources, command)
159
+ self.class.extend_option_sources(sources, @command_object, @command_class)
157
160
  end
158
161
 
159
- def extend_option_family(command_class)
162
+ def extend_option_family
160
163
  allowed = @only & %i[option_family]
161
164
  return if allowed.empty? || (allowed & @except).any?
162
165
 
163
- self.class.extend_option_family(command_class)
166
+ self.class.extend_option_family(@command_class)
164
167
  end
165
168
 
166
169
  def delegatee(command_class)
167
170
  self.class.delegatee = command_class
168
171
  end
169
172
 
173
+ def command_class(command_class)
174
+ @command_class = command_class
175
+ end
176
+
177
+ def command_object(command_object)
178
+ @command_object = command_object
179
+ end
180
+
170
181
  def details
171
182
  except = @except.empty? ? '*nothing*' : @except
172
183
  details = if @only == ALLOWED_EXTENSIONS
@@ -198,17 +209,17 @@ module HammerCLI
198
209
  logger.debug("Added predefined options for #{command_class}: #{@predefined_option_names}")
199
210
  end
200
211
 
201
- def self.extend_before_print(data)
212
+ def self.extend_before_print(data, command_object, command_class)
202
213
  return if @before_print_block.nil?
203
214
 
204
- @before_print_block.call(data)
215
+ @before_print_block.call(data, command_object, command_class)
205
216
  logger.debug("Called block for #{@delegatee} data:\n\t#{@before_print_block}")
206
217
  end
207
218
 
208
- def self.extend_output(command_class)
219
+ def self.extend_output(command_class, command_object)
209
220
  return if @output_extension_block.nil?
210
221
 
211
- @output_extension_block.call(command_class.output_definition)
222
+ @output_extension_block.call(command_class.output_definition, command_object, command_class)
212
223
  logger.debug("Called block for #{@delegatee} output definition:\n\t#{@output_extension_block}")
213
224
  end
214
225
 
@@ -219,40 +230,42 @@ module HammerCLI
219
230
  logger.debug("Saved block for #{@delegatee} help definition:\n\t#{@help_extension_block}")
220
231
  end
221
232
 
222
- def self.extend_request_headers(headers)
233
+ def self.extend_request_headers(headers, command_object, command_class)
223
234
  return if @request_headers_block.nil?
224
235
 
225
- @request_headers_block.call(headers)
236
+ @request_headers_block.call(headers, command_object, command_class)
226
237
  logger.debug("Called block for #{@delegatee} request headers:\n\t#{@request_headers_block}")
227
238
  end
228
239
 
229
- def self.extend_request_options(options)
240
+ def self.extend_request_options(options, command_object, command_class)
230
241
  return if @request_options_block.nil?
231
242
 
232
- @request_options_block.call(options)
243
+ @request_options_block.call(options, command_object, command_class)
233
244
  logger.debug("Called block for #{@delegatee} request options:\n\t#{@request_options_block}")
234
245
  end
235
246
 
236
- def self.extend_request_params(params)
247
+ def self.extend_request_params(params, command_object, command_class)
237
248
  return if @request_params_block.nil?
238
249
 
239
- @request_params_block.call(params)
250
+ @request_params_block.call(params, command_object, command_class)
240
251
  logger.debug("Called block for #{@delegatee} request params:\n\t#{@request_params_block}")
241
252
  end
242
253
 
243
- def self.extend_option_sources(sources, command = nil)
254
+ def self.extend_option_sources(sources, command_object, command_class)
244
255
  return if @option_sources_block.nil?
245
256
 
246
- @option_sources_block.call(sources, command)
257
+ @option_sources_block.call(sources, command_object, command_class)
247
258
  logger.debug("Called block for #{@delegatee} option sources:\n\t#{@option_sources_block}")
248
259
  end
249
260
 
250
261
  def self.extend_option_family(command_class)
251
- return if @option_family_block.nil?
262
+ return if @option_family_extensions.nil?
252
263
 
253
- @option_family_opts[:creator] = command_class
254
- command_class.send(:option_family, @option_family_opts, &@option_family_block)
255
- logger.debug("Called option family block for #{command_class}:\n\t#{@option_family_block}")
264
+ @option_family_extensions.each do |extension|
265
+ extension[:options][:creator] = command_class
266
+ command_class.send(:option_family, extension[:options], &extension[:block])
267
+ logger.debug("Called option family block for #{command_class}:\n\t#{extension[:block]}")
268
+ end
256
269
  end
257
270
  end
258
271
  end