Class: Mothership

Inherits:
Object
  • Object
show all
Defined in:
lib/mothership.rb,
lib/mothership/base.rb,
lib/mothership/help.rb,
lib/mothership/errors.rb,
lib/mothership/inputs.rb,
lib/mothership/parser.rb,
lib/mothership/command.rb,
lib/mothership/version.rb,
lib/mothership/callbacks.rb

Defined Under Namespace

Modules: Help, Pretty, Progress Classes: Command, Error, ExtraArguments, Inputs, MissingArgument, Parser, TypeMismatch

Constant Summary collapse

VERSION =
"0.0.6"
@@global =
Mothership::Command

global options

Command.new(self, "(global options)")
@@inputs =

parsed global input set

nil
@@exit_status =
Fixnum

exit status; reassign as appropriate error code (e.g. 1)

0
@@commands =

all commands

{}
@@filters =

temporary filters via #with_filters

command => { tag => [callbacks] }

Hash.new { |h, k| h[k] = Hash.new { |h, k| h[k] = [] } }

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(command = nil) ⇒ Mothership

Initialize with the command being executed.



12
13
14
# File 'lib/mothership/base.rb', line 12

def initialize(command = nil)
  @command = command
end

Class Method Details

.after(name, &callback) ⇒ Object

register a callback that’s evaluated after a command is run



14
15
16
# File 'lib/mothership/callbacks.rb', line 14

def after(name, &callback)
  @@commands[name].after << [callback, self]
end

.alias_command(orig, new) ⇒ Object



39
40
41
# File 'lib/mothership/base.rb', line 39

def alias_command(orig, new)
  @@commands[new] = @@commands[orig]
end

.around(name, &callback) ⇒ Object

register a callback that’s evaluated around a command, controlling its evaluation (i.e. inputs)



20
21
22
# File 'lib/mothership/callbacks.rb', line 20

def around(name, &callback)
  @@commands[name].around << [callback, self]
end

.before(name, &callback) ⇒ Object

register a callback that’s evaluated before a command is run



9
10
11
# File 'lib/mothership/callbacks.rb', line 9

def before(name, &callback)
  @@commands[name].before << [callback, self]
end

.change_argument(name, arg, to) ⇒ Object

change an argument’s status, i.e. optional, splat, or required



31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/mothership/callbacks.rb', line 31

def change_argument(name, arg, to)
  changed = false

  @@commands[name].arguments.each do |a|
    if a[:name] == arg
      a[:type] = to
      changed = true
    end
  end

  changed
end

.desc(description) ⇒ Object

start defining a new command with the given description



18
19
20
# File 'lib/mothership/base.rb', line 18

def desc(description)
  @command = Command.new(self, description)
end

.filter(name, tag, &callback) ⇒ Object

register a callback that’s evaluated when a command uses the given filter



26
27
28
# File 'lib/mothership/callbacks.rb', line 26

def filter(name, tag, &callback)
  @@commands[name].filters[tag] << [callback, self]
end

.group(*names) ⇒ Object

add command to help group



193
194
195
196
197
198
199
200
201
202
# File 'lib/mothership/help.rb', line 193

def group(*names)
  options =
    if names.last.is_a? Hash
      names.pop
    else
      {}
    end

  Mothership::Help.add_to_group(@command, names, options)
end

.input(name, options = {}, &default) ⇒ Object

define an input for the current command or the global command



23
24
25
26
27
# File 'lib/mothership/base.rb', line 23

def input(name, options = {}, &default)
  raise "no current command" unless @command

  @command.add_input(name, options, &default)
end

.method_added(name) ⇒ Object

register a command



30
31
32
33
34
35
36
37
# File 'lib/mothership/base.rb', line 30

def method_added(name)
  return unless @command

  @command.name = name
  @@commands[name] = @command

  @command = nil
end

.option(name, options = {}, &default) ⇒ Object

define a global option



20
21
22
# File 'lib/mothership.rb', line 20

