engineyard 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/engineyard/cli.rb +11 -2
 - data/lib/engineyard/model/environment.rb +36 -3
 - data/lib/engineyard/model/instance.rb +1 -1
 - data/lib/engineyard/thor.rb +50 -68
 - data/lib/engineyard/version.rb +1 -1
 - data/spec/ey/deploy_spec.rb +66 -0
 - metadata +23 -36
 - data/lib/engineyard/vendor/thor.rb +0 -270
 - data/lib/engineyard/vendor/thor/actions.rb +0 -297
 - data/lib/engineyard/vendor/thor/actions/create_file.rb +0 -105
 - data/lib/engineyard/vendor/thor/actions/directory.rb +0 -93
 - data/lib/engineyard/vendor/thor/actions/empty_directory.rb +0 -134
 - data/lib/engineyard/vendor/thor/actions/file_manipulation.rb +0 -229
 - data/lib/engineyard/vendor/thor/actions/inject_into_file.rb +0 -104
 - data/lib/engineyard/vendor/thor/base.rb +0 -540
 - data/lib/engineyard/vendor/thor/core_ext/file_binary_read.rb +0 -9
 - data/lib/engineyard/vendor/thor/core_ext/hash_with_indifferent_access.rb +0 -75
 - data/lib/engineyard/vendor/thor/core_ext/ordered_hash.rb +0 -100
 - data/lib/engineyard/vendor/thor/error.rb +0 -30
 - data/lib/engineyard/vendor/thor/group.rb +0 -271
 - data/lib/engineyard/vendor/thor/invocation.rb +0 -180
 - data/lib/engineyard/vendor/thor/parser.rb +0 -4
 - data/lib/engineyard/vendor/thor/parser/argument.rb +0 -67
 - data/lib/engineyard/vendor/thor/parser/arguments.rb +0 -161
 - data/lib/engineyard/vendor/thor/parser/option.rb +0 -128
 - data/lib/engineyard/vendor/thor/parser/options.rb +0 -164
 - data/lib/engineyard/vendor/thor/rake_compat.rb +0 -66
 - data/lib/engineyard/vendor/thor/runner.rb +0 -314
 - data/lib/engineyard/vendor/thor/shell.rb +0 -83
 - data/lib/engineyard/vendor/thor/shell/basic.rb +0 -268
 - data/lib/engineyard/vendor/thor/shell/color.rb +0 -108
 - data/lib/engineyard/vendor/thor/task.rb +0 -102
 - data/lib/engineyard/vendor/thor/util.rb +0 -229
 - data/lib/engineyard/vendor/thor/version.rb +0 -3
 
| 
         @@ -1,164 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            class Thor
         
     | 
| 
       2 
     | 
    
         
            -
              # This is a modified version of Daniel Berger's Getopt::Long class, licensed
         
     | 
| 
       3 
     | 
    
         
            -
              # under Ruby's license.
         
     | 
| 
       4 
     | 
    
         
            -
              #
         
     | 
| 
       5 
     | 
    
         
            -
              class Options < Arguments #:nodoc:
         
     | 
| 
       6 
     | 
    
         
            -
                LONG_RE     = /^(--\w+(?:-\w+)*)$/
         
     | 
| 
       7 
     | 
    
         
            -
                SHORT_RE    = /^(-[a-z])$/i
         
     | 
| 
       8 
     | 
    
         
            -
                EQ_RE       = /^(--\w+(?:-\w+)*|-[a-z])=(.*)$/i
         
     | 
| 
       9 
     | 
    
         
            -
                SHORT_SQ_RE = /^-([a-z]{2,})$/i # Allow either -x -v or -xv style for single char args
         
     | 
| 
       10 
     | 
    
         
            -
                SHORT_NUM   = /^(-[a-z])#{NUMERIC}$/i
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                # Receives a hash and makes it switches.
         
     | 
| 
       13 
     | 
    
         
            -
                def self.to_switches(options)
         
     | 
| 
       14 
     | 
    
         
            -
                  options.map do |key, value|
         
     | 
| 
       15 
     | 
    
         
            -
                    case value
         
     | 
| 
       16 
     | 
    
         
            -
                      when true
         
     | 
| 
       17 
     | 
    
         
            -
                        "--#{key}"
         
     | 
| 
       18 
     | 
    
         
            -
                      when Array
         
     | 
| 
       19 
     | 
    
         
            -
                        "--#{key} #{value.map{ |v| v.inspect }.join(' ')}"
         
     | 
| 
       20 
     | 
    
         
            -
                      when Hash
         
     | 
| 
       21 
     | 
    
         
            -
                        "--#{key} #{value.map{ |k,v| "#{k}:#{v}" }.join(' ')}"
         
     | 
| 
       22 
     | 
    
         
            -
                      when nil, false
         
     | 
| 
       23 
     | 
    
         
            -
                        ""
         
     | 
| 
       24 
     | 
    
         
            -
                      else
         
     | 
| 
       25 
     | 
    
         
            -
                        "--#{key} #{value.inspect}"
         
     | 
| 
       26 
     | 
    
         
            -
                    end
         
     | 
| 
       27 
     | 
    
         
            -
                  end.join(" ")
         
     | 
| 
       28 
     | 
    
         
            -
                end
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                # Takes a hash of Thor::Option and a hash with defaults.
         
     | 
| 
       31 
     | 
    
         
            -
                def initialize(hash_options={}, defaults={})
         
     | 
| 
       32 
     | 
    
         
            -
                  options = hash_options.values
         
     | 
