lib/clamp/command.rb in clamp-0.0.9 vs lib/clamp/command.rb in clamp-0.1.0
- old
+ new
@@ -1,55 +1,97 @@
-require 'clamp/command/declaration'
require 'clamp/errors'
require 'clamp/help'
+require 'clamp/option/declaration'
require 'clamp/option/parsing'
+require 'clamp/parameter/declaration'
require 'clamp/parameter/parsing'
+require 'clamp/subcommand/declaration'
require 'clamp/subcommand/execution'
module Clamp
+ # {Command} models a shell command. Each command invocation is a new object.
+ # Command options and parameters are represented as attributes
+ # (see {Command::Declaration}).
+ #
+ # The main entry-point is {#run}, which uses {#parse} to populate attributes based
+ # on an array of command-line arguments, then calls {#execute} (which you provide)
+ # to make it go.
+ #
class Command
- def initialize(name, context = {})
- @name = name
+ # Create a command execution.
+ #
+ # @param [String] invocation_path the path used to invoke the command
+ # @param [Hash] context additional data the command may need
+ #
+ def initialize(invocation_path, context = {})
+ @invocation_path = invocation_path
@context = context
end
- attr_reader :name
- attr_reader :arguments
+ # @return [String] the path used to invoke this command
+ #
+ attr_reader :invocation_path
+
+ # @return [Array<String>] unconsumed command-line arguments
+ #
+ def arguments
+ @arguments
+ end
- attr_accessor :context
- attr_accessor :parent_command
-
+ # Parse command-line arguments.
+ #
+ # @param [Array<String>] arguments command-line arguments
+ # @return [Array<String>] unconsumed arguments
+ #
def parse(arguments)
@arguments = arguments.dup
parse_options
parse_parameters
+ @arguments
end
- # default implementation
+ # Run the command, with the specified arguments.
+ #
+ # This calls {#parse} to process the command-line arguments,
+ # then delegates to {#execute}.
+ #
+ # @param [Array<String>] arguments command-line arguments
+ #
+ def run(arguments)
+ parse(arguments)
+ execute
+ end
+
+ # Execute the command (assuming that all options/parameters have been set).
+ #
+ # This method is designed to be overridden in sub-classes.
+ #
def execute
if self.class.has_subcommands?
execute_subcommand
else
raise "you need to define #execute"
end
end
- def run(arguments)
- parse(arguments)
- execute
- end
-
+ # @return [String] usage documentation for this command
+ #
def help
- self.class.help(name)
+ self.class.help(invocation_path)
end
- include Option::Parsing
- include Parameter::Parsing
- include Subcommand::Execution
+ include Clamp::Option::Parsing
+ include Clamp::Parameter::Parsing
+ include Clamp::Subcommand::Execution
+
+ protected
+ attr_accessor :context
+ attr_accessor :parent_command
+
private
def signal_usage_error(message)
e = UsageError.new(message, self)
e.set_backtrace(caller)
@@ -60,19 +102,27 @@
raise Clamp::HelpWanted.new(self)
end
class << self
- include Command::Declaration
+ include Clamp::Option::Declaration
+ include Clamp::Parameter::Declaration
+ include Clamp::Subcommand::Declaration
include Help
- def run(name = $0, args = ARGV, context = {})
+ # Create an instance of this command class, and run it.
+ #
+ # @param [String] invocation_path the path used to invoke the command
+ # @param [Array<String>] arguments command-line arguments
+ # @param [Hash] context additional data the command may need
+ #
+ def run(invocation_path = $0, arguments = ARGV, context = {})
begin
- new(name, context).run(args)
+ new(invocation_path, context).run(arguments)
rescue Clamp::UsageError => e
$stderr.puts "ERROR: #{e.message}"
$stderr.puts ""
- $stderr.puts "See: '#{name} --help'"
+ $stderr.puts "See: '#{invocation_path} --help'"
exit(1)
rescue Clamp::HelpWanted => e
puts e.command.help
end
end