def option(name, options = {}, &default)
  @@global.add_input(name, options, &default)
end

.start(argv) ⇒ Object

parse argv, by taking the first arg as the command, and the rest as arguments and flags

arguments and flags can be in any order; all flags will be parsed out first, and the bits left over will be treated as arguments



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/mothership.rb', line 29

def start(argv)
  @@inputs = Inputs.new(@@global)

  name, *argv =
    Parser.new(@@global).parse_flags(
      @@inputs.inputs,
      argv)

  app = new

  return app.default_action unless name

  cmdname = name.gsub("-", "_").to_sym

  cmd = @@commands[cmdname]
  return app.unknown_command(cmdname) unless cmd

  app.execute(cmd, argv)

  exit @@exit_status
end

Instance Method Details

#default_actionObject



205
206
207
# File 'lib/mothership/help.rb', line 205

def default_action
  invoke :help
end

#execute(cmd, argv) ⇒ Object



44
45
46
47
48
49
50
51
52
# File 'lib/mothership/base.rb', line 44

def execute(cmd, argv)
  cmd.invoke(Parser.new(cmd).inputs(argv))
rescue Mothership::Error => e
  puts e
  puts ""
  Mothership::Help.command_usage(cmd)

  @@exit_status = 1
end

#exit_status(num) ⇒ Object

set the exit status



53
54
55
# File 'lib/mothership.rb', line 53

def exit_status(num)
  @@exit_status = num
end

#filter(tag, val) ⇒ Object

filter a value through any plugins



46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/mothership/callbacks.rb', line 46

def filter(tag, val)
  if @@filters.key?(@command.name) &&
       @@filters[@command.name].key?(tag)
    @@filters[@command.name][tag].each do |f, ctx|
      val = ctx.instance_exec(val, &f)
    end
  end

  @command.filters[tag].each do |f, c|
    val = c.new.instance_exec(val, &f)
  end

  val
end

#help(input) ⇒ Object



217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/mothership/help.rb', line 217

def help(input)
  if name = input[:command]
    Mothership::Help.command_help(@@commands[name.gsub("-", "_").to_sym])
  elsif Help.has_groups?
    unless input[:all]
      puts "Showing basic command set. Pass --all to list all commands."
      puts ""
    end

    Mothership::Help.print_help_groups(@@global, input[:all])
  else
    Mothership::Help.basic_help(@@commands, @@global)
  end
end

#invoke(name, inputs = {}) ⇒ Object

invoke a command with the given inputs



55
56
57
58
59
60
61
# File 'lib/mothership/base.rb', line 55

def invoke(name, inputs = {})
  if cmd = @@commands[name]
    cmd.invoke(inputs)
  else
    unknown_command(name)
  end
end

#option(name, *args) ⇒ Object

get value of global option



58
59
60
# File 'lib/mothership.rb', line 58

def option(name, *args)
  @@inputs.get(name, self, *args)
end

#option_given?(name) ⇒ Boolean

test if an option was explicitly provided

Returns:

  • (Boolean)


63
64
65
# File 'lib/mothership.rb', line 63

def option_given?(name)
  @@inputs.given? name
end

#unknown_command(name) ⇒ Object



209
210
211
212
# File 'lib/mothership/help.rb', line 209

def unknown_command(name)
  puts "Unknown command '#{name}'. See 'help' for available commands."
  exit_status 1
end

#with_filters(filters) ⇒ Object

temporary dynamically-scoped filters



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/mothership/callbacks.rb', line 62

def with_filters(filters)
  filters.each do |cmd, callbacks|
    callbacks.each do |tag, callback|
      @@filters[cmd][tag] << [callback, self]
    end
  end

  yield
ensure
  filters.each do |cmd, callbacks|
    callbacks.each do |tag, callback|
      @@filters[cmd][tag].pop
      @@filters[cmd].delete(tag) if @@filters[cmd][tag].empty?
    end

    @@filters.delete(cmd) if @@filters[cmd].empty?
  end
end