| 
       33 
     | 
    
         
            -
                  super(options)
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                  # Add defaults
         
     | 
| 
       36 
     | 
    
         
            -
                  defaults.each do |key, value|
         
     | 
| 
       37 
     | 
    
         
            -
                    @assigns[key.to_s] = value
         
     | 
| 
       38 
     | 
    
         
            -
                    @non_assigned_required.delete(hash_options[key])
         
     | 
| 
       39 
     | 
    
         
            -
                  end
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                  @shorts, @switches, @unknown = {}, {}, []
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
                  options.each do |option|
         
     | 
| 
       44 
     | 
    
         
            -
                    @switches[option.switch_name] = option
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                    option.aliases.each do |short|
         
     | 
| 
       47 
     | 
    
         
            -
                      @shorts[short.to_s] ||= option.switch_name
         
     | 
| 
       48 
     | 
    
         
            -
                    end
         
     | 
| 
       49 
     | 
    
         
            -
                  end
         
     | 
| 
       50 
     | 
    
         
            -
                end
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
                def parse(args)
         
     | 
| 
       53 
     | 
    
         
            -
                  @pile = args.dup
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                  while peek
         
     | 
| 
       56 
     | 
    
         
            -
                    if current_is_switch?
         
     | 
| 
       57 
     | 
    
         
            -
                      case shift
         
     | 
| 
       58 
     | 
    
         
            -
                        when SHORT_SQ_RE
         
     | 
| 
       59 
     | 
    
         
            -
                          unshift($1.split('').map { |f| "-#{f}" })
         
     | 
| 
       60 
     | 
    
         
            -
                          next
         
     | 
| 
       61 
     | 
    
         
            -
                        when EQ_RE, SHORT_NUM
         
     | 
| 
       62 
     | 
    
         
            -
                          unshift($2)
         
     | 
| 
       63 
     | 
    
         
            -
                          switch = $1
         
     | 
| 
       64 
     | 
    
         
            -
                        when LONG_RE, SHORT_RE
         
     | 
| 
       65 
     | 
    
         
            -
                          switch = $1
         
     | 
| 
       66 
     | 
    
         
            -
                      end
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
                      switch = normalize_switch(switch)
         
     | 
| 
       69 
     | 
    
         
            -
                      option = switch_option(switch)
         
     | 
| 
       70 
     | 
    
         
            -
                      @assigns[option.human_name] = parse_peek(switch, option)
         
     | 
| 
       71 
     | 
    
         
            -
                    elsif current_is_switch_formatted?
         
     | 
| 
       72 
     | 
    
         
            -
                      @unknown << shift
         
     | 
| 
       73 
     | 
    
         
            -
                    else
         
     | 
| 
       74 
     | 
    
         
            -
                      shift
         
     | 
| 
       75 
     | 
    
         
            -
                    end
         
     | 
| 
       76 
     | 
    
         
            -
                  end
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
                  check_requirement!
         
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
                  assigns = Thor::CoreExt::HashWithIndifferentAccess.new(@assigns)
         
     | 
| 
       81 
     | 
    
         
            -
                  assigns.freeze
         
     | 
| 
       82 
     | 
    
         
            -
                  assigns
         
     | 
| 
       83 
     | 
    
         
            -
                end
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                def check_unknown!
         
     | 
| 
       86 
     | 
    
         
            -
                  raise UnknownArgumentError, "Unknown switches '#{@unknown.join(', ')}'" unless @unknown.empty?
         
     | 
| 
       87 
     | 
    
         
            -
                end
         
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
                protected
         
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
                  # Returns true if the current value in peek is a registered switch.
         
     | 
| 
       92 
     | 
    
         
            -
                  #
         
     | 
| 
       93 
     | 
    
         
            -
                  def current_is_switch?
         
     | 
| 
       94 
     | 
    
         
            -
                    case peek
         
     | 
| 
       95 
     | 
    
         
            -
                      when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM
         
     | 
| 
       96 
     | 
    
         
            -
                        switch?($1)
         
     | 
| 
       97 
     | 
    
         
            -
                      when SHORT_SQ_RE
         
     | 
| 
       98 
     | 
    
         
            -
                        $1.split('').any? { |f| switch?("-#{f}") }
         
     | 
| 
       99 
     | 
    
         
            -
                    end
         
     | 
| 
       100 
     | 
    
         
            -
                  end
         
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
                  def switch_formatted?(arg)
         
     | 
| 
       103 
     | 
    
         
            -
                    case arg
         
     | 
| 
       104 
     | 
    
         
            -
                    when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM, SHORT_SQ_RE
         
     | 
| 
       105 
     | 
    
         
            -
                      true
         
     | 
| 
       106 
     | 
    
         
            -
                    else
         
     | 
| 
       107 
     | 
    
         
            -
                      false
         
     | 
| 
       108 
     | 
    
         
            -
                    end
         
     | 
| 
       109 
     | 
    
         
            -
                  end
         
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
     | 
    
         
            -
                  def current_is_switch_formatted?
         
     | 
| 
       112 
     | 
    
         
            -
                    switch_formatted? peek
         
     | 
| 
       113 
     | 
    
         
            -
                  end
         
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
                  def switch?(arg)
         
     | 
| 
       116 
     | 
    
         
            -
                    switch_option(arg) || @shorts.key?(arg)
         
     | 
| 
       117 
     | 
    
         
            -
                  end
         
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
                  def switch_option(arg)
         
     | 
| 
       120 
     | 
    
         
            -
                    if match = no_or_skip?(arg)
         
     | 
