tap 0.10.0 → 0.10.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/History +9 -0
- data/README +1 -0
- data/bin/tap +7 -45
- data/cmd/manifest.rb +94 -0
- data/cmd/run.rb +1 -1
- data/lib/tap.rb +0 -5
- data/lib/tap/constants.rb +1 -1
- data/lib/tap/env.rb +195 -187
- data/lib/tap/exe.rb +63 -0
- data/lib/tap/file_task.rb +33 -8
- data/lib/tap/generator/base.rb +7 -28
- data/lib/tap/generator/generators/root/root_generator.rb +21 -15
- data/lib/tap/generator/generators/root/templates/Rakefile +1 -1
- data/lib/tap/generator/generators/root/templates/gemspec +2 -1
- data/lib/tap/patches/rake/testtask.rb +2 -0
- data/lib/tap/support/class_configuration.rb +5 -6
- data/lib/tap/support/configurable_class.rb +15 -18
- data/lib/tap/support/configuration.rb +8 -6
- data/lib/tap/support/declarations.rb +2 -2
- data/lib/tap/support/framework.rb +14 -2
- data/lib/tap/support/framework_class.rb +13 -32
- data/lib/tap/support/gems.rb +63 -0
- data/lib/tap/support/gems/rake.rb +90 -0
- data/lib/tap/support/instance_configuration.rb +8 -8
- data/lib/tap/support/lazy_attributes.rb +30 -0
- data/lib/tap/support/lazydoc.rb +65 -33
- data/lib/tap/support/manifest.rb +117 -54
- data/lib/tap/tasks/rake.rb +1 -0
- data/lib/tap/test/script_methods.rb +34 -71
- data/lib/tap/test/script_methods/script_test.rb +98 -0
- data/lib/tap/test/tap_methods.rb +1 -5
- data/lib/tap/workflow.rb +47 -34
- metadata +8 -2
    
        data/History
    CHANGED
    
    | @@ -1,3 +1,12 @@ | |
| 1 | 
            +
            == 0.10.1 / 2008-08-21
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Update of Tap with a few improvements to manifests
         | 
| 4 | 
            +
            and a new manifest command.
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            * Fixed some bugs and extended manifests
         | 
| 7 | 
            +
            * Bug fixes in generators
         | 
| 8 | 
            +
            * Added task definitions to Workflow
         | 
| 9 | 
            +
             | 
| 1 10 | 
             
            == 0.10.0 / 2008-08-08
         | 
| 2 11 |  | 
| 3 12 | 
             
            Major revision.  Reworked configurations and the execution
         | 
    
        data/README
    CHANGED
    
    | @@ -14,6 +14,7 @@ development, and bug tracking. | |
