Class: Clin::Command

Inherits:
CommandOptionsMixin show all
Defined in:
lib/clin/command.rb

Overview

Clin Command

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from CommandOptionsMixin

add_option, flag_option, general_option, opt_option, option, register_options, remove_general_option

Constructor Details

#initialize(params) ⇒ Command

Returns a new instance of Command.



191
192
193
194
# File 'lib/clin/command.rb', line 191

def initialize(params)
  @params = params
  self.class.execute_general_options(params)
end

Instance Attribute Details

#paramsObject

Returns the value of attribute params.



189
190
191
# File 'lib/clin/command.rb', line 189

def params
  @params
end

Class Method Details

.abstract(value) ⇒ Object

Mark the class as abstract



34
35
36
# File 'lib/clin/command.rb', line 34

def self.abstract(value)
  self._abstract = value
end

.arguments(args) ⇒ Object



54
55
56
57
58
59
# File 'lib/clin/command.rb', line 54

def self.arguments(args)
  self.args = []
  [*args].map(&:split).flatten.each do |arg|
    self.args += [Clin::Argument.new(arg)]
  end
end


66
67
68
# File 'lib/clin/command.rb', line 66

def self.banner
  "Usage: #{usage}"
end

.default_commandsObject



176
177
178
179
# File 'lib/clin/command.rb', line 176

def self.default_commands
  # self.constants.map { |c| self.const_get(c) }.select { |c| c.is_a?(Class) && (c < Clin::Command) }
  self.subcommands
end

.dispatch(args, prefix: nil, commands: nil) ⇒ Object

Redispatch the command to a sub command with the given arguments If no commands are given it will look for Clin::Command in the class namespace e.g. If those 2 classes are defined. ‘MyDispatcher < Clin::Command` and `MyDispatcher::ChildCommand < Clin::Command` Will test against ChildCommand

Parameters:

  • args (Array<String>|String)

    New argument to parse

  • prefix (String) (defaults to: nil)

    Prefix to add to the beginning of the command

  • commands (Array<Clin::Command.class>) (defaults to: nil)

    Commands that will be tried against



148
149
150
# File 'lib/clin/command.rb', line 148

def self.dispatch(args, prefix: nil, commands: nil)
  self._redispatch_args = [[*args], prefix, commands]
end

.dispatch_doc(opts) ⇒ Object



167
168
169
170
171
172
173
174
# File 'lib/clin/command.rb', line 167

def self.dispatch_doc(opts)
  return if self._redispatch_args.nil?
  opts.separator 'Examples: '
  commands = (self._redispatch_args[2] || default_commands)
  commands.each do |cmd_cls|
    opts.separator "\t#{cmd_cls.usage}"
  end
end

.exe_name(value = nil) ⇒ Object

Set or get the exe name. Executable name that will be display in the usage. If exe_name is not set in a class or it’s parent it will use the global setting Clin.exe_name “‘ class Git < Clin::Command

exe_name 'git'
arguments '<command> <args>...'

end Git.usage # => git <command> <args>… “‘

Parameters:

  • value (String) (defaults to: nil)

    name of the exe.



49
50
51
52
# File 'lib/clin/command.rb', line 49

def self.exe_name(value=nil)
  self._exe_name = value unless value.nil?
  self._exe_name ||= Clin.exe_name
end

.execute_general_options(options) ⇒ Object



124
125
126
127
128
# File 'lib/clin/command.rb', line 124

def self.execute_general_options(options)
  general_options.each do |_cls, gopts|
    gopts.execute(options)
  end
end

.handle_dispatch(params) ⇒ Object

Method called after the argument have been parsed and before creating the command

Parameters:

  • params (List<String>)

    Parsed params from the command line.



154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/clin/command.rb', line 154

def self.handle_dispatch(params)
  args, prefix, commands = self._redispatch_args
  commands ||= default_commands
  dispatcher = Clin::CommandDispatcher.new(commands)
  args = args.map { |x| params[x] }.flatten
  args = prefix.split + args unless prefix.nil?
  begin
    dispatcher.parse(args)
  rescue Clin::HelpError
    raise Clin::HelpError, option_parser
  end
end

.inherited(subclass) ⇒ Object

Trigger when a class inherit this class Rest class_attributes that should not be shared with subclass

Parameters:



27
28
29
30
31
# File 'lib/clin/command.rb', line 27

def self.inherited(subclass)
  subclass._redispatch_args = nil
  subclass._abstract = false
  super
end

.option_parser(out = {}) ⇒ Object

Build the Option Parser object Used to parse the option Useful for regenerating the help as well.



109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/clin/command.rb', line 109

def self.option_parser(out = {})
  OptionParser.new do |opts|
    opts.banner = banner
    opts.separator ''
    opts.separator 'Options:'
    register_options(opts, out)
    dispatch_doc(opts)
    unless description.blank?
      opts.separator "\nDescription:"
      opts.separator description
    end
    opts.separator ''
  end
end

.parse(argv = ARGV, fallback_help: true) ⇒ Object

Parse the command and initialize the command object with the parsed options

Parameters:

  • argv (Array|String) (defaults to: ARGV)

    command line to parse.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/clin/command.rb', line 72

def self.parse(argv = ARGV, fallback_help: true)
  argv = Shellwords.split(argv) if argv.is_a? String
  argv = argv.clone
  options_map = parse_options(argv)
  error = nil
  begin
    args_map = parse_arguments(argv)
  rescue Clin::MissingArgumentError => e
    error = e
  rescue Clin::FixedArgumentError => e
    raise e unless fallback_help
    error = e
  end
  args_map ||= {}

  options = options_map.merge(args_map)
  return handle_dispatch(options) unless self._redispatch_args.nil?
  obj = new(options)
  if error
    fail Clin::HelpError, option_parser if fallback_help
    fail error
  end
  obj
end

.parse_arguments(argv) ⇒ Object

Parse the argument. The options must have been strip out first.



131
132
133
134
135
136
137
138
# File 'lib/clin/command.rb', line 131

def self.parse_arguments(argv)
  out = {}
  self.args.each do |arg|
    value, argv = arg.parse(argv)
    out[arg.name.to_sym] = value
  end
  out.delete_if { |_, v| v.nil? }
end

.parse_options(argv) ⇒ Array

Parse the options in the argv.

Returns:

  • (Array)

    the list of argv that are not options(positional arguments)



99
100
101
102
103
104
# File 'lib/clin/command.rb', line 99

def self.parse_options(argv)
  out = {}
  parser = option_parser(out)
  parser.parse!(argv)
  out
end

.subcommandsObject

List the subcommands The subcommands are all the Classes inheriting this one that are not set to abstract



183
184
185
# File 'lib/clin/command.rb', line 183

def self.subcommands
  self.subclasses.reject(&:_abstract)
end

.usageObject



61
62
63
64
# File 'lib/clin/command.rb', line 61

def self.usage
  a = [exe_name, args.map(&:original).join(' '), '[Options]']
  a.reject(&:blank?).join(' ')
end