Class: Boson::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/boson/command.rb

Overview

A command starts with the functionality of a ruby method and adds benefits with options, render_options, etc.

Constant Summary collapse

ATTRIBUTES =
[:name, :lib, :alias, :desc, :options, :args, :config]

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes) ⇒ Command

A hash of attributes which map to instance variables and values. :name and :lib are required keys.

Attributes that can be configured:

:desc

Description that shows up in command listings

:alias

Alternative name for command

:options

Hash of options passed to OptionParser

:render_options

Hash of rendering options to pass to OptionParser. If the key :output_class is passed, that class’s Hirb config will serve as defaults for this rendering hash.

:option_command

Boolean to wrap a command with an OptionCommand object i.e. allow commands to have options.

:args

Should only be set if not automatically set. This attribute is only important for commands that have options/render_options. Its value can be an array (as ArgumentInspector.scrape_with_eval produces), a number representing the number of arguments or ‘*’ if the command has a variable number of arguments.

:default_option

Only for an option command that has one or zero arguments. This treats the given option as an optional first argument. Example:

# For a command with default option 'query' and options --query and -v
'some -v'   -> '--query=some -v'
'-v'        -> '-v'
:config

A hash for third party libraries to get and set custom command attributes.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/boson/command.rb', line 61

def initialize(attributes)
  hash = attributes.dup
  @name = hash.delete(:name) or raise ArgumentError
  @lib = hash.delete(:lib) or raise ArgumentError
  [:alias, :desc, :options, :namespace, :default_option, :option_command].each do |e|
      instance_variable_set("@#{e}", hash.delete(e)) if hash.key?(e)
  end

  if hash[:render_options] && (@render_options = hash.delete(:render_options))[:output_class]
    @render_options = Util.recursive_hash_merge View.class_config(@render_options[:output_class]), @render_options
  end

  if (args = hash.delete(:args))
    if args.is_a?(Array)
      @args = args
    elsif args.to_s[/^\d+/]
      @arg_size = args.to_i
    elsif args == '*'
      @args = [['*args']]
    end
  end
  @config = Util.recursive_hash_merge hash, hash.delete(:config) || {}
end

Class Attribute Details

.all_option_commandsObject

Returns the value of attribute all_option_commands.



4
5
6
# File 'lib/boson/command.rb', line 4

def all_option_commands
  @all_option_commands
end

Class Method Details

.create(name, library) ⇒ Object

Creates a command given its name and a library.



7
8
9
10
11
12
13
# File 'lib/boson/command.rb', line 7

def self.create(name, library)
  obj = new(new_attributes(name, library))
  if @all_option_commands && !%w{get method_missing}.include?(name)
    obj.make_option_command(library)
  end
  obj
end

.find(command, commands = Boson.commands) ⇒ Object

Finds a command, namespaced or not and aliased or not. If found returns the command object, otherwise returns nil.



22
23
24
25
26
27
28
29
30
31
32
# File 'lib/boson/command.rb', line 22

def self.find(command, commands=Boson.commands)
  if command.to_s.include?(NAMESPACE)
    command, subcommand = command.to_s.split(NAMESPACE, 2)
    commands.find {|current_command|
      [current_command.name, current_command.alias].include?(subcommand) &&
      current_command.library && (current_command.library.namespace == command)
    }
  else
    commands.find {|e| [e.name, e.alias].include?(command) && !e.namespace}
  end
end

.new_attributes(name, library) ⇒ Object

Used to generate a command’s initial attributes when creating a command object



16
17
18
# File 'lib/boson/command.rb', line 16

def self.new_attributes(name, library)
  (library.commands_hash[name] || {}).merge({:name=>name, :lib=>library.name, :namespace=>library.namespace})
end

.usage(command) ⇒ Object

One line usage for a command if it exists



35
36
37
# File 'lib/boson/command.rb', line 35

def self.usage(command)
  (cmd = find(command)) ? "#{command} #{cmd.usage}" : "Command '#{command}' not found"
end

Instance Method Details

#arg_sizeObject



167
168
169
170
# File 'lib/boson/command.rb', line 167

def arg_size
  @arg_size = args ? args.size : nil unless instance_variable_defined?("@arg_size")
  @arg_size
end

#args(lib = library) ⇒ Object

Array of array args with optional defaults. Scraped with ArgumentInspector.



91
92
93
94
95
96
97
98
99
# File 'lib/boson/command.rb', line 91

