aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails/vendor/thor-0.11.6/lib/thor.rb
diff options
context:
space:
mode:
Diffstat (limited to 'railties/lib/rails/vendor/thor-0.11.6/lib/thor.rb')
-rw-r--r--railties/lib/rails/vendor/thor-0.11.6/lib/thor.rb243
1 files changed, 243 insertions, 0 deletions
diff --git a/railties/lib/rails/vendor/thor-0.11.6/lib/thor.rb b/railties/lib/rails/vendor/thor-0.11.6/lib/thor.rb
new file mode 100644
index 0000000000..3b45c4e9b7
--- /dev/null
+++ b/railties/lib/rails/vendor/thor-0.11.6/lib/thor.rb
@@ -0,0 +1,243 @@
+$:.unshift File.expand_path(File.dirname(__FILE__))
+require 'thor/base'
+require 'thor/group'
+require 'thor/actions'
+
+class Thor
+ class << self
+ # Sets the default task when thor is executed without an explicit task to be called.
+ #
+ # ==== Parameters
+ # meth<Symbol>:: name of the defaut task
+ #
+ def default_task(meth=nil)
+ case meth
+ when :none
+ @default_task = 'help'
+ when nil
+ @default_task ||= from_superclass(:default_task, 'help')
+ else
+ @default_task = meth.to_s
+ end
+ end
+
+ # Defines the usage and the description of the next task.
+ #
+ # ==== Parameters
+ # usage<String>
+ # description<String>
+ #
+ def desc(usage, description, options={})
+ if options[:for]
+ task = find_and_refresh_task(options[:for])
+ task.usage = usage if usage
+ task.description = description if description
+ else
+ @usage, @desc = usage, description
+ end
+ end
+
+ # Maps an input to a task. If you define:
+ #
+ # map "-T" => "list"
+ #
+ # Running:
+ #
+ # thor -T
+ #
+ # Will invoke the list task.
+ #
+ # ==== Parameters
+ # Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given task.
+ #
+ def map(mappings=nil)
+ @map ||= from_superclass(:map, {})
+
+ if mappings
+ mappings.each do |key, value|
+ if key.respond_to?(:each)
+ key.each {|subkey| @map[subkey] = value}
+ else
+ @map[key] = value
+ end
+ end
+ end
+
+ @map
+ end
+
+ # Declares the options for the next task to be declared.
+ #
+ # ==== Parameters
+ # Hash[Symbol => Object]:: The hash key is the name of the option and the value
+ # is the type of the option. Can be :string, :array, :hash, :boolean, :numeric
+ # or :required (string). If you give a value, the type of the value is used.
+ #
+ def method_options(options=nil)
+ @method_options ||= {}
+ build_options(options, @method_options) if options
+ @method_options
+ end
+
+ # Adds an option to the set of class options. If :for is given as option,
+ # it allows you to change the options from a previous defined task.
+ #
+ # def previous_task
+ # # magic
+ # end
+ #
+ # method_options :foo => :bar, :for => :previous_task
+ #
+ # def next_task
+ # # magic
+ # end
+ #
+ # ==== Parameters
+ # name<Symbol>:: The name of the argument.
+ # options<Hash>:: Described below.
+ #
+ # ==== Options
+ # :desc - Description for the argument.
+ # :required - If the argument is required or not.
+ # :default - Default value for this argument. It cannot be required and have default values.
+ # :aliases - Aliases for this option.
+ # :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
+ # :group - The group for this options. Use by class options to output options in different levels.
+ # :banner - String to show on usage notes.
+ #
+ def method_option(name, options={})
+ scope = if options[:for]
+ find_and_refresh_task(options[:for]).options
+ else
+ method_options
+ end
+
+ build_option(name, options, scope)
+ end
+
+ # Parses the task and options from the given args, instantiate the class
+ # and invoke the task. This method is used when the arguments must be parsed
+ # from an array. If you are inside Ruby and want to use a Thor class, you
+ # can simply initialize it:
+ #
+ # script = MyScript.new(args, options, config)
+ # script.invoke(:task, first_arg, second_arg, third_arg)
+ #
+ def start(given_args=ARGV, config={})
+ super do
+ meth = normalize_task_name(given_args.shift)
+ task = all_tasks[meth]
+
+ if task
+ args, opts = Thor::Options.split(given_args)
+ config.merge!(:task_options => task.options)
+ else
+ args, opts = given_args, {}
+ end
+
+ task ||= Thor::Task::Dynamic.new(meth)
+ trailing = args[Range.new(arguments.size, -1)]
+ new(args, opts, config).invoke(task, trailing || [])
+ end
+ end
+
+ # Prints help information. If a task name is given, it shows information
+ # only about the specific task.
+ #
+ # ==== Parameters
+ # meth<String>:: An optional task name to print usage information about.
+ #
+ # ==== Options
+ # namespace:: When true, shows the namespace in the output before the usage.
+ # skip_inherited:: When true, does not show tasks from superclass.
+ #
+ def help(shell, meth=nil, options={})
+ meth, options = nil, meth if meth.is_a?(Hash)
+
+ if meth
+ task = all_tasks[meth]
+ raise UndefinedTaskError, "task '#{meth}' could not be found in namespace '#{self.namespace}'" unless task
+
+ shell.say "Usage:"
+ shell.say " #{banner(task, options[:namespace], false)}"
+ shell.say
+ class_options_help(shell, "Class", :Method => task.options.map { |_, o| o })
+ shell.say task.description
+ else
+ list = (options[:short] ? tasks : all_tasks).map do |_, task|
+ item = [ banner(task, options[:namespace]) ]
+ item << "# #{task.short_description}" if task.short_description
+ item << " "
+ end
+
+ options[:ident] ||= 2
+ if options[:short]
+ shell.print_list(list, :ident => options[:ident])
+ else
+ shell.say "Tasks:"
+ shell.print_list(list, :ident => options[:ident])
+ end
+
+ Thor::Util.thor_classes_in(self).each do |subclass|
+ namespace = options[:namespace] == true || subclass.namespace.gsub(/^#{self.namespace}:/, '')
+ subclass.help(shell, options.merge(:short => true, :namespace => namespace))
+ end
+
+ class_options_help(shell, "Class") unless options[:short]
+ end
+ end
+
+ protected
+
+ # The banner for this class. You can customize it if you are invoking the
+ # thor class by another ways which is not the Thor::Runner. It receives
+ # the task that is going to be invoked and a boolean which indicates if
+ # the namespace should be displayed as arguments.
+ #
+ def banner(task, namespace=true, show_options=true)
+ task.formatted_usage(self, namespace, show_options)
+ end
+
+ def baseclass #:nodoc:
+ Thor
+ end
+
+ def create_task(meth) #:nodoc:
+ if @usage && @desc
+ tasks[meth.to_s] = Thor::Task.new(meth, @desc, @usage, method_options)
+ @usage, @desc, @method_options = nil
+ true
+ elsif self.all_tasks[meth.to_s] || meth.to_sym == :method_missing
+ true
+ else
+ puts "[WARNING] Attempted to create task #{meth.inspect} without usage or description. " <<
+ "Call desc if you want this method to be available as task or declare it inside a " <<
+ "no_tasks{} block. Invoked from #{caller[1].inspect}."
+ false
+ end
+ end
+
+ def initialize_added #:nodoc:
+ class_options.merge!(method_options)
+ @method_options = nil
+ end
+
+ # Receives a task name (can be nil), and try to get a map from it.
+ # If a map can't be found use the sent name or the default task.
+ #
+ def normalize_task_name(meth) #:nodoc:
+ mapping = map[meth.to_s]
+ meth = mapping || meth || default_task
+ meth.to_s.gsub('-','_') # treat foo-bar > foo_bar
+ end
+ end
+
+ include Thor::Base
+
+ map HELP_MAPPINGS => :help
+
+ desc "help [TASK]", "Describe available tasks or one specific task"
+ def help(task=nil)
+ self.class.help(shell, task, :namespace => task && task.include?(?:))
+ end
+end