lib/tap/env.rb in tap-0.17.1 vs lib/tap/env.rb in tap-0.18.0

- old
+ new

@@ -1,8 +1,8 @@ require 'tap/root' require 'tap/env/manifest' -require 'tap/support/templater' +require 'tap/templater' autoload(:YAML, 'yaml') module Tap # Env abstracts an execution environment that spans many directories. class Env @@ -63,27 +63,21 @@ rescue(Exception) raise ConfigError.new($!, path) end end - def scan(load_path, pattern='**/*.rb') + def scan_dir(load_path, pattern='**/*.rb') Dir.chdir(load_path) do Dir.glob(pattern).each do |require_path| next unless File.file?(require_path) default_const_name = require_path.chomp('.rb').camelize # note: the default const name has to be set here to allow for implicit - # constant attributes (because a dir is needed to figure the relative path). - # A conflict could arise if the same path is globed from two different - # dirs... no surefire solution. - document = Lazydoc[require_path] - case document.default_const_name - when nil then document.default_const_name = default_const_name - when default_const_name - else raise "found a conflicting default const name" - end + # constant attributes. An error can arise if the same path is globed + # from two different dirs... no surefire solution. + Lazydoc[require_path].default_const_name = default_const_name # scan for constants Lazydoc::Document.scan(File.read(require_path)) do |const_name, type, comment| const_name = default_const_name if const_name.empty? constant = Constant.new(const_name, require_path, comment) @@ -98,10 +92,31 @@ ############################################################### end end end end + + def scan(path, key='[a-z_]+') + Lazydoc::Document.scan(File.read(path), key) do |const_name, type, comment| + if const_name.empty? + unless const_name = Lazydoc[path].default_const_name + raise "could not determine a constant name for #{type} in: #{path.inspect}" + end + end + + constant = Constant.new(const_name, path, comment) + yield(type, constant) + + ############################################################### + # [depreciated] manifest as a task key will be removed at 1.0 + if type == 'manifest' + warn "depreciation: ::task should be used instead of ::manifest as a resource key (#{require_path})" + yield('task', constant) + end + ############################################################### + end + end end self.instance = nil include Enumerable include Configurable @@ -439,13 +454,12 @@ registries[minikey] ||= begin registry = {} load_paths.each do |load_path| next unless File.directory?(load_path) - Env.scan(load_path) do |type, constant| - entries = registry[type.to_sym] ||= [] - entries << constant + Env.scan_dir(load_path) do |type, constant| + (registry[type.to_sym] ||= []) << constant end end registry end @@ -466,10 +480,19 @@ end builders[type] = block end + #-- + # Potential bug, constants can be added twice. + def scan(path, key='[a-z_]+') + registry = self.registry + Env.scan(path, key) do |type, constant| + (registry[type.to_sym] ||= []) << constant + end + end + def manifest(type) # :yields: env type = type.to_sym registry[type] ||= begin builder = builders[type] @@ -486,13 +509,15 @@ def reset manifests.clear registries.clear end - #-- - # Environment-seek - def eeek(type, key) + # Searches across each for the first registered object minimatching key. A + # single env can be specified by using a compound key like 'env_key:key'. + # + # Returns nil if no matching object is found. + def seek(type, key, value_only=true) key =~ COMPOUND_KEY envs = if $2 # compound key, match for env key = $2 [minimatch($1)].compact @@ -502,25 +527,28 @@ end # traverse envs looking for the first # manifest entry matching key envs.each do |env| - if result = env.manifest(type).minimatch(key) - return [env, result] + if value = env.manifest(type).minimatch(key) + return value_only ? value : [env, value] end end nil end - # Searches across each for the first registered object minimatching key. A - # single env can be specified by using a compound key like 'env_key:key'. - # - # Returns nil if no matching object is found. - def seek(type, key, &block) # :yields: env, key - env, result = eeek(type, key, &block) - result + def reverse_seek(type, key_only=true, &block) + each do |env| + manifest = env.manifest(type) + if value = manifest.find(&block) + key = manifest.minihash(true)[value] + return key_only ? key : "#{minihash(true)[env]}:#{key}" + end + end + + nil end # All templaters are yielded to the block before any are built. This # allows globals to be determined for all environments. def inspect(template=nil, globals={}, filename=nil) # :yields: templater, globals @@ -528,10 +556,10 @@ return "#<#{self.class}:#{object_id} root='#{root.root}'>" end env_keys = minihash(true) collect do |env| - templater = Support::Templater.new(template, :env => env, :env_key => env_keys[env]) + templater = Templater.new(template, :env => env, :env_key => env_keys[env]) yield(templater, globals) if block_given? templater end.collect! do |templater| templater.build(globals, filename) end.join \ No newline at end of file