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
|