Class: HammerCLI::AbstractCommand

Inherits:
Clamp::Command
  • Object
show all
Includes:
Subcommand
Defined in:
lib/hammer_cli/abstract.rb

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Subcommand

included

Constructor Details

#initialize(*args) ⇒ AbstractCommand

Returns a new instance of AbstractCommand.



144
145
146
147
148
149
150
151
# File 'lib/hammer_cli/abstract.rb', line 144

def initialize(*args)
  super
  context[:path] ||= []
  context[:path] << self
  self.class.command_extensions.each do |extension|
    extension.command_object(self)
  end
end

Class Attribute Details

.validation_blocksObject

Returns the value of attribute validation_blocks.



26
27
28
# File 'lib/hammer_cli/abstract.rb', line 26

def validation_blocks
  @validation_blocks
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



23
24
25
# File 'lib/hammer_cli/abstract.rb', line 23

def context
  @context
end

Class Method Details

.add_option_details_section(help) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/hammer_cli/abstract.rb', line 76

def add_option_details_section(help)
  option_details = HammerCLI::Help::Section.new(_('Option details'), nil, id: :s_option_details, richtext: true)
  option_details.definition << HammerCLI::Help::Text.new(
    _('Here you can find option types and the value an option can accept:')
  )
  type_list = HammerCLI::Options::Normalizers.available.each_with_object([]) do |n, l|
    l << [n.completion_type.to_s.upcase, n.common_description]
  end.uniq(&:first).sort

  option_details.definition << HammerCLI::Help::List.new(type_list)
  help.definition.unshift(option_details)
end

.add_option_schema(option) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/hammer_cli/abstract.rb', line 58

def add_option_schema(option)
  extend_help do |h|
    option_details = h.find_item(:s_option_details)
    begin
      option_details.definition.find_item(:t_schema_help)
    rescue ArgumentError
      option_details.definition << HammerCLI::Help::Text.new(
        _('Following parameters accept format defined by its schema ' \
          '(bold are required; <> contains acceptable type; [] contains acceptable value):'),
        id: :t_schema_help
      )
    end
    option_details.definition << HammerCLI::Help::List.new([
      [option.switches.last, option.value_formatter.schema.description]
    ])
  end
end

.add_sets_help(help) ⇒ Object



89
90
91
92
93
# File 'lib/hammer_cli/abstract.rb', line 89

def add_sets_help(help)
  sets_details = HammerCLI::Help::Section.new(_('Predefined field sets'), nil, id: :s_sets_details, richtext: true)
  sets_details.definition << HammerCLI::Help::Text.new(output_definition.sets_table)
  help.definition.unshift(sets_details)
end

.build_options(builder_params = {}) ⇒ Object



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/hammer_cli/abstract.rb', line 233

def self.build_options(builder_params={})
  builder_params = yield(builder_params) if block_given?
  builder_params[:command] = self

  option_builder.build(builder_params).each do |option|
    # skip switches that are already defined
    next if option.nil? || option.family || option.switches.any? { |s| find_option(s) }

    declared_options << option
    block ||= option.default_conversion_block
    define_accessors_for(option, &block)
    add_option_schema(option) if option.value_formatter.is_a?(HammerCLI::Options::Normalizers::ListNested)
    completion_type_for(option)
  end
end

.command_extensionsObject



44
45
46
47
# File 'lib/hammer_cli/abstract.rb', line 44

def command_extensions
  @command_extensions = @command_extensions || inherited_command_extensions || []
  @command_extensions
end

.extend_help(&block) ⇒ Object



181
182
183
184
# File 'lib/hammer_cli/abstract.rb', line 181

def self.extend_help(&block)
  # We save the block for execution on object level, where we can access command's context and check :is_tty? flag
  self.help_extension_blocks << block
end

.extend_output_definition(&block) ⇒ Object



186
187
188
189
190
191
# File 'lib/hammer_cli/abstract.rb', line 186