| 
       121 
     | 
    
         
            -
                      @switches[arg] || @switches["--#{match}"]
         
     | 
| 
       122 
     | 
    
         
            -
                    else
         
     | 
| 
       123 
     | 
    
         
            -
                      @switches[arg]
         
     | 
| 
       124 
     | 
    
         
            -
                    end
         
     | 
| 
       125 
     | 
    
         
            -
                  end
         
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
                  # Check if the given argument is actually a shortcut.
         
     | 
| 
       128 
     | 
    
         
            -
                  #
         
     | 
| 
       129 
     | 
    
         
            -
                  def normalize_switch(arg)
         
     | 
| 
       130 
     | 
    
         
            -
                    @shorts.key?(arg) ? @shorts[arg] : arg
         
     | 
| 
       131 
     | 
    
         
            -
                  end
         
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
                  # Parse boolean values which can be given as --foo=true, --foo or --no-foo.
         
     | 
| 
       134 
     | 
    
         
            -
                  #
         
     | 
| 
       135 
     | 
    
         
            -
                  def parse_boolean(switch)
         
     | 
| 
       136 
     | 
    
         
            -
                    if current_is_value?
         
     | 
| 
       137 
     | 
    
         
            -
                      ["true", "TRUE", "t", "T", true].include?(shift)
         
     | 
| 
       138 
     | 
    
         
            -
                    else
         
     | 
| 
       139 
     | 
    
         
            -
                      @switches.key?(switch) || !no_or_skip?(switch)
         
     | 
| 
       140 
     | 
    
         
            -
                    end
         
     | 
| 
       141 
     | 
    
         
            -
                  end
         
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
                  # Parse the value at the peek analyzing if it requires an input or not.
         
     | 
| 
       144 
     | 
    
         
            -
                  #
         
     | 
| 
       145 
     | 
    
         
            -
                  def parse_peek(switch, option)
         
     | 
| 
       146 
     | 
    
         
            -
                    if current_is_switch_formatted? || last?
         
     | 
| 
       147 
     | 
    
         
            -
                      if option.boolean?
         
     | 
| 
       148 
     | 
    
         
            -
                        # No problem for boolean types
         
     | 
| 
       149 
     | 
    
         
            -
                      elsif no_or_skip?(switch)
         
     | 
| 
       150 
     | 
    
         
            -
                        return nil # User set value to nil
         
     | 
| 
       151 
     | 
    
         
            -
                      elsif option.string? && !option.required?
         
     | 
| 
       152 
     | 
    
         
            -
                        # Return the default if there is one, else the human name
         
     | 
| 
       153 
     | 
    
         
            -
                        return option.default || option.human_name
         
     | 
| 
       154 
     | 
    
         
            -
                      else
         
     | 
| 
       155 
     | 
    
         
            -
                        raise MalformattedArgumentError, "No value provided for option '#{switch}'"
         
     | 
| 
       156 
     | 
    
         
            -
                      end
         
     | 
| 
       157 
     | 
    
         
            -
                    end
         
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
                    @non_assigned_required.delete(option)
         
     | 
| 
       160 
     | 
    
         
            -
                    send(:"parse_#{option.type}", switch)
         
     | 
| 
       161 
     | 
    
         
            -
                  end
         
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
              end
         
     | 
| 
       164 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,66 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'rake'
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            class Thor
         
     | 
| 
       4 
     | 
    
         
            -
              # Adds a compatibility layer to your Thor classes which allows you to use
         
     | 
| 
       5 
     | 
    
         
            -
              # rake package tasks. For example, to use rspec rake tasks, one can do:
         
     | 
| 
       6 
     | 
    
         
            -
              #
         
     | 
| 
       7 
     | 
    
         
            -
              #   require 'thor/rake_compat'
         
     | 
| 
       8 
     | 
    
         
            -
              #
         
     | 
| 
       9 
     | 
    
         
            -
              #   class Default < Thor
         
     | 
| 
       10 
     | 
    
         
            -
              #     include Thor::RakeCompat
         
     | 
| 
       11 
     | 
    
         
            -
              #
         
     | 
| 
       12 
     | 
    
         
            -
              #     Spec::Rake::SpecTask.new(:spec) do |t|
         
     | 
| 
       13 
     | 
    
         
            -
              #       t.spec_opts = ['--options', "spec/spec.opts"]
         
     | 
| 
       14 
     | 
    
         
            -
              #       t.spec_files = FileList['spec/**/*_spec.rb']
         
     | 
| 
       15 
     | 
    
         
            -
              #     end
         
     | 
| 
       16 
     | 
    
         
            -
              #   end
         
     | 
| 
       17 
     | 
    
         
            -
              #
         
     | 
| 
       18 
     | 
    
         
            -
              module RakeCompat
         
     | 
| 
       19 
     | 
    
         
            -
                def self.rake_classes
         
     | 
| 
       20 
     | 
    
         
            -
                  @rake_classes ||= []
         
     | 
| 
       21 
     | 
    
         
            -
                end
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                def self.included(base)
         
     | 
| 
       24 
     | 
    
         
            -
                  # Hack. Make rakefile point to invoker, so rdoc task is generated properly.
         
     | 
| 
       25 
     | 
    
         
            -
                  rakefile = File.basename(caller[0].match(/(.*):\d+/)[1])
         
     | 
| 
       26 
     | 
    
         
            -
                  Rake.application.instance_variable_set(:@rakefile, rakefile)
         
     | 
| 
       27 
     | 
    
         
            -
                  self.rake_classes << base
         
     | 