| 14 14 | 
             
            * Website[http://tap.rubyforge.org]
         | 
| 15 15 | 
             
            * Lighthouse[http://bahuvrihi.lighthouseapp.com/projects/9908-tap-task-application/overview]
         | 
| 16 16 | 
             
            * Github[http://github.com/bahuvrihi/tap/tree/master]
         | 
| 17 | 
            +
            * Google Group[http://groups.google.com/group/ruby-on-tap]
         | 
| 17 18 |  | 
| 18 19 | 
             
            === Additional Notes:
         | 
| 19 20 |  | 
    
        data/bin/tap
    CHANGED
    
    | @@ -10,37 +10,14 @@ | |
| 10 10 | 
             
            #   tap command --help                   # prints help for 'command'
         | 
| 11 11 | 
             
            #
         | 
| 12 12 |  | 
| 13 | 
            -
             | 
| 14 | 
            -
            require  | 
| 13 | 
            +
            require "#{File.dirname(__FILE__)}/../lib/tap.rb"
         | 
| 14 | 
            +
            require 'tap/exe'
         | 
| 15 15 |  | 
| 16 16 | 
             
            # setup the environment
         | 
| 17 17 | 
             
            begin
         | 
| 18 18 |  | 
| 19 19 | 
             
              $DEBUG = true if ARGV.delete('-d-')
         | 
| 20 | 
            -
               | 
| 21 | 
            -
              after = nil
         | 
| 22 | 
            -
              aliases = nil
         | 
| 23 | 
            -
             | 
| 24 | 
            -
              app = Tap::App.instance
         | 
| 25 | 
            -
              env = Tap::Env.instantiate(app, Tap::Env.load_config(Tap::Env::GLOBAL_CONFIG_FILE), app.logger) do |unhandled_configs|
         | 
| 26 | 
            -
                before = unhandled_configs.delete(:before)
         | 
| 27 | 
            -
                after = unhandled_configs.delete(:after)
         | 
| 28 | 
            -
                
         | 
| 29 | 
            -
                aliases = unhandled_configs.delete(:alias)
         | 
| 30 | 
            -
                Tap::Support::Validation.validate(aliases, [Hash]) if aliases
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                unless unhandled_configs.empty?
         | 
| 33 | 
            -
                  local.log(:warn, "ignoring non-env configs: #{unhandled_configs.keys.join(',')}", Logger::DEBUG)
         | 
| 34 | 
            -
                end
         | 
| 35 | 
            -
              end
         | 
| 36 | 
            -
              
         | 
| 37 | 
            -
              # add all gems if no gems are specified (Note this is VERY SLOW ~ 1/3 the overhead for tap)
         | 
| 38 | 
            -
              if !File.exists?(Tap::Env::DEFAULT_CONFIG_FILE)
         | 
| 39 | 
            -
                env.gems = Tap::Env.known_gems(true)
         | 
| 40 | 
            -
              end
         | 
| 41 | 
            -
              
         | 
| 42 | 
            -
              tap = Tap::Env.instance_for(tap_root_dir)
         | 
| 43 | 
            -
              env.push(tap)
         | 
| 20 | 
            +
              env = Tap::Exe.instantiate
         | 
| 44 21 |  | 
| 45 22 | 
             
            rescue(Tap::Env::ConfigError)
         | 
| 46 23 | 
             
              # catch errors and exit gracefully
         | 
| @@ -55,7 +32,7 @@ end | |
| 55 32 |  | 
| 56 33 | 
             
            at_exit do
         | 
| 57 34 | 
             
              begin
         | 
| 58 | 
            -
                eval(after) if after != nil
         | 
| 35 | 
            +
                eval(env.after) if env.after != nil
         | 
| 59 36 | 
             
              rescue(Exception)
         | 
| 60 37 | 
             
                puts "Error in after script."
         | 
| 61 38 | 
             
                env.handle_error($!)
         | 
| @@ -68,7 +45,7 @@ end | |
| 68 45 | 
             
            #
         | 
| 69 46 |  | 
| 70 47 | 
             
            begin
         | 
| 71 | 
            -
              eval(before) if before != nil
         | 
| 48 | 
            +
              eval(env.before) if env.before != nil
         | 
| 72 49 | 
             
            rescue(Exception)
         | 
| 73 50 | 
             
              puts "Error in before script."
         | 
| 74 51 | 
             
              env.handle_error($!)
         | 
| @@ -81,15 +58,7 @@ end | |
| 81 58 |  | 
| 82 59 | 
             
            begin
         | 
| 83 60 | 
             
              env.activate
         | 
| 84 | 
            -
             | 
| 85 | 
            -
              command = ARGV.shift
         | 
| 86 | 
            -
              if aliases && aliases.has_key?(command)
         | 
| 87 | 
            -
                aliases[command].reverse_each {|arg| ARGV.unshift(arg)}
         | 
| 88 | 
            -
                command = ARGV.shift
         | 
| 89 | 
            -
              end
         | 
| 90 | 
            -
             | 
| 91 | 
            -
              case command  
         | 
| 92 | 
            -
              when nil, '--help'
         | 
| 61 | 
            +
              env.run do
         | 
| 93 62 | 
             
                # give some help
         | 
| 94 63 | 
             
                require 'tap/support/command_line'
         | 
| 95 64 |  | 
| @@ -98,14 +67,7 @@ begin | |
| 98 67 | 
             
                puts "available commands:"
         | 
| 99 68 | 
             
                puts env.summarize(:commands)
         | 
| 100 69 | 
             
                puts
         | 
| 101 | 
            -
                puts "version #{Tap::VERSION} -- #{Tap::WEBSITE}" | 
| 102 | 
            -
              else
         | 
| 103 | 
            -
                if path = env.search(:commands, command)
         | 
| 104 | 
            -
                  load path # run the command, if it exists
         | 
| 105 | 
            -
                else
         | 
| 106 | 
            -
                  puts "Unknown command: '#{command}'"
         | 
| 107 | 
            -
                  puts "Type 'tap help' for usage information."
         | 
| 108 | 
            -
                end
         | 
| 70 | 
            +
                puts "version #{Tap::VERSION} -- #{Tap::WEBSITE}"
         | 
| 109 71 | 
             
              end
         | 
| 110 72 | 
             
            rescue
         | 
| 111 73 | 
             
              env.handle_error($!)
         | 
    
        data/cmd/manifest.rb
    ADDED
    
    | @@ -0,0 +1,94 @@ | |
| 1 | 
            +
            # tap manifest
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # Prints information about each env.
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            options = {}
         | 
| 7 | 
            +
            OptionParser.new do |opts|
         | 
| 8 | 
            +
              
         | 
| 9 | 
            +
              opts.separator ""
         | 
| 10 | 
            +
              opts.separator "options:"
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              opts.on("-h", "--help", "Show this message") do
         | 
| 13 | 
            +
                opts.banner = cmdline.usage(__FILE__)
         | 
| 14 | 
            +
                puts opts
         | 
| 15 | 
            +
                exit
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
              
         | 
| 18 | 
            +
              opts.on("-e", "--envs_only", "Only list environments") do
         | 
| 19 | 
            +
                options[:envs_only] = true
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
              
         | 
| 22 | 
            +
              opts.on("-r", "--require FILEPATH", "Require the specified file") do |value|
         | 
| 23 | 
            +
                require value
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
              
         | 
| 26 | 
            +
            end.parse!(ARGV)
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            # Simply a method to collect and format paths for
         | 
| 29 | 
            +
            # the specified manifest.
         | 
| 30 | 
            +
            def collect_map(env, manifest)
         | 
| 31 | 
            +
              width = 10
         | 
| 32 | 
            +
              map = manifest.minimize.collect do |(key, path)|
         | 
| 33 | 
            +
                path = case path
         | 
| 34 | 
            +
                when Tap::Support::Constant then path.require_path
         | 
| 35 | 
            +
                else path
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
                
         | 
| 38 | 
            +
                width = key.length if width < key.length
         | 
| 39 | 
            +
                [key, env.root.relative_filepath(:root, path) || path]
         | 
| 40 | 
            +
              end.collect do |args|
         | 
| 41 | 
            +
                "%-#{width}s (%s)" % args
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
              
         | 
| 44 | 
            +
              map.unshift("") unless map.empty?
         | 
| 45 | 
            +
              map
         | 
| 46 | 
            +
            end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            # Collect remaining args as 
         | 
| 49 | 
            +
            env = Tap::Env.instance
         | 
| 50 | 
            +
            envs_manifest = if ARGV.empty?
         | 
| 51 | 
            +
              env.manifest(:envs, true).minimize
         | 
| 52 | 
            +
            else
         | 
| 53 | 
            +
              ARGV.collect do |name| 
         | 
| 54 | 
            +
                entry = env.find(:envs, name, false)
         | 
| 55 | 
            +
                raise "could not find an env matching: #{name}" if entry == nil
         | 
| 56 | 
            +
                entry
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
            end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            width = 10
         | 
| 61 | 
            +
            envs_manifest.each {|(env_name, e)| width = env_name.length if width < env_name.length}
         | 
| 62 | 
            +
            width += 2
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            env.each do |current|
         | 
| 65 | 
            +
              env_name, current = envs_manifest.find {|(env_name, e)| e == current }
         | 
| 66 | 
            +
              next if env_name == nil
         | 
| 67 | 
            +
              
         | 
| 68 | 
            +
              puts '-' * 80 unless options[:envs_only]
         | 
| 69 | 
            +
              puts "%-#{width}s (%s)" % [env_name + ':', current.root.root]
         | 
| 70 | 
            +
              
         | 
| 71 | 
            +
              next if options[:envs_only]
         | 
| 72 | 
            +
              
         | 
| 73 | 
            +
              manifest_keys = (Tap::Env.manifests.keys + current.manifests.keys).uniq 
         | 
| 74 | 
            +
              manifest_keys.each do |name|
         | 
| 75 | 
            +
                next if name == :envs
         | 
| 76 | 
            +
                manifest = current.manifest(name, true)
         | 
| 77 | 
            +
                next if manifest.empty?
         | 
| 78 | 
            +
                
         | 
| 79 | 
            +
                puts "  %-10s %s" % [name, collect_map(current, manifest).join("\n    ")]
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
            end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
            if ARGV.empty?
         | 
| 84 | 
            +
              puts '-' * 80
         | 
| 85 | 
            +
              puts
         | 
| 86 | 
            +
              env.recursive_each(0, nil) do |current, nesting_depth, last_env|
         | 
| 87 | 
            +
                env_name, current = envs_manifest.find {|(env_name, e)| e == current }
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                leader = nesting_depth == 0 ? "" : '|   ' * (nesting_depth - 1) + (last_env == current ? "`- " : "|- ")
         | 
| 90 | 
            +
                puts("#{leader}#{env_name}")
         | 
| 91 | 
            +
                [nesting_depth + 1, current.envs[-1]]
         | 
| 92 | 
            +
              end
         | 
| 93 | 
            +
              puts
         | 
| 94 | 
            +
            end
         | 
    
        data/cmd/run.rb
    CHANGED
    
    
    
        data/lib/tap.rb
    CHANGED
    
    | @@ -1,5 +1,3 @@ | |
| 1 | 
            -
            require 'rubygems'
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            require 'yaml'                   # expensive to load
         | 
| 4 2 | 
             
            require 'thread'
         | 
| 5 3 |  | 
| @@ -7,9 +5,6 @@ require 'thread' | |
| 7 5 | 
             
            case RUBY_VERSION
         | 
| 8 6 | 
             
            when /^1.9/
         | 
| 9 7 | 
             
              $: << File.expand_path(File.dirname(__FILE__) + "/tap/patches/ruby19")
         | 
| 10 | 
            -
              
         | 
| 11 | 
            -
              # suppresses TDoc warnings
         | 
| 12 | 
            -
              $DEBUG_RDOC ||= nil 
         | 
| 13 8 | 
             
            end
         | 
| 14 9 |  | 
| 15 10 | 
             
            $:.unshift File.expand_path(File.dirname(__FILE__))
         | 
    
        data/lib/tap/constants.rb
    CHANGED
    
    
    
        data/lib/tap/env.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 | 
            -
            require 'tap/ | 
| 1 | 
            +
            require 'tap/support/manifest'
         | 
| 2 2 | 
             
            require 'tap/support/constant'
         | 
| 3 3 | 
             
            require 'tap/support/summary'
         | 
| 4 | 
            -
            require 'tap/support/ | 
| 4 | 
            +
            require 'tap/support/gems'
         | 
| 5 5 |  | 
| 6 6 | 
             
            module Tap
         | 
| 7 7 |  | 
| @@ -12,16 +12,13 @@ module Tap | |
| 12 12 | 
             
                include Support::Configurable
         | 
| 13 13 | 
             
                include Enumerable
         | 
| 14 14 |  | 
| 15 | 
            -
                 | 
| 16 | 
            -
             | 
| 17 | 
            -
                @@manifests = {}
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                class << self  
         | 
| 15 | 
            +
                class << self
         | 
| 16 | 
            +
                  
         | 
| 20 17 | 
             
                  # Returns the active instance of Env.
         | 
| 21 18 | 
             
                  def instance
         | 
| 22 19 | 
             
                    @@instance
         | 
| 23 20 | 
             
                  end
         | 
| 24 | 
            -
             | 
| 21 | 
            +
                  
         | 
| 25 22 | 
             
                  # A hash of (path, Env instance) pairs, generated by Env#instantiate.  Used
         | 
| 26 23 | 
             
                  # to prevent infinite loops of Env dependencies by assigning a single Env
         | 
| 27 24 | 
             
                  # to a given path.
         | 
| @@ -29,6 +26,13 @@ module Tap | |
| 29 26 | 
             
                    @@instances
         | 
| 30 27 | 
             
                  end
         | 
| 31 28 |  | 
| 29 | 
            +
                  # A hash of predefined manifest classes that can be initialized
         | 
| 30 | 
            +
                  # from an env.  These classes are instantiated by instances
         | 
| 31 | 
            +
                  # of Env, as needed.
         | 
| 32 | 
            +
                  def manifests
         | 
| 33 | 
            +
                    @@manifests
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                  
         | 
| 32 36 | 
             
                  # Creates a new Env for the specified path and adds it to Env#instances, or 
         | 
| 33 37 | 
             
                  # returns the existing instance for the path.  Paths can point to an env config
         | 
| 34 38 | 
             
                  # file, or to a directory.  If a directory is provided, instantiate treats
         | 
| @@ -45,7 +49,7 @@ module Tap | |
| 45 49 | 
             
                  # The Env is initialized using configurations read from the env config file using
         | 
| 46 50 | 
             
                  # load_config, and a Root initialized to the config file directory. An instance 
         | 
| 47 51 | 
             
                  # will be initialized regardless of whether the config file or directory exists.
         | 
| 48 | 
            -
                  def instantiate(path_or_root, default_config={}, logger=nil)
         | 
| 52 | 
            +
                  def instantiate(path_or_root, default_config={}, logger=nil, &block)
         | 
| 49 53 | 
             
                    path = path_or_root.kind_of?(Root) ? path_or_root.root : path_or_root
         | 
| 50 54 | 
             
                    path = pathify(path)
         | 
| 51 55 |  | 
| @@ -55,14 +59,17 @@ module Tap | |
| 55 59 |  | 
| 56 60 | 
             
                      # note the assignment of env to instances MUST occur before
         | 
| 57 61 | 
             
                      # reconfigure to prevent infinite looping
         | 
| 58 | 
            -
                      (instances[path] =  | 
| 59 | 
            -
                        yield(unhandled_configs) if block_given?
         | 
| 60 | 
            -
                      end
         | 
| 62 | 
            +
                      (instances[path] = new({}, root, logger)).reconfigure(config, &block)
         | 
| 61 63 | 
             
                    rescue(Exception)
         | 
| 62 64 | 
             
                      raise Env::ConfigError.new($!, path)
         | 
| 63 65 | 
             
                    end
         | 
| 64 66 | 
             
                  end
         | 
| 65 67 |  | 
| 68 | 
            +
                  def instance_for(path)
         | 
| 69 | 
            +
                    path = pathify(path)
         | 
| 70 | 
            +
                    instances.has_key?(path) ? instances[path] : instantiate(path)
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                  
         | 
| 66 73 | 
             
                  def pathify(path)
         | 
| 67 74 | 
             
                    if File.directory?(path) || (!File.exists?(path) && File.extname(path) == "")
         | 
| 68 75 | 
             
                      path = File.join(path, DEFAULT_CONFIG_FILE) 
         | 
| @@ -70,41 +77,60 @@ module Tap | |
| 70 77 | 
             
                    File.expand_path(path)
         | 
| 71 78 | 
             
                  end
         | 
| 72 79 |  | 
| 73 | 
            -
                  def  | 
| 74 | 
            -
                     | 
| 75 | 
            -
                     | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
             | 
| 82 | 
            -
                     | 
| 83 | 
            -
                    
         | 
| 84 | 
            -
                    # figure the version of the gem, by default >= 0.0.0
         | 
| 85 | 
            -
                    gem_name.to_s =~ /^([^<=>]*)(.*)$/
         | 
| 86 | 
            -
                    name, version = $1.strip, $2
         | 
| 87 | 
            -
                    version = ">= 0.0.0" if version.empty?
         | 
| 88 | 
            -
                    
         | 
| 89 | 
            -
                    return nil if name.empty?
         | 
| 90 | 
            -
                    
         | 
| 91 | 
            -
                    # load the gem and get the spec
         | 
| 92 | 
            -
                    gem(name, version)
         | 
| 93 | 
            -
                    Gem.loaded_specs[name]
         | 
| 94 | 
            -
                  end
         | 
| 95 | 
            -
                  
         | 
| 96 | 
            -
                  # Returns the gem name for all installed gems with a DEFAULT_CONFIG_FILE.
         | 
| 97 | 
            -
                  # If latest==true, then only the names for the most current gem specs
         | 
| 98 | 
            -
                  # will be returned.
         | 
| 99 | 
            -
                  def known_gems(latest=true)
         | 
| 100 | 
            -
                    index = latest ?
         | 
| 101 | 
            -
                      Gem.source_index.latest_specs :
         | 
| 102 | 
            -
                      Gem.source_index.gems.collect {|(name, spec)| spec }
         | 
| 80 | 
            +
                  def manifest(name, pattern, default_paths=[], &block) # :yields: search_path
         | 
| 81 | 
            +
                    manifest_class = Class.new(Support::Manifest)
         | 
| 82 | 
            +
                    manifest_class.send(:define_method, :entries_for, &block) if block_given?
         | 
| 83 | 
            +
                    manifest_class.send(:attr_reader, :env)
         | 
| 84 | 
            +
                    manifest_class.send(:define_method, :initialize) do |env|
         | 
| 85 | 
            +
                      @env = env
         | 
| 86 | 
            +
                      search_paths = default_paths.collect {|path| env.root[path] }
         | 
| 87 | 
            +
                      search_paths += env.root.glob(:root, pattern)
         | 
| 88 | 
            +
                      super search_paths.sort_by {|p| File.basename(p) }
         | 
| 89 | 
            +
                    end
         | 
| 103 90 |  | 
| 104 | 
            -
                     | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 91 | 
            +
                    manifests[name] = manifest_class
         | 
| 92 | 
            +
                  end
         | 
| 93 | 
            +
                  
         | 
| 94 | 
            +
                  #--
         | 
| 95 | 
            +
                  # To manifest simply requires an glob_<name> method which
         | 
| 96 | 
            +
                  # yields each (key, path) pair for the manifested object in
         | 
| 97 | 
            +
                  # a predictable order. 
         | 
| 98 | 
            +
                  #
         | 
| 99 | 
            +
                  #--
         | 
| 100 | 
            +
                  # Alternate implementation would create the manifest for each individual
         | 
| 101 | 
            +
                  # env, then merge the manifests.  On the plus side, each env would then
         | 
| 102 | 
            +
                  # carry it's own slice of the manifest without having to recalculate.
         | 
| 103 | 
            +
                  # On the down side, the merging would have to occur in some separate
         | 
| 104 | 
            +
                  # method that cannot be defined here.
         | 
| 105 | 
            +
                  def path_manifest(name, paths_key, pattern, default_paths=[], &block) # :yields: search_path_root, search_path
         | 
| 106 | 
            +
                    manifest_class = Class.new(Support::Manifest)
         | 
| 107 | 
            +
                    manifest_class.send(:define_method, :entries_for, &block) if block_given?
         | 
| 108 | 
            +
                    manifest_class.send(:attr_reader, :env)
         | 
| 109 | 
            +
                    manifest_class.send(:define_method, :initialize) do |env|
         | 
| 110 | 
            +
                      @env = env
         | 
| 111 | 
            +
                      search_paths = default_paths.collect do |path| 
         | 
| 112 | 
            +
                        [env.root.root, env.root[path]]
         | 
| 113 | 
            +
                      end
         | 
| 114 | 
            +
                      
         | 
| 115 | 
            +
                      env.send(paths_key).each do |search_path_root|
         | 
| 116 | 
            +
                        env.root.glob(search_path_root, pattern).each do |search_path|
         | 
| 117 | 
            +
                          search_paths << [search_path_root, search_path]
         | 
| 118 | 
            +
                        end
         | 
| 119 | 
            +
                      end
         | 
| 120 | 
            +
                      
         | 
| 121 | 
            +
                      super search_paths.sort_by {|pr, p| File.basename(p) }
         | 
| 122 | 
            +
                    end
         | 
| 123 | 
            +
                    manifests[name] = manifest_class
         | 
| 124 | 
            +
                  end
         | 
| 125 | 
            +
                  
         | 
| 126 | 
            +
                  # Returns the gemspecs for all installed gems with a DEFAULT_TASK_FILE
         | 
| 127 | 
            +
                  # or DEFAULT_CONFIG_FILE. If latest==true, then only the specs for the 
         | 
| 128 | 
            +
                  # most current gems will be returned.
         | 
| 129 | 
            +
                  def gemspecs(latest=true)
         | 
| 130 | 
            +
                    Support::Gems.select_gems(latest) do |spec|
         | 
| 131 | 
            +
                      File.exists?(File.join(spec.full_gem_path, DEFAULT_TASK_FILE)) ||
         | 
| 132 | 
            +
                      File.exists?(File.join(spec.full_gem_path, DEFAULT_CONFIG_FILE))
         | 
| 133 | 
            +
                    end
         | 
| 108 134 | 
             
                  end
         | 
| 109 135 |  | 
| 110 136 | 
             
                  protected
         | 
| @@ -137,46 +163,21 @@ module Tap | |
| 137 163 | 
             
                      instance_variable_set(instance_variable, [*input].compact.collect {|path| root[path]}.uniq)
         | 
| 138 164 | 
             
                    end
         | 
| 139 165 | 
             
                  end
         | 
| 140 | 
            -
             | 
| 141 | 
            -
             | 
| 142 | 
            -
             | 
| 143 | 
            -
                   | 
| 144 | 
            -
             | 
| 145 | 
            -
             | 
| 146 | 
            -
                  #--
         | 
| 147 | 
            -
                  # Alternate implementation would create the manifest for each individual
         | 
| 148 | 
            -
                  # env, then merge the manifests.  On the plus side, each env would then
         | 
| 149 | 
            -
                  # carry it's own slice of the manifest without having to recalculate.
         | 
| 150 | 
            -
                  # On the down side, the merging would have to occur in some separate
         | 
| 151 | 
            -
                  # method that cannot be defined here.
         | 
| 152 | 
            -
                  def manifest(name, paths_key, pattern, &block)
         | 
| 153 | 
            -
                    return manifest(name, paths_key, pattern) do |context, path|
         | 
| 154 | 
            -
                       [[path.chomp(File.extname(path)), path]]
         | 
| 155 | 
            -
                    end unless block_given?
         | 
| 156 | 
            -
                    
         | 
| 157 | 
            -
                    glob_method = Support::Manifest.glob_method(name)
         | 
| 158 | 
            -
                    module_eval %Q{
         | 
| 159 | 
            -
                      def #{glob_method}
         | 
| 160 | 
            -
                        paths = []
         | 
| 161 | 
            -
                        self.#{paths_key}.each do |manifest_path|
         | 
| 162 | 
            -
                          root.glob(manifest_path, "#{pattern}").each do |path|
         | 
| 163 | 
            -
                            next if File.directory?(path)
         | 
| 164 | 
            -
                            paths << [manifest_path, path]
         | 
| 165 | 
            -
                          end
         | 
| 166 | 
            -
                        end
         | 
| 167 | 
            -
                        paths.sort_by {|mp, p| File.basename(p)}
         | 
| 168 | 
            -
                      end
         | 
| 169 | 
            -
                    }
         | 
| 170 | 
            -
             | 
| 171 | 
            -
                    map_method = Support::Manifest.map_method(name)
         | 
| 172 | 
            -
                    define_method(map_method, &block)
         | 
| 173 | 
            -
                    
         | 
| 174 | 
            -
                    protected glob_method, map_method
         | 
| 166 | 
            +
                end
         | 
| 167 | 
            +
                
         | 
| 168 | 
            +
                class Manifest < Support::Manifest
         | 
| 169 | 
            +
                  def initialize(env)
         | 
| 170 | 
            +
                    super([])
         | 
| 171 | 
            +
                    @entries = env.collect {|e| [e.root.root, e] }
         | 
| 175 172 | 
             
                  end
         | 
| 176 173 | 
             
                end
         | 
| 177 174 |  | 
| 175 | 
            +
                @@instance = nil
         | 
| 176 | 
            +
                @@instances = {}
         | 
| 177 | 
            +
                @@manifests = {:envs => Manifest}
         | 
| 178 | 
            +
             | 
| 178 179 | 
             
                # The global config file path
         | 
| 179 | 
            -
                GLOBAL_CONFIG_FILE = File.join( | 
| 180 | 
            +
                GLOBAL_CONFIG_FILE = File.join(Support::Gems.user_home, ".tap.yml")
         | 
| 180 181 |  | 
| 181 182 | 
             
                # The default config file path
         | 
| 182 183 | 
             
                DEFAULT_CONFIG_FILE = "tap.yml"
         | 
| @@ -204,7 +205,7 @@ module Tap | |
| 204 205 | 
             
                config_attr :gems, [] do |input|
         | 
| 205 206 | 
             
                  check_configurable
         | 
| 206 207 | 
             
                  @gems = [*input].compact.collect do |gem_name| 
         | 
| 207 | 
            -
                    spec =  | 
| 208 | 
            +
                    spec = Support::Gems.gemspec(gem_name)
         | 
| 208 209 |  | 
| 209 210 | 
             
                    case spec
         | 
| 210 211 | 
             
                    when nil then log(:warn, "unknown gem: #{gem_name}", Logger::WARN)
         | 
| @@ -224,10 +225,8 @@ module Tap | |
| 224 225 | 
             
                  end.uniq
         | 
| 225 226 | 
             
                  reset_envs
         | 
| 226 227 | 
             
                end
         | 
| 227 | 
            -
             | 
| 228 | 
            -
                # Designate load paths. | 
| 229 | 
            -
                # load_paths will be used for automatic loading of modules
         | 
| 230 | 
            -
                # through the active_support Dependencies module.
         | 
| 228 | 
            +
                
         | 
| 229 | 
            +
                # Designate load paths.
         | 
| 231 230 | 
             
                path_config :load_paths, ["lib"]
         | 
| 232 231 |  | 
| 233 232 | 
             
                # Designate paths for discovering and executing commands. 
         | 
| @@ -236,12 +235,12 @@ module Tap | |
| 236 235 | 
             
                # Designate paths for discovering generators.  
         | 
| 237 236 | 
             
                path_config :generator_paths, ["lib"]
         | 
| 238 237 |  | 
| 239 | 
            -
                 | 
| 240 | 
            -
                  next unless document = Support::Lazydoc.scan_doc(path, 'manifest')
         | 
| 238 | 
            +
                path_manifest(:tasks, :load_paths, "**/*.rb", [DEFAULT_TASK_FILE]) do |load_path, path|
         | 
| 239 | 
            +
                  next unless File.file?(path) && document = Support::Lazydoc.scan_doc(path, 'manifest')
         | 
| 241 240 |  | 
| 242 241 | 
             
                  document.const_names.collect do |const_name|
         | 
| 243 242 | 
             
                    if const_name.empty?
         | 
| 244 | 
            -
                      key = root.relative_filepath(load_path, path).chomp('.rb')
         | 
| 243 | 
            +
                      key = env.root.relative_filepath(load_path, path).chomp('.rb')
         | 
| 245 244 | 
             
                      [key, Support::Constant.new(key.camelize, path)]
         | 
| 246 245 | 
             
                    else
         | 
| 247 246 | 
             
                      [const_name.underscore, Support::Constant.new(const_name, path)]
         | 
| @@ -249,16 +248,18 @@ module Tap | |
| 249 248 | 
             
                  end
         | 
| 250 249 | 
             
                end
         | 
| 251 250 |  | 
| 252 | 
            -
                 | 
| 251 | 
            +
                path_manifest(:commands, :command_paths, "**/*.rb") do |command_path, path|
         | 
| 252 | 
            +
                  File.file?(path) ? [[path, path]] : nil
         | 
| 253 | 
            +
                end
         | 
| 253 254 |  | 
| 254 | 
            -
                 | 
| 255 | 
            +
                path_manifest(:generators, :generator_paths, '**/*_generator.rb') do |generator_path, path|
         | 
| 255 256 | 
             
                  dirname = File.dirname(path)
         | 
| 256 | 
            -
                  next unless "#{File.basename(dirname)}_generator.rb" == File.basename(path)
         | 
| 257 | 
            +
                  next unless File.file?(path) && "#{File.basename(dirname)}_generator.rb" == File.basename(path)
         | 
| 257 258 |  | 
| 258 259 | 
             
                  next unless document = Support::Lazydoc.scan_doc(path, 'generator')
         | 
| 259 260 | 
             
                  document.const_names.collect do |const_name|
         | 
| 260 261 | 
             
                    if const_name.empty?
         | 
| 261 | 
            -
                      key = root.relative_filepath( | 
| 262 | 
            +
                      key = env.root.relative_filepath(generator_path, dirname)
         | 
| 262 263 | 
             
                      [key, Support::Constant.new((key + '_generator').camelize, path)]
         | 
| 263 264 | 
             
                    else
         | 
| 264 265 | 
             
                      [const_name.underscore, Support::Constant.new(const_name, path)]
         | 
| @@ -304,7 +305,7 @@ module Tap | |
| 304 305 | 
             
                  unless env == self || envs[0] == env
         | 
| 305 306 | 
             
                    self.envs = envs.dup.unshift(env)
         | 
| 306 307 | 
             
                  end
         | 
| 307 | 
            -
                   | 
| 308 | 
            +
                  self
         | 
| 308 309 | 
             
                end
         | 
| 309 310 |  | 
| 310 311 | 
             
                # Pushes env onto envs, removing duplicates.  
         | 
| @@ -314,7 +315,7 @@ module Tap | |
| 314 315 | 
             
                    envs = self.envs.reject {|e| e == env }
         | 
| 315 316 | 
             
                    self.envs = envs.push(env)
         | 
| 316 317 | 
             
                  end
         | 
| 317 | 
            -
                   | 
| 318 | 
            +
                  self
         | 
| 318 319 | 
             
                end
         | 
| 319 320 |  | 
| 320 321 | 
             
                # Passes each nested env to the block in order, starting with self.
         | 
| @@ -327,18 +328,40 @@ module Tap | |
| 327 328 | 
             
                  envs(true).reverse_each {|e| yield(e) }
         | 
| 328 329 | 
             
                end
         | 
| 329 330 |  | 
| 331 | 
            +
                # Visits each nested env in order, starting with self, and passing
         | 
| 332 | 
            +
                # to the block the env and any arguments generated by the parent of 
         | 
| 333 | 
            +
                # the env.  The initial arguments are set when recursive_each is 
         | 
| 334 | 
            +
                # first called; subsequent arguements are the return values of the 
         | 
| 335 | 
            +
                # block.
         | 
| 336 | 
            +
                #
         | 
| 337 | 
            +
                #   e0, e1, e2, e3, e4 = ('a'..'e').collect {|name| Tap::Env.new(:name => name) }
         | 
| 338 | 
            +
                # 
         | 
| 339 | 
            +
                #   e0.push(e1).push(e2)
         | 
| 340 | 
            +
                #   e1.push(e3).push(e4)
         | 
| 341 | 
            +
                # 
         | 
| 342 | 
            +
                #   lines = []
         | 
| 343 | 
            +
                #   e0.recursive_each(0) do |env, nesting_depth|
         | 
| 344 | 
            +
                #     lines << "\n#{'..' * nesting_depth}#{env.config[:name]} (#{nesting_depth})"
         | 
| 345 | 
            +
                #     nesting_depth + 1
         | 
| 346 | 
            +
                #   end
         | 
| 347 | 
            +
                #
         | 
| 348 | 
            +
                #   lines.join
         | 
| 349 | 
            +
                #   # => %Q{
         | 
| 350 | 
            +
                #   # a (0)
         | 
| 351 | 
            +
                #   # ..b (1)
         | 
| 352 | 
            +
                #   # ....d (2)
         | 
| 353 | 
            +
                #   # ....e (2)
         | 
| 354 | 
            +
                #   # ..c (1)}
         | 
| 355 | 
            +
                #
         | 
| 356 | 
            +
                def recursive_each(*args, &block) # :yields: env, *parent_args
         | 
| 357 | 
            +
                  each_nested_env(self, [], args, &block)
         | 
| 358 | 
            +
                end
         | 
| 359 | 
            +
                
         | 
| 330 360 | 
             
                # Returns the total number of unique envs nested in self (including self).
         | 
| 331 361 | 
             
                def count
         | 
| 332 362 | 
             
                  envs(true).length
         | 
| 333 363 | 
             
                end
         | 
| 334 364 |  | 
| 335 | 
            -
                # Returns a list of arrays that receive load_paths on activate,
         | 
| 336 | 
            -
                # by default [$LOAD_PATH]. If use_dependencies == true, then
         | 
| 337 | 
            -
                # Dependencies.load_paths will also be included.
         | 
| 338 | 
            -
                def load_path_targets
         | 
| 339 | 
            -
                  [$LOAD_PATH]
         | 
| 340 | 
            -
                end
         | 
| 341 | 
            -
                
         | 
| 342 365 | 
             
                # Processes and resets the input configurations for both root
         | 
| 343 366 | 
             
                # and self. Reconfiguration consists of the following steps:
         | 
| 344 367 | 
             
                #
         | 
| @@ -412,7 +435,7 @@ module Tap | |
| 412 435 | 
             
                  return false if active?
         | 
| 413 436 |  | 
| 414 437 | 
             
                  @active = true
         | 
| 415 | 
            -
                  @@instance = self  | 
| 438 | 
            +
                  @@instance = self if @@instance == nil
         | 
| 416 439 |  | 
| 417 440 | 
             
                  # freeze array configs like load_paths
         | 
| 418 441 | 
             
                  config.each_pair do |key, value|
         | 
| @@ -426,15 +449,12 @@ module Tap | |
| 426 449 | 
             
                    env.activate
         | 
| 427 450 | 
             
                  end
         | 
| 428 451 |  | 
| 429 | 
            -
                  # add load paths | 
| 430 | 
            -
                   | 
| 431 | 
            -
                     | 
| 432 | 
            -
                      target.unshift(path)
         | 
| 433 | 
            -
                    end
         | 
| 434 | 
            -
                
         | 
| 435 | 
            -
                    target.uniq!
         | 
| 452 | 
            +
                  # add load paths
         | 
| 453 | 
            +
                  load_paths.reverse_each do |path|
         | 
| 454 | 
            +
                    $LOAD_PATH.unshift(path)
         | 
| 436 455 | 
             
                  end
         | 
| 437 456 |  | 
| 457 | 
            +
                  $LOAD_PATH.uniq!
         | 
| 438 458 | 
             
                  true
         | 
| 439 459 | 
             
                end
         | 
| 440 460 |  | 
| @@ -446,13 +466,11 @@ module Tap | |
| 446 466 | 
             
                def deactivate
         | 
| 447 467 | 
             
                  return false unless active?
         | 
| 448 468 |  | 
| 449 | 
            -
                  # remove load paths | 
| 450 | 
            -
                   | 
| 451 | 
            -
                     | 
| 452 | 
            -
                      target.delete(path)
         | 
| 453 | 
            -
                    end
         | 
| 469 | 
            +
                  # remove load paths
         | 
| 470 | 
            +
                  load_paths.each do |path|
         | 
| 471 | 
            +
                    $LOAD_PATH.delete(path)
         | 
| 454 472 | 
             
                  end
         | 
| 455 | 
            -
             | 
| 473 | 
            +
             | 
| 456 474 | 
             
                  # unfreeze array configs by duplicating
         | 
| 457 475 | 
             
                  self.config.class_config.each_pair do |key, value|
         | 
| 458 476 | 
             
                    value = send(key)
         | 
| @@ -478,57 +496,76 @@ module Tap | |
| 478 496 | 
             
                  @active
         | 
| 479 497 | 
             
                end
         | 
| 480 498 |  | 
| 481 | 
            -
                #  | 
| 482 | 
            -
                #  | 
| 483 | 
            -
                #  | 
| 484 | 
            -
                 | 
| 485 | 
            -
             | 
| 486 | 
            -
             | 
| 487 | 
            -
             | 
| 488 | 
            -
             | 
| 489 | 
            -
             | 
| 490 | 
            -
             | 
| 491 | 
            -
                   | 
| 492 | 
            -
                     | 
| 493 | 
            -
             | 
| 494 | 
            -
                     | 
| 495 | 
            -
             | 
| 496 | 
            -
                   | 
| 497 | 
            -
             | 
| 499 | 
            +
                # Returns the manifest in manifests by the specified name. Yields
         | 
| 500 | 
            +
                # each entry in the manifest to the block, if given, or simply
         | 
| 501 | 
            +
                # builds and returns the manifest. 
         | 
| 502 | 
            +
                #
         | 
| 503 | 
            +
                # If the specified manifest does not exists, the manifest class
         | 
| 504 | 
            +
                # in self.class.manifests will be instatiated with self to make
         | 
| 505 | 
            +
                # the manifest.  Raises an error if no manifest could be found
         | 
| 506 | 
            +
                # or instantiated.
         | 
| 507 | 
            +
                def manifest(name, build=false) 
         | 
| 508 | 
            +
                  manifest = manifests[name] ||= case 
         | 
| 509 | 
            +
                  when manifests_class = self.class.manifests[name]
         | 
| 510 | 
            +
                    manifests_class.new(self)
         | 
| 511 | 
            +
                  else 
         | 
| 512 | 
            +
                    raise "unknown manifest: #{name}"
         | 
| 513 | 
            +
                  end
         | 
| 514 | 
            +
                  
         | 
| 515 | 
            +
                  manifest.build if build  
         | 
| 498 516 | 
             
                  manifest
         | 
| 499 517 | 
             
                end
         | 
| 500 518 |  | 
| 501 | 
            -
                 | 
| 502 | 
            -
             | 
| 503 | 
            -
             | 
| 519 | 
            +
                # Returns the first value in the specified manifest where the key
         | 
| 520 | 
            +
                # mini-matches the input pattern.  See Tap::Root.minimal_match? 
         | 
| 521 | 
            +
                # for details on mini-matching.
         | 
| 522 | 
            +
                def find(name, pattern, value_only=true)
         | 
| 523 | 
            +
                  manifest(name).each do |key, value|
         | 
| 524 | 
            +
                    return(value_only ? value : [key, value]) if Root.minimal_match?(key, pattern)
         | 
| 504 525 | 
             
                  end
         | 
| 505 526 | 
             
                  nil
         | 
| 506 527 | 
             
                end
         | 
| 507 528 |  | 
| 508 | 
            -
                 | 
| 509 | 
            -
             | 
| 529 | 
            +
                # Like find, but searches across all envs for the matching value.
         | 
| 530 | 
            +
                # An env pattern can be provided in pattern, to select a single
         | 
| 531 | 
            +
                # env to search.
         | 
| 532 | 
            +
                #
         | 
| 533 | 
            +
                # The :envs manifest cannot be searched; use find instead.
         | 
| 534 | 
            +
                def search(name, pattern, value_only=true)
         | 
| 535 | 
            +
                  if name == :envs
         | 
| 536 | 
            +
                    raise ArgumentError, "cannot search the :envs manifest; use find instead" 
         | 
| 537 | 
            +
                  end
         | 
| 510 538 |  | 
| 511 539 | 
             
                  envs = case pattern
         | 
| 512 540 | 
             
                  when /^(.*):([^:]+)$/
         | 
| 513 541 | 
             
                    env_pattern = $1
         | 
| 514 542 | 
             
                    pattern = $2
         | 
| 515 | 
            -
                    find(:envs, env_pattern) | 
| 543 | 
            +
                    find(:envs, env_pattern)
         | 
| 516 544 | 
             
                  else manifest(:envs).values
         | 
| 517 545 | 
             
                  end
         | 
| 518 546 |  | 
| 519 547 | 
             
                  envs.each do |env|
         | 
| 520 | 
            -
                    if result = env.find(name, pattern)
         | 
| 548 | 
            +
                    if result = env.find(name, pattern, value_only)
         | 
| 521 549 | 
             
                      return result
         | 
| 522 550 | 
             
                    end
         | 
| 523 | 
            -
                  end
         | 
| 551 | 
            +
                  end if envs
         | 
| 524 552 |  | 
| 525 553 | 
             
                  nil
         | 
| 526 554 | 
             
                end
         | 
| 527 555 |  | 
| 556 | 
            +
                def constantize(name, *patterns)
         | 
| 557 | 
            +
                  patterns.collect do |pattern| 
         | 
| 558 | 
            +
                    case const = search(name, pattern)
         | 
| 559 | 
            +
                    when Support::Constant then const.constantize
         | 
| 560 | 
            +
                    else raise "could not constantize: #{pattern} (#{name})" 
         | 
| 561 | 
            +
                    end
         | 
| 562 | 
            +
                  end
         | 
| 563 | 
            +
                end
         | 
| 564 | 
            +
                
         | 
| 528 565 | 
             
                def summary(name)
         | 
| 529 566 | 
             
                  summary = Support::Summary.new
         | 
| 530 | 
            -
                  manifest(:envs). | 
| 531 | 
            -
                   summary.add(key, env, env.manifest(name). | 
| 567 | 
            +
                  manifest(:envs, true).minimize.each do |(key, env)|
         | 
| 568 | 
            +
                   summary.add(key, env, env.manifest(name, true).minimize)
         | 
| 532 569 | 
             
                  end
         | 
| 533 570 | 
             
                  summary
         | 
| 534 571 | 
             
                end
         | 
| @@ -546,51 +583,9 @@ module Tap | |
| 546 583 | 
             
                def to_s
         | 
| 547 584 | 
             
                  inspect(true)
         | 
| 548 585 | 
             
                end
         | 
| 549 | 
            -
             | 
| 550 | 
            -
                #--
         | 
| 551 | 
            -
                # Under construction
         | 
| 552 | 
            -
                #++
         | 
| 553 | 
            -
                
         | 
| 554 | 
            -
                def handle_error(err)
         | 
| 555 | 
            -
                  case
         | 
| 556 | 
            -
                  when $DEBUG
         | 
| 557 | 
            -
                    puts err.message
         | 
| 558 | 
            -
                    puts
         | 
| 559 | 
            -
                    puts err.backtrace
         | 
| 560 | 
            -
                  else puts err.message
         | 
| 561 | 
            -
                  end
         | 
| 562 | 
            -
                end
         | 
| 563 586 |  | 
| 564 587 | 
             
                protected
         | 
| 565 588 |  | 
| 566 | 
            -
                # Iterates over each nested env, yielding the root path and env.
         | 
| 567 | 
            -
                # This is the manifest method for envs.
         | 
| 568 | 
            -
                def manifest_glob_envs
         | 
| 569 | 
            -
                  collect {|env| [env.root.root, env] }.sort_by {|root, env| File.basename(root) }
         | 
| 570 | 
            -
                end
         | 
| 571 | 
            -
                
         | 
| 572 | 
            -
                def manifest_map(context, path)
         | 
| 573 | 
            -
                  [[context, path]]
         | 
| 574 | 
            -
                end
         | 
| 575 | 
            -
                
         | 
| 576 | 
            -
                alias default_manifest_glob_tasks manifest_glob_tasks
         | 
| 577 | 
            -
                
         | 
| 578 | 
            -
                def manifest_glob_tasks
         | 
| 579 | 
            -
                  paths = default_manifest_glob_tasks
         | 
| 580 | 
            -
                  
         | 
| 581 | 
            -
                  # very odd behaviors --
         | 
| 582 | 
            -
                  # * OS X is case-insensitive, apparently.  Tapfile.rb and tapfile.rb are the same.
         | 
| 583 | 
            -
                  # * require 'tapfile' does not work
         | 
| 584 | 
            -
                  # * require 'tapfile.rb' works
         | 
| 585 | 
            -
                  # * load 'tapfile' works
         | 
| 586 | 
            -
                  #
         | 
| 587 | 
            -
                  root.glob(:root, DEFAULT_TASK_FILE).each do |path|
         | 
| 588 | 
            -
                    next if File.directory?(path)
         | 
| 589 | 
            -
                    paths.unshift [root.root, path]
         | 
| 590 | 
            -
                  end
         | 
| 591 | 
            -
                  paths
         | 
| 592 | 
            -
                end
         | 
| 593 | 
            -
                
         | 
| 594 589 | 
             
                # Raises an error if self is already active (and hence, configurations
         | 
| 595 590 | 
             
                # should not be modified)
         | 
| 596 591 | 
             
                def check_configurable
         | 
| @@ -619,7 +614,20 @@ module Tap | |
| 619 614 |  | 
| 620 615 | 
             
                  target
         | 
| 621 616 | 
             
                end
         | 
| 622 | 
            -
             | 
| 617 | 
            +
                
         | 
| 618 | 
            +
                private
         | 
| 619 | 
            +
                
         | 
| 620 | 
            +
                def each_nested_env(env, visited, args, &block)
         | 
| 621 | 
            +
                  return if visited.include?(env)
         | 
| 622 | 
            +
                  
         | 
| 623 | 
            +
                  visited << env
         | 
| 624 | 
            +
                  next_args = yield(env, *args)
         | 
| 625 | 
            +
                  next_args = [] if next_args == nil
         | 
| 626 | 
            +
                  env.envs.each do |nested_env|
         | 
| 627 | 
            +
                    each_nested_env(nested_env, visited, next_args, &block)
         | 
| 628 | 
            +
                  end
         | 
| 629 | 
            +
                end
         | 
| 630 | 
            +
                
         | 
| 623 631 | 
             
                # Raised when there is a Env-level configuration error.
         | 
| 624 632 | 
             
                class ConfigError < StandardError
         | 
| 625 633 | 
             
                  attr_reader :original_error, :env_path
         |