diff options
Diffstat (limited to 'railties/lib/vendor/thor/lib/thor.rb')
m--------- | railties/lib/vendor/thor | 0 | ||||
-rw-r--r-- | railties/lib/vendor/thor/lib/thor.rb | 234 |
2 files changed, 234 insertions, 0 deletions
diff --git a/railties/lib/vendor/thor b/railties/lib/vendor/thor deleted file mode 160000 -Subproject fccc2fddfb3e696d4715bfddc1c25211fc7480d diff --git a/railties/lib/vendor/thor/lib/thor.rb b/railties/lib/vendor/thor/lib/thor.rb new file mode 100644 index 0000000000..72d5574983 --- /dev/null +++ b/railties/lib/vendor/thor/lib/thor.rb @@ -0,0 +1,234 @@ +$:.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, :boolean or :default. + # Default accepts arguments as booleans (--switch) or as strings (--switch=VALUE). + # :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 ||= Task.dynamic(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])}" + shell.say + class_options_help(shell, "Class") + shell.say task.description + else + list = (options[:short] ? tasks : all_tasks).map do |_, task| + [ banner(task, options[:namespace]), task.short_description || '' ] + end + + if options[:short] + shell.print_table(list, :emphasize_last => true) + else + shell.say "Tasks:" + shell.print_table(list, :ident => 2, :emphasize_last => true) + shell.say + + class_options_help(shell, "Class") + end + end + end + + protected + + # The banner for this class. You can customize it if you are invoking the + # thor class by another means which is not the Thor::Runner. It receives + # the task that is going to be invoked and if the namespace should be + # displayed. + # + def banner(task, namespace=true) #:nodoc: + task.formatted_usage(self, namespace) + end + + def baseclass #:nodoc: + Thor + end + + def valid_task?(meth) #:nodoc: + @usage && @desc + end + + def create_task(meth) #:nodoc: + tasks[meth.to_s] = Thor::Task.new(meth, @desc, @usage, method_options) + @usage, @desc, @method_options = nil + 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 |