def self.extend_output_definition(&block)
  block.call(output_definition)
rescue ArgumentError => e
  handler = HammerCLI::ExceptionHandler.new
  handler.handle_exception(e)
end

.extend_with(*extensions) ⇒ Object



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/hammer_cli/abstract.rb', line 249

def self.extend_with(*extensions)
  extensions.each do |extension|
    unless extension.is_a?(HammerCLI::CommandExtensions)
      raise ArgumentError, _('Command extensions should be inherited from %s.') % HammerCLI::CommandExtensions
    end
    extension.delegatee(self)
    extension.command_class(self)
    extension.extend_predefined_options
    extension.extend_options
    extension.extend_option_family
    extension.extend_output
    extension.extend_help
    logger('Extensions').info "Applied #{extension.details} on #{self}."
    command_extensions << extension
  end
end

.family_registryObject



28
29
30
# File 'lib/hammer_cli/abstract.rb', line 28

def family_registry
  @family_registry ||= HammerCLI::Options::OptionFamilyRegistry.new
end

.help(invocation_path, builder = HammerCLI::Help::Builder.new) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/hammer_cli/abstract.rb', line 161

def self.help(invocation_path, builder = HammerCLI::Help::Builder.new)
  super(invocation_path, builder)
  help_extension = HammerCLI::Help::TextBuilder.new(builder.richtext)
  fields_switch = HammerCLI::Options::Predefined::OPTIONS[:fields].first[0]
  add_option_details_section(help_extension) if recognised_options.size > 1
  add_sets_help(help_extension) if find_option(fields_switch)
  unless help_extension_blocks.empty?
    help_extension_blocks.each do |extension_block|
      begin
        extension_block.call(help_extension)
      rescue ArgumentError => e
        handler = HammerCLI::ExceptionHandler.new
        handler.handle_exception(e)
      end
    end
  end
  builder.add_text(help_extension.string)
  builder.string
end

.help_extension_blocksObject



40
41
42
# File 'lib/hammer_cli/abstract.rb', line 40

def help_extension_blocks
  @help_extension_blocks ||= []
end

.inherited_command_extensionsObject



49
50
51
52
53
54
55
56
# File 'lib/hammer_cli/abstract.rb', line 49

def inherited_command_extensions
  extensions = nil
  if superclass.respond_to?(:command_extensions)
    parent_extensions = superclass.command_extensions.select(&:inheritable?)
    extensions = parent_extensions.dup unless parent_extensions.empty?
  end
  extensions
end

.option(switches, type, description, opts = {}, &block) ⇒ Object



222
223
224
225
226
227
228
229
230
231
# File 'lib/hammer_cli/abstract.rb', line 222

def self.option(switches, type, description, opts = {}, &block)
  option = HammerCLI::Options::OptionDefinition.new(switches, type, description, opts).tap do |option|
    declared_options << option
    block ||= option.default_conversion_block
    define_accessors_for(option, &block)
    add_option_schema(option) if option.value_formatter.is_a?(HammerCLI::Options::Normalizers::ListNested)
    completion_type_for(option, opts)
  end
  option
end

.option_builderObject



217
218
219
220
# File 'lib/hammer_cli/abstract.rb', line 217

def self.option_builder
  @option_builder ||= create_option_builder
  @option_builder
end

.option_familiesObject



32
33
34
35
36
37
38
# File 'lib/hammer_cli/abstract.rb', line 32

def option_families
  ancestors.inject([]) do |registry, ancestor|
    next registry unless ancestor <= HammerCLI::AbstractCommand

    registry + ancestor.family_registry
  end
end

.option_family(options = {}, &block) ⇒ Object



272
273
274
275
276
277
278
279
280
281
282
# File 'lib/hammer_cli/abstract.rb', line 272

def self.option_family(options = {}, &block)
  options[:creator] ||= self
  family = if options[:associate]
             option_families.find { |f| f.root.to_s == options[:associate].to_s }
           else
             HammerCLI::Options::OptionFamily.new(options)
           end
  return family.instance_eval(&block) if family

  logger('Option Family').debug "No family found for #{options[:associate]}, skipping"