| 
       28 
     | 
    
         
            -
                end
         
     | 
| 
       29 
     | 
    
         
            -
              end
         
     | 
| 
       30 
     | 
    
         
            -
            end
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
            class Object #:nodoc:
         
     | 
| 
       33 
     | 
    
         
            -
              alias :rake_task :task
         
     | 
| 
       34 
     | 
    
         
            -
              alias :rake_namespace :namespace
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
              def task(*args, &block)
         
     | 
| 
       37 
     | 
    
         
            -
                task = rake_task(*args, &block)
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                if klass = Thor::RakeCompat.rake_classes.last
         
     | 
| 
       40 
     | 
    
         
            -
                  non_namespaced_name = task.name.split(':').last
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                  description = non_namespaced_name
         
     | 
| 
       43 
     | 
    
         
            -
                  description << task.arg_names.map{ |n| n.to_s.upcase }.join(' ')
         
     | 
| 
       44 
     | 
    
         
            -
                  description.strip!
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                  klass.desc description, task.comment || non_namespaced_name
         
     | 
| 
       47 
     | 
    
         
            -
                  klass.send :define_method, non_namespaced_name do |*args|
         
     | 
| 
       48 
     | 
    
         
            -
                    Rake::Task[task.name.to_sym].invoke(*args)
         
     | 
| 
       49 
     | 
    
         
            -
                  end
         
     | 
| 
       50 
     | 
    
         
            -
                end
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
                task
         
     | 
| 
       53 
     | 
    
         
            -
              end
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
              def namespace(name, &block)
         
     | 
| 
       56 
     | 
    
         
            -
                if klass = Thor::RakeCompat.rake_classes.last
         
     | 
| 
       57 
     | 
    
         
            -
                  const_name = Thor::Util.camel_case(name.to_s).to_sym
         
     | 
| 
       58 
     | 
    
         
            -
                  klass.const_set(const_name, Class.new(Thor))
         
     | 
| 
       59 
     | 
    
         
            -
                  new_klass = klass.const_get(const_name)
         
     | 
| 
       60 
     | 
    
         
            -
                  Thor::RakeCompat.rake_classes << new_klass
         
     | 
| 
       61 
     | 
    
         
            -
                end
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                rake_namespace(name, &block)
         
     | 
| 
       64 
     | 
    
         
            -
                Thor::RakeCompat.rake_classes.pop
         
     | 
| 
       65 
     | 
    
         
            -
              end
         
     | 
| 
       66 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,314 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'thor'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'thor/group'
         
     | 
| 
       3 
     | 
    
         
            -
            require 'thor/core_ext/file_binary_read'
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            require 'fileutils'
         
     | 
| 
       6 
     | 
    
         
            -
            require 'open-uri'
         
     | 
| 
       7 
     | 
    
         
            -
            require 'yaml'
         
     | 
| 
       8 
     | 
    
         
            -
            require 'digest/md5'
         
     | 
| 
       9 
     | 
    
         
            -
            require 'pathname'
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
            class Thor::Runner < Thor #:nodoc:
         
     | 
| 
       12 
     | 
    
         
            -
              map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
              # Override Thor#help so it can give information about any class and any method.
         
     | 
| 
       15 
     | 
    
         
            -
              #
         
     | 
| 
       16 
     | 
    
         
            -
              def help(meth=nil)
         
     | 
| 
       17 
     | 
    
         
            -
                if meth && !self.respond_to?(meth)
         
     | 
| 
       18 
     | 
    
         
            -
                  initialize_thorfiles(meth)
         
     | 
| 
       19 
     | 
    
         
            -
                  klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
         
     | 
| 
       20 
     | 
    
         
            -
                  klass.start(["-h", task].compact, :shell => self.shell)
         
     | 
| 
       21 
     | 
    
         
            -
                else
         
     | 
| 
       22 
     | 
    
         
            -
                  super
         
     | 
| 
       23 
     | 
    
         
            -
                end
         
     | 
| 
       24 
     | 
    
         
            -
              end
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
              # If a task is not found on Thor::Runner, method missing is invoked and
         
     | 
| 
       27 
     | 
    
         
            -
              # Thor::Runner is then responsable for finding the task in all classes.
         
     | 
| 
       28 
     | 
    
         
            -
              #
         
     | 
| 
       29 
     | 
    
         
            -
              def method_missing(meth, *args)
         
     | 
| 
       30 
     | 
    
         
            -
                meth = meth.to_s
         
     | 
| 
       31 
     | 
    
         
            -
                initialize_thorfiles(meth)
         
     | 
| 
       32 
     | 
    
         
            -
                klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
         
     | 
| 
       33 
     | 
    
         
            -
                args.unshift(task) if task
         
     | 
| 
       34 
     | 
    
         
            -
                klass.start(args, :shell => self.shell)
         
     | 
| 
       35 
     | 
    
         
            -
              end
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
              desc "install NAME", "Install an optionally named Thor file into your system tasks"
         
     | 
| 
       38 
     | 
    
         
            -
              method_options :as => :string, :relative => :boolean, :force => :boolean
         
     | 
| 
       39 
     | 
    
         
            -
              def install(name)
         
     | 
| 
       40 
     | 
    
         
            -
                initialize_thorfiles
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                # If a directory name is provided as the argument, look for a 'main.thor'
         
     | 
| 
       43 
     | 
    
         
            -
                # task in said directory.
         
     | 
| 
       44 
     | 
    
         
            -
                begin
         
     | 