def args(lib=library)
  @args = !@args.nil? ? @args : begin
    if lib
      file_string, meth = file_string_and_method_for_args(lib)
      (file_string && meth && (@file_parsed_args = true) &&
        ArgumentInspector.scrape_with_text(file_string, meth))
    end || false
  end
end

#configObject

:stopdoc: until @config is consistent in index + actual loading



136
137
138
# File 'lib/boson/command.rb', line 136

def config
  @config ||= {}
end

#descriptionObject

Deprecated method



177
178
179
180
181
# File 'lib/boson/command.rb', line 177

def description
  puts "@command.description has been changed to @command.desc. Delete your old " +
    "Boson index at ~/.boson/command/index.marshal for Boson to work from the commandline."
  Kernel.exit
end

#file_parsed_args?Boolean

Returns:

  • (Boolean)


172
173
174
# File 'lib/boson/command.rb', line 172

def file_parsed_args?
  @file_parsed_args
end

#file_string_and_method_for_args(lib) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/boson/command.rb', line 140

def file_string_and_method_for_args(lib)
  if !lib.is_a?(ModuleLibrary) && (klass_method = (lib.class_commands || {})[@name])
    if RUBY_VERSION >= '1.9'
      klass, meth = klass_method.split(NAMESPACE, 2)
      if (meth_locations = MethodInspector.find_method_locations_for_19(klass, meth))
        file_string = File.read meth_locations[0]
      end
    end
  elsif File.exists?(lib.library_file || '')
    file_string, meth = FileLibrary.read_library_file(lib.library_file), @name
  end
  [file_string, meth]
end

#full_nameObject

Full name is only different than name if a command has a namespace. The full name should be what you would type to execute the command.



130
131
132
# File 'lib/boson/command.rb', line 130

def full_name
  @namespace ? "#{@namespace}.#{@name}" : @name
end

#has_splat_args?Boolean

Returns:

  • (Boolean)


154
155
156
# File 'lib/boson/command.rb', line 154

def has_splat_args?
  !!(args && @args[-1] && @args[-1][0][/^\*/])
end

#libraryObject

Library object a command belongs to.



86
87
88
# File 'lib/boson/command.rb', line 86

def library
  @library ||= Boson.library(@lib)
end

#make_option_command(lib = library) ⇒ Object



158
159
160
161
# File 'lib/boson/command.rb', line 158

def make_option_command(lib=library)
  @option_command = true
  @args = [['*args']] unless args(lib) || arg_size
end

#marshal_dumpObject



183
184
185
186
187
188
189
# File 'lib/boson/command.rb', line 183

def marshal_dump
  if @args && @args.any? {|e| e[1].is_a?(Module) }
    @args.map! {|e| e.size == 2 ? [e[0], e[1].inspect] : e }
    @file_parsed_args = true
  end
  [@name, @alias, @lib, @desc, @options, @render_options, @args, @default_option]
end

#marshal_load(ary) ⇒ Object



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

def marshal_load(ary)
  @name, @alias, @lib, @desc, @options, @render_options, @args, @default_option = ary
end

#option_command?Boolean

Returns:

  • (Boolean)


163
164
165
# File 'lib/boson/command.rb', line 163

def option_command?
  options || render_options || @option_command
end

#option_helpObject

Help string for options if a command has it.



112
113
114
# File 'lib/boson/command.rb', line 112

def option_help
  @options ? option_parser.to_s : ''
end

#option_parserObject

Option parser for command as defined by @options.



102
103
104
# File 'lib/boson/command.rb', line 102

def option_parser
  @option_parser ||= OptionParser.new(@options || {})
end

#render_option_parserObject

Option parser for command as defined by @render_options.



107
108
109
# File 'lib/boson/command.rb', line 107

def render_option_parser
  option_command? ? Boson::Scientist.option_command(self).option_parser : nil
end

#usageObject

Usage string for command, created from options and args.



117
118
119
120
121
122
123
124
125
126
# File 'lib/boson/command.rb', line 117

def usage
  return '' if options.nil? && args.nil?
  usage_args = args && @options && !has_splat_args? ?
    (@default_option ? [[@default_option.to_s, @file_parsed_args ? ''.inspect : '']] + args[0..-2] :
    args[0..-2]) : args
  str = args ? usage_args.map {|e|
    (e.size < 2) ? "[#{e[0]}]" : "[#{e[0]}=#{@file_parsed_args ? e[1] : e[1].inspect}]"
  }.join(' ') : '[*unknown]'
  str + option_help
end