end

.output(definition = nil, &block) ⇒ Object



193
194
195
196
197
198
# File 'lib/hammer_cli/abstract.rb', line 193

def self.output(definition=nil, &block)
  dsl = HammerCLI::Output::Dsl.new
  dsl.build &block if block_given?
  output_definition.append definition.fields unless definition.nil?
  output_definition.append dsl.fields
end

.output_definitionObject



208
209
210
211
# File 'lib/hammer_cli/abstract.rb', line 208

def self.output_definition
  @output_definition = @output_definition || inherited_output_definition || HammerCLI::Output::Definition.new
  @output_definition
end

.use_option(*names) ⇒ Object



266
267
268
269
270
# File 'lib/hammer_cli/abstract.rb', line 266

def self.use_option(*names)
  names.each do |name|
    HammerCLI::Options::Predefined.use(name, self)
  end
end

.validate_options(mode = :append, target_name = nil, validator: nil, &block) ⇒ Object



130
131
132
133
134
# File 'lib/hammer_cli/abstract.rb', line 130

def self.validate_options(mode=:append, target_name=nil, validator: nil, &block)
  validator ||= HammerCLI::Options::Validators::DSLBlockValidator.new(&block)
  self.validation_blocks ||= []
  self.validation_blocks << [mode, target_name, validator]
end

Instance Method Details

#adapterObject



96
97
98
# File 'lib/hammer_cli/abstract.rb', line 96

def adapter
  :base
end

#clean_up_contextObject



126
127
128
# File 'lib/hammer_cli/abstract.rb', line 126

def clean_up_context
  context.delete(:fields)
end

#exception_handlerObject



140
141
142
# File 'lib/hammer_cli/abstract.rb', line 140

def exception_handler
  @exception_handler ||= exception_handler_class.new(:output => output)
end

#executeObject



122
123
124
# File 'lib/hammer_cli/abstract.rb', line 122

def execute
  HammerCLI::EX_OK
end

#helpObject



157
158
159
# File 'lib/hammer_cli/abstract.rb', line 157

def help
  self.class.help(invocation_path, HammerCLI::Help::Builder.new(context[:is_tty?]))
end

#interactive?Boolean

Returns:

  • (Boolean)


213
214
215
# File 'lib/hammer_cli/abstract.rb', line 213

def interactive?
  HammerCLI.interactive?
end

#outputObject



200
201
202
# File 'lib/hammer_cli/abstract.rb', line 200

def output
  @output ||= HammerCLI::Output::Output.new(context, :default_adapter => adapter)
end

#output_definitionObject



204
205
206
# File 'lib/hammer_cli/abstract.rb', line 204

def output_definition
  self.class.output_definition
end

#parent_commandObject



153
154
155
# File 'lib/hammer_cli/abstract.rb', line 153

def parent_command
  context[:path][-2]
end

#parse(arguments) ⇒ Object



114
115
116
117
118
119
120
# File 'lib/hammer_cli/abstract.rb', line 114

def parse(arguments)
  super
  validate_options
  logger.info "Called with options: %s" % options.inspect
rescue HammerCLI::Options::Validators::ValidationError => e
  signal_usage_error e.message
end

#run(arguments) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/hammer_cli/abstract.rb', line 100

def run(arguments)
  begin
    begin
      exit_code = super
      clean_up_context
      raise "exit code must be integer" unless exit_code.is_a? Integer
    rescue => e
      exit_code = handle_exception(e)
    end
    logger.debug 'Retrying the command' if (exit_code == HammerCLI::EX_RETRY)
  end while (exit_code == HammerCLI::EX_RETRY)
  return exit_code
end

#validate_optionsObject



136
137
138
# File 'lib/hammer_cli/abstract.rb', line 136

def validate_options
  # keep the method for legacy reasons
end