Permalink
Browse files

Document everything but Command.

  • Loading branch information...
1 parent 9d8c0b6 commit 3783e0b37db09cf08d2ae46343c11fc9b2a82965 @alloy alloy committed Oct 26, 2012
Showing with 193 additions and 8 deletions.
  1. +2 −0 .gitignore
  2. +1 −0 Gemfile
  3. +2 −0 Gemfile.lock
  4. +11 −0 Rakefile
  5. +177 −8 lib/claide.rb
View
@@ -1,2 +1,4 @@
.*.sw?
.rbenv-version
+.yardoc
+doc
View
@@ -1,6 +1,7 @@
source :rubygems
group :development do
+ gem 'yard'
gem 'activesupport'
end
View
@@ -12,6 +12,7 @@ GEM
mocha-on-bacon (0.2.1)
mocha (>= 0.9.8)
multi_json (1.3.6)
+ yard (0.8.3)
PLATFORMS
ruby
@@ -20,3 +21,4 @@ DEPENDENCIES
activesupport
bacon
mocha-on-bacon
+ yard
View
@@ -0,0 +1,11 @@
+desc 'Generate yardoc'
+task :doc do
+ sh "yardoc -m markdown lib"
+end
+
+desc 'Run specs'
+task :spec do
+ sh "bacon spec/claide_spec.rb"
+end
+
+task :default => :spec
View
@@ -1,11 +1,32 @@
module CLAide
VERSION = '0.0.1'
+ # This class is responsible for parsing the parameters specified by the user,
+ # accessing individual parameters, and keep state by removing handled
+ # parameters.
+ #
class ARGV
+
+ # @param [Array<String>] argv
+ #
+ # A list of parameters. Each entry is ensured to be a string by calling
+ # `#to_s` on it.
+ #
def initialize(argv)
@entries = self.class.parse(argv)
end
+ # @return [Array<String>]
+ #
+ # A list of the remaining unhandled parameters, in the same format a user
+ # specifies it in.
+ #
+ # @example
+ #
+ # argv = CLAide::ARGV.new(['tea', '--no-milk', '--sweetner=honey'])
+ # argv.shift_argument # => 'tea'
+ # argv.remainder # => ['--no-milk', '--sweetner=honey']
+ #
def remainder
@entries.map do |type, (key, value)|
case type
@@ -19,6 +40,16 @@ def remainder
end
end
+ # @return [Hash]
+ #
+ # A hash that consists of the remaining flags and options and their
+ # values.
+ #
+ # @example
+ #
+ # argv = CLAide::ARGV.new(['tea', '--no-milk', '--sweetner=honey'])
+ # argv.options # => { 'milk' => false, 'sweetner' => 'honey' }
+ #
def options
options = {}
@entries.each do |type, (key, value)|
@@ -27,10 +58,35 @@ def options
options
end
+ # @return [Array<String>]
+ #
+ # A list of the remaining arguments.
+ #
+ # @example
+ #
+ # argv = CLAide::ARGV.new(['tea', 'white', '--no-milk', 'biscuit'])
+ # argv.shift_argument # => 'tea'
+ # argv.arguments # => ['white', 'biscuit']
+ #
def arguments
@entries.map { |type, value| value if type == :arg }.compact
end
+ # @return [Array<String>]
+ #
+ # A list of the remaining arguments.
+ #
+ # @note
+ #
+ # This version also removes the arguments from the remaining parameters.
+ #
+ # @example
+ #
+ # argv = CLAide::ARGV.new(['tea', 'white', '--no-milk', 'biscuit'])
+ # argv.arguments # => ['tea', 'white', 'biscuit']
+ # argv.arguments! # => ['tea', 'white', 'biscuit']
+ # argv.arguments # => []
+ #
def arguments!
arguments = []
while arg = shift_argument
@@ -39,21 +95,87 @@ def arguments!
arguments
end
+ # @return [String]
+ #
+ # The first argument in the remaining parameters.
+ #
+ # @note
+ #
+ # This will remove the argument from the remaining parameters.
+ #
+ # @example
+ #
+ # argv = CLAide::ARGV.new(['tea', 'white'])
+ # argv.shift_argument # => 'tea'
+ # argv.arguments # => ['white']
+ #
+ def shift_argument
+ if entry = @entries.find { |type, _| type == :arg }
+ @entries.delete(entry)
+ entry.last
+ end
+ end
+
+ # @return [Boolean, nil]
+ #
+ # Returns `true` if the flag by the specified `name` is among the
+ # remaining parameters and is not negated.
+ #
+ # @param [String] name
+ #
+ # The name of the flag to look for among the remaining parameters.
+ #
+ # @param [Boolean] default
+ #
+ # The value that is returned in case the flag is not among the remaining
+ # parameters.
+ #
+ # @note
+ #
+ # This will remove the flag from the remaining parameters.
+ #
+ # @example
+ #
+ # argv = CLAide::ARGV.new(['tea', '--no-milk', '--sweetner=honey'])
+ # argv.flag?('milk') # => false
+ # argv.flag?('milk') # => nil
+ # argv.flag?('milk', true) # => true
+ # argv.remainder # => ['tea', '--sweetner=honey']
+ #
def flag?(name, default = nil)
delete_entry(:flag, name, default)
end
+ # @return [String, nil]
+ #
+ # Returns the value of the option by the specified `name` is among the
+ # remaining parameters.
+ #
+ # @param [String] name
+ #
+ # The name of the option to look for among the remaining parameters.
+ #
+ # @param [String] default
+ #
+ # The value that is returned in case the option is not among the
+ # remaining parameters.
+ #
+ # @note
+ #
+ # This will remove the option from the remaining parameters.
+ #
+ # @example
+ #
+ # argv = CLAide::ARGV.new(['tea', '--no-milk', '--sweetner=honey'])
+ # argv.option('sweetner') # => 'honey'
+ # argv.option('sweetner') # => nil
+ # argv.option('sweetner', 'sugar') # => 'sugar'
+ # argv.remainder # => ['tea', '--no-milk']
+ #
def option(name, default = nil)
delete_entry(:option, name, default)
end
- def shift_argument
- if entry = @entries.find { |type, _| type == :arg }
- @entries.delete(entry)
- entry.last
- end
- end
-
private
def delete_entry(requested_type, requested_key, default)
@@ -103,30 +225,77 @@ def self.is_arg?(x)
end
end
+ # Including this module into an exception class will ensure that when raised,
+ # while running {Command.run}, only the message of the exception will be
+ # shown to the user. Unless disabled with the `--verbose` flag.
+ #
+ # In addition, the message will be colored red, if {Command.colorize_output}
+ # is set to `true`.
+ #
module InformativeError
attr_writer :exit_status
+
+ # @return [Numeric]
+ #
+ # The exist status code that should be used to terminate the program with.
+ #
+ # Defaults to `1`.
+ #
def exit_status
@exit_status ||= 1
end
end
+ # The exception class that is raised to indicate a help banner should be
+ # shown while running {Command.run}.
+ #
class Help < StandardError
include InformativeError
- attr_reader :command, :error_message
+ # @return [Command]
+ #
+ # The command instance for which a help banner should be shown.
+ attr_reader :command
+ # @return [String]
+ #
+ # The optional error message that will be shown before the help banner.
+ #
+ attr_reader :error_message
+
+ # @param [Command] command
+ #
+ # An instance of a command class for which a help banner should be shown.
+ #
+ # @param [String] error_message
+ #
+ # An optional error message that will be shown before the help banner.
+ # If specified, the exit status, used to terminate the program with, will
+ # be set to `1`, otherwise a {Help} exception is treated as not being a
+ # real error and exits with `0`.
+ #
def initialize(command, error_message = nil)
@command, @error_message = command, error_message
@exit_status = @error_message.nil? ? 0 : 1
end
+ # @return [String]
+ #
+ # The optional error message, colored in red if {Command.colorize_output}
+ # is set to `true`.
+ #
def formatted_error_message
if @error_message
message = "[!] #{@error_message}"
@command.colorize_output? ? message.red : message
end
end
+ # @return [String]
+ #
+ # The optional error message, combined with the help banner of the
+ # command.
+ #
def message
[formatted_error_message, @command.formatted_banner].compact.join("\n\n")
end

0 comments on commit 3783e0b

Please sign in to comment.