Class: Climate::Command
- Inherits:
-
Object
- Object
- Climate::Command
- Extended by:
- ParsingMethods
- Defined in:
- lib/climate/command.rb
Overview
A Command is a unit of work, intended to be invoked from the command line. It should be extended to either do something itself by implementing run, or just be there as a conduit for subcommands to do their work.
See ParsingMethods for details on how to specify options and arguments
Direct Known Subclasses
Class Attribute Summary collapse
-
.parent ⇒ Object
Set the parent of this command.
-
.parsing_disabled ⇒ Object
Returns true if parsing is disabled.
Instance Attribute Summary collapse
-
#arguments ⇒ Hash
Arguments that were given on the command line.
-
#argv ⇒ Array
The original list of unparsed argv style arguments that were given to the command.
-
#leftovers ⇒ Array
Unparsed arguments, usually for subcommands.
-
#options ⇒ Hash
Options that were parsed from the command line.
-
#parent ⇒ Command
The parent command, or nil if this is not a subcommand.
-
#stderr ⇒ IO
a possibly redirected stream.
-
#stdin ⇒ IO
a possibly redirected stream.
-
#stdout ⇒ IO
a possibly redirected stream.
Class Method Summary collapse
- .add_subcommand(subcommand) ⇒ Object
- .ancestors(exclude_self = false) ⇒ Object
- .arg(*args) ⇒ Object
-
.class_name ⇒ Object
because we’ve extended Class.name, we expose the original method under another name FIXME: surely there is a saner way of doing this?.
-
.description(string = nil) ⇒ Object
Set the description for this command.
-
.disable_parsing ⇒ Object
Call this during class definition time if you don’t want any of the usual command line parsing to happen.
- .has_subcommands? ⇒ Boolean
-
.name(name = nil) ⇒ Object
Supply a name for this command, or return the existing name.
-
.run(argv, options = {}) ⇒ Object
Create an instance of this command class and run it against the given arguments.
-
.subcommand_of(parent_class) ⇒ Object
Register this class as being a subcommand of another Command class.
- .subcommands ⇒ Object
Instance Method Summary collapse
- #ancestor(ancestor_class, include_self = true) ⇒ Object
-
#initialize(argv, options = {}) ⇒ Command
constructor
Create an instance of this command to be run.
-
#run ⇒ Object
Run the command, must be implemented by all commands that are not parent commands (leaf commands).
Methods included from ParsingMethods
arg, cli_arguments, cli_options, has_arguments?, has_options?, opt, parse, parse_arguments, stop_on, trollop_parser
Constructor Details
#initialize(argv, options = {}) ⇒ Command
Create an instance of this command to be run. You’ll probably want to use run
135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/climate/command.rb', line 135 def initialize(argv, ={}) @argv = argv.clone @parent = [:parent] @stdout = [:stdout] || $stdout @stderr = [:stderr] || $stderr @stdin = [:stdin] || $stdin if ! self.class.parsing_disabled @arguments, @options, @leftovers = self.class.parse(argv) end end |
Class Attribute Details
.parent ⇒ Object
Set the parent of this command
84 85 86 |
# File 'lib/climate/command.rb', line 84 def parent @parent end |
.parsing_disabled ⇒ Object
Returns true if parsing is disabled
81 82 83 |
# File 'lib/climate/command.rb', line 81 def parsing_disabled @parsing_disabled end |
Instance Attribute Details
#arguments ⇒ Hash
Arguments that were given on the command line
159 160 161 |
# File 'lib/climate/command.rb', line 159 def arguments @arguments end |
#argv ⇒ Array
The original list of unparsed argv style arguments that were given to the command
151 152 153 |
# File 'lib/climate/command.rb', line 151 def argv @argv end |
#leftovers ⇒ Array
Unparsed arguments, usually for subcommands
163 164 165 |
# File 'lib/climate/command.rb', line 163 def leftovers @leftovers end |
#options ⇒ Hash
Options that were parsed from the command line
155 156 157 |
# File 'lib/climate/command.rb', line 155 def @options end |
#parent ⇒ Command
The parent command, or nil if this is not a subcommand
167 168 169 |
# File 'lib/climate/command.rb', line 167 def parent @parent end |
#stderr ⇒ IO
a possibly redirected stream
171 172 173 |
# File 'lib/climate/command.rb', line 171 def stderr @stderr end |
#stdin ⇒ IO
a possibly redirected stream
171 172 173 |
# File 'lib/climate/command.rb', line 171 def stdin @stdin end |
#stdout ⇒ IO
a possibly redirected stream
171 172 173 |
# File 'lib/climate/command.rb', line 171 def stdout @stdout end |
Class Method Details
.add_subcommand(subcommand) ⇒ Object
86 87 88 89 90 91 92 93 94 |
# File 'lib/climate/command.rb', line 86 def add_subcommand(subcommand) if cli_arguments.empty? subcommands << subcommand subcommand.parent = self stop_on(subcommands.map(&:name)) else raise DefinitionError, 'can not mix subcommands with arguments' end end |
.ancestors(exclude_self = false) ⇒ Object
39 40 41 42 |
# File 'lib/climate/command.rb', line 39 def ancestors(exclude_self=false) our_list = exclude_self ? [] : [self] parent.nil?? our_list : parent.ancestors + our_list end |
.arg(*args) ⇒ Object
96 97 98 99 100 101 102 |
# File 'lib/climate/command.rb', line 96 def arg(*args) if subcommands.empty? super(*args) else raise DefinitionError, 'can not mix subcommands with arguments' end end |
.class_name ⇒ Object
because we’ve extended Class.name, we expose the original method under another name FIXME: surely there is a saner way of doing this?
53 54 55 |
# File 'lib/climate/command.rb', line 53 def class_name Class.method(:name).unbind.bind(self).call end |
.description(string = nil) ⇒ Object
Set the description for this command
66 67 68 69 70 71 72 |
# File 'lib/climate/command.rb', line 66 def description(string=nil) if string @description = string else @description end end |
.disable_parsing ⇒ Object
Call this during class definition time if you don’t want any of the usual command line parsing to happen
76 77 78 |
# File 'lib/climate/command.rb', line 76 def disable_parsing @parsing_disabled = true end |
.has_subcommands? ⇒ Boolean
104 |
# File 'lib/climate/command.rb', line 104 def has_subcommands? ; not subcommands.empty? ; end |
.name(name = nil) ⇒ Object
Supply a name for this command, or return the existing name
45 46 47 48 |
# File 'lib/climate/command.rb', line 45 def name(name=nil) @name = name if name @name end |
.run(argv, options = {}) ⇒ Object
Create an instance of this command class and run it against the given arguments
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/climate/command.rb', line 19 def run(argv, ={}) begin instance = new(argv, ) rescue Trollop::HelpNeeded raise HelpNeeded.new(self) end if subcommands.empty? begin instance.run rescue Climate::CommandError => e # make it easier on users e.command_class = self if e.command_class.nil? raise end else find_and_run_subcommand(instance, ) end end |
.subcommand_of(parent_class) ⇒ Object
Register this class as being a subcommand of another Climate::Command class
59 60 61 62 |
# File 'lib/climate/command.rb', line 59 def subcommand_of(parent_class) raise DefinitionError, 'can not set subcommand before name' unless @name parent_class.add_subcommand(self) end |
.subcommands ⇒ Object
105 |
# File 'lib/climate/command.rb', line 105 def subcommands ; @subcommands ||= [] ; end |
Instance Method Details
#ancestor(ancestor_class, include_self = true) ⇒ Object
173 174 175 176 177 178 179 180 181 182 |
# File 'lib/climate/command.rb', line 173 def ancestor(ancestor_class, include_self=true) if include_self && self.class == ancestor_class self elsif parent.nil? raise "no ancestor exists: #{ancestor_class}" nil else parent.ancestor(ancestor_class) end end |
#run ⇒ Object
Run the command, must be implemented by all commands that are not parent commands (leaf commands)
186 187 188 |
# File 'lib/climate/command.rb', line 186 def run raise NotImplementedError, "Leaf commands must implement a run method" end |