Class: Mothership
- Inherits:
-
Object
- Object
- Mothership
- Defined in:
- lib/mothership.rb,
lib/mothership/base.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,
lib/mothership/help/commands.rb
Defined Under Namespace
Modules: Help Classes: Command, Error, ExtraArguments, Inputs, MissingArgument, Parser, TypeMismatch
Constant Summary collapse
- VERSION =
"0.5.1"
- @@global =
- Mothership::Command
-
global options
Command.new(self, "(global options)")
- @@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] = [] } }
Instance Attribute Summary collapse
-
#input ⇒ Object
Returns the value of attribute input.
Class Method Summary collapse
-
.add_input(cmd, name, options = {}, &interact) ⇒ Object
add an input/flag to a command.
-
.after(name, &callback) ⇒ Object
register a callback that’s evaluated after a command is run.
- .alias_command(new, orig = nil) ⇒ Object
-
.around(name, &callback) ⇒ Object
register a callback that’s evaluated around a command, controlling its evaluation (i.e. inputs).
-
.before(name, &callback) ⇒ Object
register a callback that’s evaluated before a command is run.
-
.change_argument(name, arg, to) ⇒ Object
change an argument’s status, i.e.
-
.commands ⇒ Object
all of the defined commands.
-
.desc(description) ⇒ Object
start defining a new command with the given description.
-
.filter(name, tag, &callback) ⇒ Object
register a callback that’s evaluated when a command uses the given filter.
- .global_option(name) ⇒ Object
-
.group(*names) ⇒ Object
add command to help group.
-
.input(name, options = {}, &interact) ⇒ Object
define an input for the current command or the global command.
-
.interactions(mod) ⇒ Object
specify a module that defines interactions for each input.
-
.method_added(name) ⇒ Object
register a command.
-
.option(name, options = {}, &interact) ⇒ Object
define a global option.
-
.start(argv) ⇒ Object
parse argv, by taking the first arg as the command, and the rest as arguments and flags.
Instance Method Summary collapse
- #default_action ⇒ Object
- #execute(cmd, argv, global = {}) ⇒ Object
-
#exit_status(num) ⇒ Object
set the exit status.
-
#filter(tag, val) ⇒ Object
filter a value through any plugins.
- #help ⇒ Object
-
#initialize(command = nil, input = nil) ⇒ Mothership
constructor
Initialize with the command being executed.
-
#interact(input = nil, *args) ⇒ Object
explicitly perform the interaction of an input.
-
#invoke(name, inputs = {}, given = {}, global = @input ? @input.global : {}) ⇒ Object
invoke a command with inputs.
-
#run(name) ⇒ Object
wrap this with your error handling/etc.
- #unknown_command(name) ⇒ Object
-
#with_filters(filters) ⇒ Object
temporary dynamically-scoped filters.
Constructor Details
#initialize(command = nil, input = nil) ⇒ Mothership
Initialize with the command being executed.
11 12 13 14 |
# File 'lib/mothership/base.rb', line 11 def initialize(command = nil, input = nil) @command = command @input = input end |
Instance Attribute Details
#input ⇒ Object
Returns the value of attribute input.
8 9 10 |
# File 'lib/mothership/base.rb', line 8 def input @input end |
Class Method Details
.add_input(cmd, name, options = {}, &interact) ⇒ Object
add an input/flag to a command
45 46 47 |
# File 'lib/mothership/callbacks.rb', line 45 def add_input(cmd, name, = {}, &interact) @@commands[cmd].add_input(name, , &interact) end |
.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(new, orig = nil) ⇒ Object
49 50 51 |
# File 'lib/mothership/base.rb', line 49 def alias_command(new, orig = nil) @@commands[new] = orig ? @@commands[orig] : @command 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 |
.commands ⇒ Object
all of the defined commands
18 19 20 |
# File 'lib/mothership/base.rb', line 18 def commands @@commands end |
.desc(description) ⇒ Object
start defining a new command with the given description
23 24 25 |
# File 'lib/mothership/base.rb', line 23 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 |
.global_option(name) ⇒ Object
55 56 57 |
# File 'lib/mothership.rb', line 55 def global_option(name) @@global.inputs[name] end |
.group(*names) ⇒ Object
add command to help group
6 7 8 9 10 11 12 13 14 15 |
# File 'lib/mothership/help/commands.rb', line 6 def group(*names) = if names.last.is_a? Hash names.pop else {} end Mothership::Help.add_to_group(@command, names, ) end |
.input(name, options = {}, &interact) ⇒ Object
define an input for the current command or the global command
28 29 30 31 32 |
# File 'lib/mothership/base.rb', line 28 def input(name, = {}, &interact) raise "no current command" unless @command @command.add_input(name, , &interact) end |
.interactions(mod) ⇒ Object
specify a module that defines interactions for each input
35 36 37 |
# File 'lib/mothership/base.rb', line 35 def interactions(mod) @command.interactions = mod end |
.method_added(name) ⇒ Object
register a command
40 41 42 43 44 45 46 47 |
# File 'lib/mothership/base.rb', line 40 def method_added(name) return unless @command @command.name = name @@commands[name] = @command @command = nil end |
.option(name, options = {}, &interact) ⇒ Object
define a global option
17 18 19 |
# File 'lib/mothership.rb', line 17 def option(name, = {}, &interact) @@global.add_input(name, , &interact) 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
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/mothership.rb', line 26 def start(argv) global_parser = Parser.new(@@global) name, *argv = global_parser.parse_flags(argv, @@commands) global = new(@@global) global.input = Inputs.new(@@global, global, {}, global_parser.given) return global.default_action unless name cmdname = name.gsub("-", "_").to_sym cmd = @@commands[cmdname] return global.unknown_command(cmdname) unless cmd ctx = cmd.context.new # make global input available for those wrapping execute ctx.input = global.input ctx.execute(cmd, argv, global.input) code = @@exit_status # reset exit status @@exit_status = 0 exit code end |
Instance Method Details
#default_action ⇒ Object
18 19 20 |
# File 'lib/mothership/help/commands.rb', line 18 def default_action invoke :help end |
#execute(cmd, argv, global = {}) ⇒ Object
54 55 56 57 58 59 60 61 62 |
# File 'lib/mothership/base.rb', line 54 def execute(cmd, argv, global = {}) cmd.invoke({}, Parser.new(cmd).parse_argv(argv), global) rescue Mothership::Error => e $stderr.puts e $stderr.puts "" Mothership::Help.command_usage(cmd, $stderr) exit_status 1 end |
#exit_status(num) ⇒ Object
set the exit status
61 62 63 |
# File 'lib/mothership.rb', line 61 def exit_status(num) @@exit_status = num end |
#filter(tag, val) ⇒ Object
filter a value through any plugins
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/mothership/callbacks.rb', line 51 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 ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/mothership/help/commands.rb', line 31 def help if name = input[:command] if cmd = @@commands[name.gsub("-", "_").to_sym] Mothership::Help.command_help(cmd) else unknown_command(name) end elsif Help.has_groups? unless input[:all] puts "Showing basic command set. Run with 'help --all' to list all commands." puts "" end Mothership::Help.print_help_groups(@@global, input[:all]) else Mothership::Help.basic_help(@@commands, @@global) end end |
#interact(input = nil, *args) ⇒ Object
explicitly perform the interaction of an input
if no input specified, assume current input and reuse the arguments
example:
input(:foo, :default => proc { |foos|
foos.find { |f| f.name == "XYZ" } ||
interact
}) { |foos|
ask("Foo?", :choices => foos, :display => proc(&:name))
}
90 91 92 93 94 95 96 97 98 |
# File 'lib/mothership/base.rb', line 90 def interact(input = nil, *args) unless input input, args = @input.current_input end raise "no active input" unless input @input.interact(input, self, *args) end |
#invoke(name, inputs = {}, given = {}, global = @input ? @input.global : {}) ⇒ Object
invoke a command with inputs
70 71 72 73 74 75 76 77 |
# File 'lib/mothership/base.rb', line 70 def invoke( name, inputs = {}, given = {}, global = @input ? @input.global : {}) if cmd = @@commands[name] cmd.invoke(inputs, given, global) else unknown_command(name) end end |
#run(name) ⇒ Object
wrap this with your error handling/etc.
65 66 67 |
# File 'lib/mothership/base.rb', line 65 def run(name) send(name) end |
#unknown_command(name) ⇒ Object
22 23 24 25 26 |
# File 'lib/mothership/help/commands.rb', line 22 def unknown_command(name) $stderr.print "Unknown command '#{name.to_s.gsub("_", "-")}'. " $stderr.puts "See 'help' for available commands." exit_status 1 end |
#with_filters(filters) ⇒ Object
temporary dynamically-scoped filters
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/mothership/callbacks.rb', line 67 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 |