| 
       45 
     | 
    
         
            -
                  if File.directory?(File.expand_path(name))
         
     | 
| 
       46 
     | 
    
         
            -
                    base, package = File.join(name, "main.thor"), :directory
         
     | 
| 
       47 
     | 
    
         
            -
                    contents      = open(base) {|input| input.read }
         
     | 
| 
       48 
     | 
    
         
            -
                  else
         
     | 
| 
       49 
     | 
    
         
            -
                    base, package = name, :file
         
     | 
| 
       50 
     | 
    
         
            -
                    contents      = open(name) {|input| input.read }
         
     | 
| 
       51 
     | 
    
         
            -
                  end
         
     | 
| 
       52 
     | 
    
         
            -
                rescue OpenURI::HTTPError
         
     | 
| 
       53 
     | 
    
         
            -
                  raise Error, "Error opening URI '#{name}'"
         
     | 
| 
       54 
     | 
    
         
            -
                rescue Errno::ENOENT
         
     | 
| 
       55 
     | 
    
         
            -
                  raise Error, "Error opening file '#{name}'"
         
     | 
| 
       56 
     | 
    
         
            -
                end
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                say "Your Thorfile contains:"
         
     | 
| 
       59 
     | 
    
         
            -
                say contents
         
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
                unless options["force"]
         
     | 
| 
       62 
     | 
    
         
            -
                  return false if no?("Do you wish to continue [y/N]?")
         
     | 
| 
       63 
     | 
    
         
            -
                end
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
                as = options["as"] || begin
         
     | 
| 
       66 
     | 
    
         
            -
                  first_line = contents.split("\n")[0]
         
     | 
