hammer_cli 2.5.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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