Class: Climate::Command
- Inherits:
-
Object
- Object
- Climate::Command
- Extended by:
- ParsingMethods
- Defined in:
- lib/climate/command.rb,
lib/climate/command_compat.rb
Overview
require this file to monkey patch Command to have old <= 0.4 Command.name method that was removed to fix github.com/playlouder/climate/issues/6
Defined Under Namespace
Classes: Chain
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
-
.build(argv, options = {}) ⇒ Object
Recursively construct an array of commands.
-
.class_name ⇒ Object
because we’ve extended Class.name, we expose the original method under another name.
-
.command_name ⇒ Object
Return the name of the command.
-
.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.
- .expose_ancestor_method(ancestor_class, method_name) ⇒ Object
- .expose_ancestor_methods(ancestor_class, *method_names) ⇒ Object
- .has_subcommand?(subcommand) ⇒ Boolean
- .has_subcommands? ⇒ Boolean
- .name(name = nil) ⇒ Object
- .run(argv, options = {}) ⇒ Object
-
.set_name(command_name) ⇒ Object
Set the name of this command, use if you don’t want to use the class function to define your command.
-
.subcommand_of(parent_class) ⇒ Object
Register this class as being a subcommand of another Command class.
- .subcommand_of?(parent_class) ⇒ Boolean
- .subcommands ⇒ Object
Instance Method Summary collapse
- #ancestor(ancestor_class, include_self = true) ⇒ Object
- #exit(status) ⇒ Object
- #has_run? ⇒ Boolean
-
#initialize(argv, options = {}) ⇒ Command
constructor
Create an instance of this command to be run.
Methods included from ParsingMethods
arg, cli_arguments, cli_options, conflicting_options, conflicts, dependent_options, depends, has_argument?, has_arguments?, has_multi_argument?, has_options?, has_required_argument?, 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 {Command.run
212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/climate/command.rb', line 212 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
145 146 147 |
# File 'lib/climate/command.rb', line 145 def parent @parent end |
.parsing_disabled ⇒ Object
Returns true if parsing is disabled
142 143 144 |
# File 'lib/climate/command.rb', line 142 def parsing_disabled @parsing_disabled end |
Instance Attribute Details
#arguments ⇒ Hash
Arguments that were given on the command line
236 237 238 |
# File 'lib/climate/command.rb', line 236 def arguments @arguments end |
#argv ⇒ Array
The original list of unparsed argv style arguments that were given to the command
228 229 230 |
# File 'lib/climate/command.rb', line 228 def argv @argv end |
#leftovers ⇒ Array
Unparsed arguments, usually for subcommands
240 241 242 |
# File 'lib/climate/command.rb', line 240 def leftovers @leftovers end |
#options ⇒ Hash
Options that were parsed from the command line
232 233 234 |
# File 'lib/climate/command.rb', line 232 def @options end |
#parent ⇒ Command
The parent command, or nil if this is not a subcommand
244 245 246 |
# File 'lib/climate/command.rb', line 244 def parent @parent end |
#stderr ⇒ IO
a possibly redirected stream
248 249 250 |
# File 'lib/climate/command.rb', line 248 def stderr @stderr end |
#stdin ⇒ IO
a possibly redirected stream
248 249 250 |
# File 'lib/climate/command.rb', line 248 def stdin @stdin end |
#stdout ⇒ IO
a possibly redirected stream
248 249 250 |
# File 'lib/climate/command.rb', line 248 def stdout @stdout end |
Class Method Details
.add_subcommand(subcommand) ⇒ Object
147 148 149 150 151 152 153 154 155 |
# File 'lib/climate/command.rb', line 147 def add_subcommand(subcommand) if cli_arguments.empty? subcommands << subcommand subcommand.parent = self stop_on(subcommands.map(&:command_name)) else raise DefinitionError, 'can not mix subcommands with arguments' end end |
.ancestors(exclude_self = false) ⇒ Object
98 99 100 101 |
# File 'lib/climate/command.rb', line 98 def ancestors(exclude_self=false) our_list = exclude_self ? [] : [self] parent.nil?? our_list : parent.ancestors + our_list end |
.arg(*args) ⇒ Object
161 162 163 164 165 166 167 |
# File 'lib/climate/command.rb', line 161 def arg(*args) if subcommands.empty? super(*args) else raise DefinitionError, 'can not mix subcommands with arguments' end end |
.build(argv, options = {}) ⇒ Object
Recursively construct an array of commands
72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/climate/command.rb', line 72 def build(argv, ={}) begin instance = new(argv, ) rescue Trollop::HelpNeeded raise HelpNeeded.new(self) end if subcommands.empty? [instance] else [instance, *find_and_build_subcommand(instance, )] end end |
.class_name ⇒ Object
because we’ve extended Class.name, we expose the original method under another name. Can be removed once we move away from Command.name method FIXME: surely there is a saner way of doing this?
14 15 16 |
# File 'lib/climate/command_compat.rb', line 14 def self.class_name Class.method(:name).unbind.bind(self).call end |
.command_name ⇒ Object
Return the name of the command
110 111 112 |
# File 'lib/climate/command.rb', line 110 def command_name @name end |
.description(string = nil) ⇒ Object
Set the description for this command
127 128 129 130 131 132 133 |
# File 'lib/climate/command.rb', line 127 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
137 138 139 |
# File 'lib/climate/command.rb', line 137 def disable_parsing @parsing_disabled = true end |
.expose_ancestor_method(ancestor_class, method_name) ⇒ Object
172 173 174 175 176 |
# File 'lib/climate/command.rb', line 172 def expose_ancestor_method(ancestor_class, method_name) define_method(method_name) do |*args| ancestor(ancestor_class).send(method_name, *args) end end |
.expose_ancestor_methods(ancestor_class, *method_names) ⇒ Object
178 179 180 181 182 |
# File 'lib/climate/command.rb', line 178 def expose_ancestor_methods(ancestor_class, *method_names) method_names.each do |method_name| expose_ancestor_method(ancestor_class, method_name) end end |
.has_subcommand?(subcommand) ⇒ Boolean
157 158 159 |
# File 'lib/climate/command.rb', line 157 def has_subcommand?(subcommand) subcommands.include?(subcommand) end |
.has_subcommands? ⇒ Boolean
169 |
# File 'lib/climate/command.rb', line 169 def has_subcommands? ; not subcommands.empty? ; end |
.name(name = nil) ⇒ Object
5 6 7 8 |
# File 'lib/climate/command_compat.rb', line 5 def self.name(name=nil) set_name(name) if name command_name end |
.run(argv, options = {}) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/climate/command.rb', line 86 def run(argv, ={}) command_instance_list = build(argv, ) final_command = command_instance_list.last if ! final_command.has_run? raise NotImplementedError, "leaf command #{final_command} must implement #run" end runnable_commands = command_instance_list.select {|command| command.has_run? } Chain.new(runnable_commands).run end |
.set_name(command_name) ⇒ Object
Set the name of this command, use if you don’t want to use the class function to define your command
105 106 107 |
# File 'lib/climate/command.rb', line 105 def set_name(command_name) @name = command_name end |
.subcommand_of(parent_class) ⇒ Object
Register this class as being a subcommand of another Climate::Command class
116 117 118 119 |
# File 'lib/climate/command.rb', line 116 def subcommand_of(parent_class) raise DefinitionError, 'can not set subcommand before name' unless command_name parent_class.add_subcommand(self) end |
.subcommand_of?(parent_class) ⇒ Boolean
121 122 123 |
# File 'lib/climate/command.rb', line 121 def subcommand_of?(parent_class) parent_class.has_subcommand?(self) end |
.subcommands ⇒ Object
170 |
# File 'lib/climate/command.rb', line 170 def subcommands ; @subcommands ||= [] ; end |
Instance Method Details
#ancestor(ancestor_class, include_self = true) ⇒ Object
250 251 252 253 254 255 256 257 258 259 |
# File 'lib/climate/command.rb', line 250 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 |
#exit(status) ⇒ Object
265 266 267 |
# File 'lib/climate/command.rb', line 265 def exit(status) raise Climate::ExitException.new(nil, status) end |
#has_run? ⇒ Boolean
261 262 263 |
# File 'lib/climate/command.rb', line 261 def has_run? self.methods.include? :run end |