| 
       67 
     | 
    
         
            -
                  (match = first_line.match(/\s*#\s*module:\s*([^\n]*)/)) ? match[1].strip : nil
         
     | 
| 
       68 
     | 
    
         
            -
                end
         
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
                unless as
         
     | 
| 
       71 
     | 
    
         
            -
                  basename = File.basename(name)
         
     | 
| 
       72 
     | 
    
         
            -
                  as = ask("Please specify a name for #{name} in the system repository [#{basename}]:")
         
     | 
| 
       73 
     | 
    
         
            -
                  as = basename if as.empty?
         
     | 
| 
       74 
     | 
    
         
            -
                end
         
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
                location = if options[:relative] || name =~ /^http:\/\//
         
     | 
| 
       77 
     | 
    
         
            -
                  name
         
     | 
| 
       78 
     | 
    
         
            -
                else
         
     | 
| 
       79 
     | 
    
         
            -
                  File.expand_path(name)
         
     | 
| 
       80 
     | 
    
         
            -
                end
         
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
                thor_yaml[as] = {
         
     | 
| 
       83 
     | 
    
         
            -
                  :filename   => Digest::MD5.hexdigest(name + as),
         
     | 
| 
       84 
     | 
    
         
            -
                  :location   => location,
         
     | 
| 
       85 
     | 
    
         
            -
                  :namespaces => Thor::Util.namespaces_in_content(contents, base)
         
     | 
| 
       86 
     | 
    
         
            -
                }
         
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
                save_yaml(thor_yaml)
         
     | 
| 
       89 
     | 
    
         
            -
                say "Storing thor file in your system repository"
         
     | 
| 
       90 
     | 
    
         
            -
                destination = File.join(thor_root, thor_yaml[as][:filename])
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
                if package == :file
         
     | 
| 
       93 
     | 
    
         
            -
                  File.open(destination, "w") { |f| f.puts contents }
         
     | 
| 
       94 
     | 
    
         
            -
                else
         
     | 
| 
       95 
     | 
    
         
            -
                  FileUtils.cp_r(name, destination)
         
     | 
| 
       96 
     | 
    
         
            -
                end
         
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
     | 
    
         
            -
                thor_yaml[as][:filename] # Indicate success
         
     | 
| 
       99 
     | 
    
         
            -
              end
         
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
              desc "version", "Show Thor version"
         
     | 
| 
       102 
     | 
    
         
            -
              def version
         
     | 
| 
       103 
     | 
    
         
            -
                require 'thor/version'
         
     | 
| 
       104 
     | 
    
         
            -
                say "Thor #{Thor::VERSION}"
         
     | 
| 
       105 
     | 
    
         
            -
              end
         
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
              desc "uninstall NAME", "Uninstall a named Thor module"
         
     | 
| 
       108 
     | 
    
         
            -
              def uninstall(name)
         
     | 
| 
       109 
     | 
    
         
            -
                raise Error, "Can't find module '#{name}'" unless thor_yaml[name]
         
     | 
| 
       110 
     | 
    
         
            -
                say "Uninstalling #{name}."
         
     | 
| 
       111 
     | 
    
         
            -
                FileUtils.rm_rf(File.join(thor_root, "#{thor_yaml[name][:filename]}"))
         
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
                thor_yaml.delete(name)
         
     | 
| 
       114 
     | 
    
         
            -
                save_yaml(thor_yaml)
         
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
     | 
    
         
            -
                puts "Done."
         
     | 
| 
       117 
     | 
    
         
            -
              end
         
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
              desc "update NAME", "Update a Thor file from its original location"
         
     | 
| 
       120 
     | 
    
         
            -
              def update(name)
         
     | 
| 
       121 
     | 
    
         
            -
                raise Error, "Can't find module '#{name}'" if !thor_yaml[name] || !thor_yaml[name][:location]
         
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
                say "Updating '#{name}' from #{thor_yaml[name][:location]}"
         
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
                old_filename = thor_yaml[name][:filename]
         
     | 
| 
       126 
     | 
    
         
            -
                self.options = self.options.merge("as" => name)
         
     | 
| 
       127 
     | 
    
         
            -
                filename     = install(thor_yaml[name][:location])
         
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
                unless filename == old_filename
         
     | 
| 
       130 
     | 
    
         
            -
                  File.delete(File.join(thor_root, old_filename))
         
     | 
| 
       131 
     | 
    
         
            -
                end
         
     | 
| 
       132 
     | 
    
         
            -
              end
         
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
              desc "installed", "List the installed Thor modules and tasks"
         
     | 
| 
       135 
     | 
    
         
            -
              method_options :internal => :boolean
         
     | 
| 
       136 
     | 
    
         
            -
              def installed
         
     | 
| 
       137 
     | 
    
         
            -
                initialize_thorfiles(nil, true)
         
     | 
| 
       138 
     | 
    
         
            -
                display_klasses(true, options["internal"])
         
     | 
| 
       139 
     | 
    
         
            -
              end
         
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
              desc "list [SEARCH]", "List the available thor tasks (--substring means .*SEARCH)"
         
     | 
| 
       142 
     | 
    
         
            -
              method_options :substring => :boolean, :group => :string, :all => :boolean, :debug => :boolean
         
     | 
| 
       143 
     | 
    
         
            -
              def list(search="")
         
     | 
| 
       144 
     | 
    
         
            -
                initialize_thorfiles
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
                search = ".*#{search}" if options["substring"]
         
     | 
| 
       147 
     | 
    
         
            -
                search = /^#{search}.*/i
         
     | 
| 
       148 
     | 
    
         
            -
                group  = options[:group] || "standard"
         
     | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
       150 
     | 
    
         
            -
                klasses = Thor::Base.subclasses.select do |k|
         
     | 
| 
       151 
     | 
    
         
            -
                  (options[:all] || k.group == group) && k.namespace =~ search
         
     | 
| 
       152 
     | 
    
         
            -
                end
         
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
                display_klasses(false, false, klasses)
         
     | 
| 
       155 
     | 
    
         
            -
              end
         
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
              private
         
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
                def self.banner(task)
         
     | 
| 
       160 
     | 
    
         
            -
                  "thor " + task.formatted_usage(self, false)
         
     | 
| 
       161 
     | 
    
         
            -
                end
         
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
                def thor_root
         
     | 
| 
       164 
     | 
    
         
            -
                  Thor::Util.thor_root
         
     | 
| 
       165 
     | 
    
         
            -
                end
         
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
                def thor_yaml
         
     | 
| 
       168 
     | 
    
         
            -
                  @thor_yaml ||= begin
         
     | 
| 
       169 
     | 
    
         
            -
                    yaml_file = File.join(thor_root, "thor.yml")
         
     | 
| 
       170 
     | 
    
         
            -
                    yaml = YAML.load_file(yaml_file) if File.exists?(yaml_file)
         
     | 
| 
       171 
     | 
    
         
            -
                    yaml || {}
         
     | 
| 
       172 
     | 
    
         
            -
                  end
         
     | 
| 
       173 
     | 
    
         
            -
                end
         
     | 
| 
       174 
     | 
    
         
            -
             
     | 
| 
       175 
     | 
    
         
            -
                # Save the yaml file. If none exists in thor root, creates one.
         
     | 
| 
       176 
     | 
    
         
            -
                #
         
     | 
| 
       177 
     | 
    
         
            -
                def save_yaml(yaml)
         
     | 
| 
       178 
     | 
    
         
            -
                  yaml_file = File.join(thor_root, "thor.yml")
         
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
       180 
     | 
    
         
            -
                  unless File.exists?(yaml_file)
         
     | 
| 
       181 
     | 
    
         
            -
                    FileUtils.mkdir_p(thor_root)
         
     | 
| 
       182 
     | 
    
         
            -
                    yaml_file = File.join(thor_root, "thor.yml")
         
     | 
| 
       183 
     | 
    
         
            -
                    FileUtils.touch(yaml_file)
         
     | 
| 
       184 
     | 
    
         
            -
                  end
         
     | 
| 
       185 
     | 
    
         
            -
             
     | 
| 
       186 
     | 
    
         
            -
                  File.open(yaml_file, "w") { |f| f.puts yaml.to_yaml }
         
     | 
| 
       187 
     | 
    
         
            -
                end
         
     | 
| 
       188 
     | 
    
         
            -
             
     | 
| 
       189 
     | 
    
         
            -
                def self.exit_on_failure?
         
     | 
| 
       190 
     | 
    
         
            -
                  true
         
     | 
| 
       191 
     | 
    
         
            -
                end
         
     | 
| 
       192 
     | 
    
         
            -
             
     | 
| 
       193 
     | 
    
         
            -
                # Load the thorfiles. If relevant_to is supplied, looks for specific files
         
     | 
| 
       194 
     | 
    
         
            -
                # in the thor_root instead of loading them all.
         
     | 
| 
       195 
     | 
    
         
            -
                #
         
     | 
| 
       196 
     | 
    
         
            -
                # By default, it also traverses the current path until find Thor files, as
         
     | 
| 
       197 
     | 
    
         
            -
                # described in thorfiles. This look up can be skipped by suppliying
         
     | 
| 
       198 
     | 
    
         
            -
                # skip_lookup true.
         
     | 
| 
       199 
     | 
    
         
            -
                #
         
     | 
| 
       200 
     | 
    
         
            -
                def initialize_thorfiles(relevant_to=nil, skip_lookup=false)
         
     | 
| 
       201 
     | 
    
         
            -
                  thorfiles(relevant_to, skip_lookup).each do |f|
         
     | 
| 
       202 
     | 
    
         
            -
                    Thor::Util.load_thorfile(f, nil, options[:debug]) unless Thor::Base.subclass_files.keys.include?(File.expand_path(f))
         
     | 
| 
       203 
     | 
    
         
            -
                  end
         
     | 
| 
       204 
     | 
    
         
            -
                end
         
     | 
| 
       205 
     | 
    
         
            -
             
     | 
| 
       206 
     | 
    
         
            -
                # Finds Thorfiles by traversing from your current directory down to the root
         
     | 
| 
       207 
     | 
    
         
            -
                # directory of your system. If at any time we find a Thor file, we stop.
         
     | 
| 
       208 
     | 
    
         
            -
                #
         
     | 
| 
       209 
     | 
    
         
            -
                # We also ensure that system-wide Thorfiles are loaded first, so local
         
     | 
| 
       210 
     | 
    
         
            -
                # Thorfiles can override them.
         
     | 
| 
       211 
     | 
    
         
            -
                #
         
     | 
| 
       212 
     | 
    
         
            -
                # ==== Example
         
     | 
| 
       213 
     | 
    
         
            -
                #
         
     | 
| 
       214 
     | 
    
         
            -
                # If we start at /Users/wycats/dev/thor ...
         
     | 
| 
       215 
     | 
    
         
            -
                #
         
     | 
| 
       216 
     | 
    
         
            -
                # 1. /Users/wycats/dev/thor
         
     | 
| 
       217 
     | 
    
         
            -
                # 2. /Users/wycats/dev
         
     | 
| 
       218 
     | 
    
         
            -
                # 3. /Users/wycats <-- we find a Thorfile here, so we stop
         
     | 
| 
       219 
     | 
    
         
            -
                #
         
     | 
| 
       220 
     | 
    
         
            -
                # Suppose we start at c:\Documents and Settings\james\dev\thor ...
         
     | 
| 
       221 
     | 
    
         
            -
                #
         
     | 
| 
       222 
     | 
    
         
            -
                # 1. c:\Documents and Settings\james\dev\thor
         
     | 
| 
       223 
     | 
    
         
            -
                # 2. c:\Documents and Settings\james\dev
         
     | 
| 
       224 
     | 
    
         
            -
                # 3. c:\Documents and Settings\james
         
     | 
| 
       225 
     | 
    
         
            -
                # 4. c:\Documents and Settings
         
     | 
| 
       226 
     | 
    
         
            -
                # 5. c:\ <-- no Thorfiles found!
         
     | 
| 
       227 
     | 
    
         
            -
                #
         
     | 
| 
       228 
     | 
    
         
            -
                def thorfiles(relevant_to=nil, skip_lookup=false)
         
     | 
| 
       229 
     | 
    
         
            -
                  thorfiles = []
         
     | 
| 
       230 
     | 
    
         
            -
             
     | 
| 
       231 
     | 
    
         
            -
                  unless skip_lookup
         
     | 
| 
       232 
     | 
    
         
            -
                    Pathname.pwd.ascend do |path|
         
     | 
| 
       233 
     | 
    
         
            -
                      thorfiles = Thor::Util.globs_for(path).map { |g| Dir[g] }.flatten
         
     | 
| 
       234 
     | 
    
         
            -
                      break unless thorfiles.empty?
         
     | 
| 
       235 
     | 
    
         
            -
                    end
         
     | 
| 
       236 
     | 
    
         
            -
                  end
         
     | 
| 
       237 
     | 
    
         
            -
             
     | 
| 
       238 
     | 
    
         
            -
                  files  = (relevant_to ? thorfiles_relevant_to(relevant_to) : Thor::Util.thor_root_glob)
         
     | 
| 
       239 
     | 
    
         
            -
                  files += thorfiles
         
     | 
| 
       240 
     | 
    
         
            -
                  files -= ["#{thor_root}/thor.yml"]
         
     | 
| 
       241 
     | 
    
         
            -
             
     | 
| 
       242 
     | 
    
         
            -
                  files.map! do |file|
         
     | 
| 
       243 
     | 
    
         
            -
                    File.directory?(file) ? File.join(file, "main.thor") : file
         
     | 
| 
       244 
     | 
    
         
            -
                  end
         
     | 
| 
       245 
     | 
    
         
            -
                end
         
     | 
| 
       246 
     | 
    
         
            -
             
     | 
| 
       247 
     | 
    
         
            -
                # Load thorfiles relevant to the given method. If you provide "foo:bar" it
         
     | 
| 
       248 
     | 
    
         
            -
                # will load all thor files in the thor.yaml that has "foo" e "foo:bar"
         
     | 
| 
       249 
     | 
    
         
            -
                # namespaces registered.
         
     | 
| 
       250 
     | 
    
         
            -
                #
         
     | 
| 
       251 
     | 
    
         
            -
                def thorfiles_relevant_to(meth)
         
     | 
| 
       252 
     | 
    
         
            -
                  lookup = [ meth, meth.split(":")[0...-1].join(":") ]
         
     | 
| 
       253 
     | 
    
         
            -
             
     | 
| 
       254 
     | 
    
         
            -
                  files = thor_yaml.select do |k, v|
         
     | 
| 
       255 
     | 
    
         
            -
                    v[:namespaces] && !(v[:namespaces] & lookup).empty?
         
     | 
| 
       256 
     | 
    
         
            -
                  end
         
     | 
| 
       257 
     | 
    
         
            -
             
     | 
| 
       258 
     | 
    
         
            -
                  files.map { |k, v| File.join(thor_root, "#{v[:filename]}") }
         
     | 
| 
       259 
     | 
    
         
            -
                end
         
     | 
| 
       260 
     | 
    
         
            -
             
     | 
| 
       261 
     | 
    
         
            -
                # Display information about the given klasses. If with_module is given,
         
     | 
| 
       262 
     | 
    
         
            -
                # it shows a table with information extracted from the yaml file.
         
     | 
| 
       263 
     | 
    
         
            -
                #
         
     | 
| 
       264 
     | 
    
         
            -
                def display_klasses(with_modules=false, show_internal=false, klasses=Thor::Base.subclasses)
         
     | 
| 
       265 
     | 
    
         
            -
                  klasses -= [Thor, Thor::Runner, Thor::Group] unless show_internal
         
     | 
| 
       266 
     | 
    
         
            -
             
     | 
| 
       267 
     | 
    
         
            -
                  raise Error, "No Thor tasks available" if klasses.empty?
         
     | 
| 
       268 
     | 
    
         
            -
                  show_modules if with_modules && !thor_yaml.empty?
         
     | 
| 
       269 
     | 
    
         
            -
             
     | 
| 
       270 
     | 
    
         
            -
                  # Remove subclasses
         
     | 
| 
       271 
     | 
    
         
            -
                  klasses.dup.each do |klass|
         
     | 
| 
       272 
     | 
    
         
            -
                    klasses -= Thor::Util.thor_classes_in(klass)
         
     | 
| 
       273 
     | 
    
         
            -
                  end
         
     | 
| 
       274 
     | 
    
         
            -
             
     | 
| 
       275 
     | 
    
         
            -
                  list = Hash.new { |h,k| h[k] = [] }
         
     | 
| 
       276 
     | 
    
         
            -
                  groups = klasses.select { |k| k.ancestors.include?(Thor::Group) }
         
     | 
| 
       277 
     | 
    
         
            -
             
     | 
| 
       278 
     | 
    
         
            -
                  # Get classes which inherit from Thor
         
     | 
| 
       279 
     | 
    
         
            -
                  (klasses - groups).each { |k| list[k.namespace] += k.printable_tasks(false) }
         
     | 
| 
       280 
     | 
    
         
            -
             
     | 
| 
       281 
     | 
    
         
            -
                  # Get classes which inherit from Thor::Base
         
     | 
| 
       282 
     | 
    
         
            -
                  groups.map! { |k| k.printable_tasks(false).first }
         
     | 
| 
       283 
     | 
    
         
            -
                  list["root"] = groups
         
     | 
| 
       284 
     | 
    
         
            -
             
     | 
| 
       285 
     | 
    
         
            -
                  # Order namespaces with default coming first
         
     | 
| 
       286 
     | 
    
         
            -
                  list = list.sort{ |a,b| a[0].sub(/^default/, '') <=> b[0].sub(/^default/, '') }
         
     | 
| 
       287 
     | 
    
         
            -
                  list.each { |n, tasks| display_tasks(n, tasks) unless tasks.empty? }
         
     | 
| 
       288 
     | 
    
         
            -
                end
         
     | 
| 
       289 
     | 
    
         
            -
             
     | 
| 
       290 
     | 
    
         
            -
                def display_tasks(namespace, list) #:nodoc:
         
     | 
| 
       291 
     | 
    
         
            -
                  list.sort!{ |a,b| a[0] <=> b[0] }
         
     | 
| 
       292 
     | 
    
         
            -
             
     | 
| 
       293 
     | 
    
         
            -
                  say shell.set_color(namespace, :blue, true)
         
     | 
| 
       294 
     | 
    
         
            -
                  say "-" * namespace.size
         
     | 
| 
       295 
     | 
    
         
            -
             
     | 
| 
       296 
     | 
    
         
            -
                  print_table(list, :truncate => true)
         
     | 
| 
       297 
     | 
    
         
            -
                  say
         
     | 
| 
       298 
     | 
    
         
            -
                end
         
     | 
| 
       299 
     | 
    
         
            -
             
     | 
| 
       300 
     | 
    
         
            -
                def show_modules #:nodoc:
         
     | 
| 
       301 
     | 
    
         
            -
                  info  = []
         
     | 
| 
       302 
     | 
    
         
            -
                  labels = ["Modules", "Namespaces"]
         
     | 
| 
       303 
     | 
    
         
            -
             
     | 
| 
       304 
     | 
    
         
            -
                  info << labels
         
     | 
| 
       305 
     | 
    
         
            -
                  info << [ "-" * labels[0].size, "-" * labels[1].size ]
         
     | 
| 
       306 
     | 
    
         
            -
             
     | 
| 
       307 
     | 
    
         
            -
                  thor_yaml.each do |name, hash|
         
     | 
| 
       308 
     | 
    
         
            -
                    info << [ name, hash[:namespaces].join(", ") ]
         
     | 
| 
       309 
     | 
    
         
            -
                  end
         
     | 
| 
       310 
     | 
    
         
            -
             
     | 
| 
       311 
     | 
    
         
            -
                  print_table info
         
     | 
| 
       312 
     | 
    
         
            -
                  say ""
         
     | 
| 
       313 
     | 
    
         
            -
                end
         
     | 
| 
       314 
     | 
    
         
            -
            end
         
     |