tap 0.12.4 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. data/History +34 -0
  2. data/README +62 -41
  3. data/bin/tap +36 -40
  4. data/cmd/console.rb +14 -6
  5. data/cmd/manifest.rb +62 -58
  6. data/cmd/run.rb +49 -31
  7. data/doc/API +84 -0
  8. data/doc/Class Reference +83 -115
  9. data/doc/Examples/Command Line +36 -0
  10. data/doc/Examples/Workflow +40 -0
  11. data/lib/tap/app.rb +293 -214
  12. data/lib/tap/app/node.rb +43 -0
  13. data/lib/tap/app/queue.rb +77 -0
  14. data/lib/tap/app/stack.rb +16 -0
  15. data/lib/tap/app/state.rb +22 -0
  16. data/lib/tap/constants.rb +2 -2
  17. data/lib/tap/env.rb +400 -314
  18. data/lib/tap/env/constant.rb +227 -0
  19. data/lib/tap/env/gems.rb +63 -0
  20. data/lib/tap/env/manifest.rb +89 -0
  21. data/lib/tap/env/minimap.rb +292 -0
  22. data/lib/tap/{support → env}/string_ext.rb +2 -2
  23. data/lib/tap/exe.rb +113 -125
  24. data/lib/tap/join.rb +175 -0
  25. data/lib/tap/joins.rb +9 -0
  26. data/lib/tap/joins/switch.rb +44 -0
  27. data/lib/tap/joins/sync.rb +99 -0
  28. data/lib/tap/root.rb +100 -491
  29. data/lib/tap/root/utils.rb +220 -0
  30. data/lib/tap/{support → root}/versions.rb +31 -29
  31. data/lib/tap/schema.rb +248 -0
  32. data/lib/tap/schema/parser.rb +413 -0
  33. data/lib/tap/schema/utils.rb +82 -0
  34. data/lib/tap/support/intern.rb +19 -6
  35. data/lib/tap/support/templater.rb +8 -3
  36. data/lib/tap/task.rb +175 -171
  37. data/lib/tap/tasks/dump.rb +58 -0
  38. data/lib/tap/tasks/load.rb +62 -0
  39. metadata +30 -73
  40. data/cmd/destroy.rb +0 -27
  41. data/cmd/generate.rb +0 -27
  42. data/doc/Command Reference +0 -105
  43. data/doc/Syntax Reference +0 -234
  44. data/doc/Tutorial +0 -348
  45. data/lib/tap/dump.rb +0 -142
  46. data/lib/tap/file_task.rb +0 -384
  47. data/lib/tap/generator/arguments.rb +0 -13
  48. data/lib/tap/generator/base.rb +0 -176
  49. data/lib/tap/generator/destroy.rb +0 -60
  50. data/lib/tap/generator/generate.rb +0 -93
  51. data/lib/tap/generator/generators/command/command_generator.rb +0 -21
  52. data/lib/tap/generator/generators/command/templates/command.erb +0 -32
  53. data/lib/tap/generator/generators/config/config_generator.rb +0 -98
  54. data/lib/tap/generator/generators/generator/generator_generator.rb +0 -37
  55. data/lib/tap/generator/generators/generator/templates/task.erb +0 -27
  56. data/lib/tap/generator/generators/generator/templates/test.erb +0 -26
  57. data/lib/tap/generator/generators/root/root_generator.rb +0 -84
  58. data/lib/tap/generator/generators/root/templates/MIT-LICENSE +0 -22
  59. data/lib/tap/generator/generators/root/templates/README +0 -14
  60. data/lib/tap/generator/generators/root/templates/Rakefile +0 -84
  61. data/lib/tap/generator/generators/root/templates/Rapfile +0 -11
  62. data/lib/tap/generator/generators/root/templates/gemspec +0 -27
  63. data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +0 -3
  64. data/lib/tap/generator/generators/task/task_generator.rb +0 -25
  65. data/lib/tap/generator/generators/task/templates/task.erb +0 -14
  66. data/lib/tap/generator/generators/task/templates/test.erb +0 -19
  67. data/lib/tap/generator/manifest.rb +0 -20
  68. data/lib/tap/generator/preview.rb +0 -69
  69. data/lib/tap/load.rb +0 -64
  70. data/lib/tap/spec.rb +0 -41
  71. data/lib/tap/support/aggregator.rb +0 -65
  72. data/lib/tap/support/audit.rb +0 -333
  73. data/lib/tap/support/constant.rb +0 -143
  74. data/lib/tap/support/constant_manifest.rb +0 -126
  75. data/lib/tap/support/dependencies.rb +0 -54
  76. data/lib/tap/support/dependency.rb +0 -44
  77. data/lib/tap/support/executable.rb +0 -198
  78. data/lib/tap/support/executable_queue.rb +0 -125
  79. data/lib/tap/support/gems.rb +0 -43
  80. data/lib/tap/support/join.rb +0 -144
  81. data/lib/tap/support/joins.rb +0 -12
  82. data/lib/tap/support/joins/switch.rb +0 -27
  83. data/lib/tap/support/joins/sync_merge.rb +0 -38
  84. data/lib/tap/support/manifest.rb +0 -171
  85. data/lib/tap/support/minimap.rb +0 -90
  86. data/lib/tap/support/node.rb +0 -176
  87. data/lib/tap/support/parser.rb +0 -450
  88. data/lib/tap/support/schema.rb +0 -385
  89. data/lib/tap/support/shell_utils.rb +0 -67
  90. data/lib/tap/test.rb +0 -77
  91. data/lib/tap/test/assertions.rb +0 -38
  92. data/lib/tap/test/env_vars.rb +0 -29
  93. data/lib/tap/test/extensions.rb +0 -73
  94. data/lib/tap/test/file_test.rb +0 -362
  95. data/lib/tap/test/file_test_class.rb +0 -15
  96. data/lib/tap/test/regexp_escape.rb +0 -87
  97. data/lib/tap/test/script_test.rb +0 -46
  98. data/lib/tap/test/script_tester.rb +0 -115
  99. data/lib/tap/test/subset_test.rb +0 -260
  100. data/lib/tap/test/subset_test_class.rb +0 -99
  101. data/lib/tap/test/tap_test.rb +0 -109
  102. data/lib/tap/test/utils.rb +0 -231
@@ -1,43 +0,0 @@
1
- require 'rubygems'
2
-
3
- module Tap
4
- module Support
5
-
6
- # Methods for working with {RubyGems}[http://www.rubygems.org/]
7
- # and other gems frequently used by Tap.
8
- module Gems
9
- module_function
10
-
11
- # Returns the gemspec for the specified gem. A gem version
12
- # can be specified in the name, like 'gem >= 1.2'. The gem
13
- # will be activated using +gem+ if necessary.
14
- def gemspec(gem_name)
15
- return gem_name if gem_name.kind_of?(Gem::Specification)
16
-
17
- # figure the version of the gem, by default >= 0.0.0
18
- gem_name.to_s =~ /^([^<=>]*)(.*)$/
19
- name, version = $1.strip, $2
20
- version = ">= 0.0.0" if version.empty?
21
-
22
- return nil if name.empty?
23
-
24
- # load the gem and get the spec
25
- gem(name, version)
26
- Gem.loaded_specs[name]
27
- end
28
-
29
- # Selects gem specs for which the block returns true. If
30
- # latest is specified, only the latest version of each
31
- # gem will be passed to the block.
32
- def select_gems(latest=true)
33
- index = latest ?
34
- Gem.source_index.latest_specs :
35
- Gem.source_index.gems.collect {|(name, spec)| spec }
36
-
37
- index.select do |spec|
38
- yield(spec)
39
- end.sort
40
- end
41
- end
42
- end
43
- end
@@ -1,144 +0,0 @@
1
- require 'configurable'
2
-
3
- module Tap
4
- module Support
5
-
6
- # Joins create on_complete blocks which link together tasks (or more
7
- # generally, Executable objects) into workflows. Joins support a
8
- # variety of configurations which affect how one task passes inputs
9
- # to subsequent tasks.
10
- #
11
- class Join
12
- include Configurable
13
-
14
- # Causes the join to iterate the results
15
- # of the source when enquing the targets.
16
- config :iterate, false, :short => 'i', &c.boolean
17
-
18
- # Causes joins to splat ('*') the results
19
- # of the source when enquing the targets.
20
- config :splat, false, :short => 's', &c.boolean
21
-
22
- # Causes the targets to be enqued rather
23
- # than executed immediately.
24
- config :stack, false, :short => 'k', &c.boolean
25
-
26
- # Aggregates results and enques them to the target
27
- # in a trailing round.
28
- config :aggregate, false, :short => 'a', &c.boolean
29
-
30
- # Initializes a new join with the specified configuration.
31
- def initialize(config={})
32
- initialize_config(config)
33
- end
34
-
35
- # The name of the join, as a symbol. By default name is the basename of
36
- # the underscored class name.
37
- def name
38
- File.basename(self.class.to_s.underscore).to_sym
39
- end
40
-
41
- # Creates a join that passes the results of each input to each output.
42
- def join(inputs, outputs)
43
- inputs.each do |input|
44
- input.on_complete do |_result|
45
- outputs.each do |output|
46
- yield(_result) if block_given?
47
- enq(output, _result)
48
- end
49
- end
50
- end
51
- end
52
-
53
- # A hash of the configurations set to true.
54
- def options
55
- opts = config.to_hash
56
- opts.delete_if {|key, value| value == false }
57
- opts
58
- end
59
-
60
- # Returns a string like: "#<Join:object_id>"
61
- def inspect
62
- "#<Join:#{object_id}>"
63
- end
64
-
65
- protected
66
-
67
- # Enques the executable with the results, respecting the
68
- # configuration for self.
69
- #
70
- # true false
71
- # iterate _results are iterated _results are enqued directly
72
- # splat _results are splat enqued _results are enqued directly
73
- # stack the executable is enqued the executable is executed
74
- #
75
- def enq(executable, *_results)
76
- case
77
- when aggregate
78
-
79
- case
80
- when iterate, splat, stack
81
- raise "iterate, splat, or stack and aggregate"
82
- else collect(executable, _results)
83
- end
84
-
85
- else
86
- unpack(_results) do |_result|
87
- case
88
- when stack
89
- executable.enq(*_result)
90
- else
91
- executable._execute(*_result)
92
- end
93
- end
94
- end
95
- end
96
-
97
- # returns the aggregator for self
98
- def aggregator # :nodoc:
99
- @aggregator ||= {}
100
- end
101
-
102
- # helper method to aggregate audited results
103
- def collect(executable, inputs) # :nodoc:
104
- queue = executable.app.queue
105
- entry = aggregator[executable]
106
-
107
- queue.synchronize do
108
- unless queue.has?(entry)
109
- entry = aggregator[executable] = [executable, []]
110
- queue.concat [entry]
111
- end
112
- entry[1].concat(inputs)
113
- end
114
- end
115
-
116
- # helper method to splat/iterate audited results
117
- def unpack(_results) # :nodoc:
118
- case
119
- when iterate && splat
120
- raise "splat and iterate"
121
- when iterate
122
- _splat(_results).each {|_result| yield(_result) }
123
- when splat
124
- yield(_splat(_results))
125
- else
126
- yield(_results)
127
- end
128
- end
129
-
130
- # helper to splat audits
131
- def _splat(_results) # :nodoc:
132
- array = []
133
- _results.each do |_result|
134
- unless _result.kind_of?(Audit)
135
- _result = Audit.new(nil, _result)
136
- end
137
-
138
- array.concat(_result.splat)
139
- end
140
- array
141
- end
142
- end
143
- end
144
- end
@@ -1,12 +0,0 @@
1
- require 'tap/support/join'
2
-
3
- module Tap
4
- module Support
5
-
6
- # A module of the standard Join classes supported by Tap.
7
- module Joins
8
- autoload(:SyncMerge, 'tap/support/joins/sync_merge')
9
- autoload(:Switch, 'tap/support/joins/switch')
10
- end
11
- end
12
- end
@@ -1,27 +0,0 @@
1
- module Tap
2
- module Support
3
- module Joins
4
-
5
- # A Switch join allows a block to determine which output from an array
6
- # of outputs will receive the results of the input.
7
- class Switch < Join
8
- def join(inputs, outputs)
9
- inputs.each do |input|
10
- input.on_complete do |_result|
11
- if index = yield(_result)
12
- unless output = outputs[index]
13
- raise "no switch target for index: #{index}"
14
- end
15
-
16
- enq(output, _result)
17
- else
18
- input.app.aggregator.store(_result)
19
- end
20
- end
21
- end
22
- end
23
- end
24
-
25
- end
26
- end
27
- end
@@ -1,38 +0,0 @@
1
- module Tap
2
- module Support
3
- module Joins
4
-
5
- # SyncMerge passes the collected results of the inputs to the outputs. The
6
- # results will not be passed until results from all of the inputs are
7
- # available; results are passed in one group. Similarly, a collision
8
- # results if a single input completes twice before the group completes as
9
- # a whole.
10
- class SyncMerge < Join
11
-
12
- def join(inputs, outputs)
13
- results = Array.new(inputs.length)
14
-
15
- inputs.each do |input|
16
- input.on_complete do |_result|
17
- index = inputs.index(_result.key)
18
-
19
- unless results[index] == nil
20
- raise "sync_merge collision... already got a result for #{inputs[index]}"
21
- end
22
- results[index] = _result
23
-
24
- unless results.include?(nil)
25
- yield(*results) if block_given?
26
- outputs.each {|output| enq(output, *results) }
27
-
28
- # reset the results array
29
- results.collect! {|i| nil }
30
- end
31
- end
32
- end
33
- end
34
-
35
- end
36
- end
37
- end
38
- end
@@ -1,171 +0,0 @@
1
- require 'tap/support/minimap'
2
- require 'tap/support/intern'
3
-
4
- module Tap
5
- module Support
6
-
7
- # Stores an array of paths and makes them available for lookup by
8
- # minipath. Manifests may be bound to a Tap::Env, allowing searches
9
- # across a full environment (including nested environments).
10
- #
11
- # Manifest has a number of hooks used by subclasses like
12
- # ConstantManifest to lazily add entries as needed.
13
- class Manifest
14
- class << self
15
-
16
- # Interns a new manifest, overriding the minikey
17
- # method with the block (the minikey method converts
18
- # entries to the path used during minimap and
19
- # minimatch lookup, see Minimap).
20
- def intern(*args, &block)
21
- instance = new(*args)
22
- if block_given?
23
- instance.extend Support::Intern(:minikey)
24
- instance.minikey_block = block
25
- end
26
- instance
27
- end
28
- end
29
-
30
- include Enumerable
31
- include Minimap
32
-
33
- # Matches a compound manifest search key. After the match,
34
- # if the key is compound then:
35
- #
36
- # $1:: env_key
37
- # $4:: key
38
- #
39
- # If the key is not compound, $4 is nil and $1 is the key.
40
- SEARCH_REGEXP = /^(([A-z]:)?.*?)(:(.*))?$/
41
-
42
- # An array entries in self.
43
- attr_reader :entries
44
-
45
- # The bound Tap::Env, or nil.
46
- attr_reader :env
47
-
48
- # The reader on Tap::Env accessing manifests of the
49
- # same type as self. reader is set during bind.
50
- attr_reader :reader
51
-
52
- # Initializes a new, unbound Manifest.
53
- def initialize(entries=[])
54
- @entries = entries
55
- @env = nil
56
- @reader = nil
57
- end
58
-
59
- # Binds self to an env and reader. The manifests returned by env.reader
60
- # will be used during traversal methods like search. Raises an error if
61
- # env does not respond to reader; returns self.
62
- def bind(env, reader)
63
- if env == nil
64
- raise ArgumentError, "env may not be nil"
65
- end
66
-
67
- unless env.respond_to?(reader)
68
- raise ArgumentError, "env does not respond to #{reader}"
69
- end
70
-
71
- @env = env
72
- @reader = reader
73
- self
74
- end
75
-
76
- # Unbinds self from env. Returns self.
77
- def unbind
78
- @env = nil
79
- @reader = nil
80
- self
81
- end
82
-
83
- # True if the env and reader have been set.
84
- def bound?
85
- @env != nil && @reader != nil
86
- end
87
-
88
- # A hook for dynamically building entries. By default build simply
89
- # returns self
90
- def build
91
- self
92
- end
93
-
94
- # A hook to flag when self is built. By default built? returns true.
95
- def built?
96
- true
97
- end
98
-
99
- # A hook to reset a build. By default reset simply returns self.
100
- def reset
101
- self
102
- end
103
-
104
- # True if entries are empty.
105
- def empty?
106
- entries.empty?
107
- end
108
-
109
- # Iterates over each entry entry in self.
110
- def each
111
- entries.each {|entry| yield(entry) }
112
- end
113
-
114
- # Alias for Minimap#minimatch.
115
- def [](key)
116
- minimatch(key)
117
- end
118
-
119
- # Search across env.each for the first entry minimatching key.
120
- # A single env can be specified by using a compound key like
121
- # 'env_key:key'. Returns nil if no matching entry is found.
122
- #
123
- # Search raises an error unless bound?
124
- def search(key)
125
- raise "cannot search unless bound" unless bound?
126
-
127
- key =~ SEARCH_REGEXP
128
- envs = if $4 != nil
129
- # compound key, match for env
130
- key = $4
131
- [env.minimatch($1)].compact
132
- else
133
- # not a compound key, search all
134
- # envs by iterating env itself
135
- env
136
- end
137
-
138
- # traverse envs looking for the first
139
- # manifest entry matching key
140
- envs.each do |env|
141
- if result = env.send(reader).minimatch(key)
142
- return result
143
- end
144
- end
145
-
146
- nil
147
- end
148
-
149
- def inspect(traverse=true)
150
- if traverse && bound?
151
- lines = []
152
- env.each do |env|
153
- manifest = env.send(reader).build
154
- next if manifest.empty?
155
-
156
- lines << "== #{env.root.root}"
157
- manifest.minimap.each do |mini, value|
158
- lines << " #{mini}: #{value.inspect}"
159
- end
160
- end
161
- return lines.join("\n")
162
- end
163
-
164
- lines = minimap.collect do |mini, value|
165
- " #{mini}: #{value.inspect}"
166
- end
167
- "#{self.class}:#{object_id} (#{bound? ? env.root.root : ''})\n#{lines.join("\n")}"
168
- end
169
- end
170
- end
171
- end
@@ -1,90 +0,0 @@
1
- require 'tap/root'
2
-
3
- module Tap
4
- module Support
5
-
6
- # Minimap adds minimization and search methods to an array of paths (see
7
- # Tap::Root.minimize and Tap::Root.minimal_match?).
8
- #
9
- # paths = %w{
10
- # path/to/file-0.1.0.txt
11
- # path/to/file-0.2.0.txt
12
- # path/to/another_file.txt
13
- # }
14
- # paths.extend Minimap
15
- #
16
- # paths.minimatch('file') # => 'path/to/file-0.1.0.txt'
17
- # paths.minimatch('file-0.2.0') # => 'path/to/file-0.2.0.txt'
18
- # paths.minimatch('another_file') # => 'path/to/another_file.txt'
19
- #
20
- # More generally, Minimap may extend any object responding to each.
21
- # Override the minikey method to convert objects into paths.
22
- #
23
- # class ConstantMap < Array
24
- # include Minimap
25
- #
26
- # def minikey(const)
27
- # const.underscore
28
- # end
29
- # end
30
- #
31
- # constants = ConstantMap[Tap::Support::Minimap Tap::Root]
32
- # constants.minimatch('root') # => Tap::Root
33
- # constants.minimatch('minimap') # => Tap::Support::Minimap
34
- #
35
- module Minimap
36
-
37
- # Provides a minimized map of the entries using keys provided minikey.
38
- #
39
- # paths = %w{
40
- # path/to/file-0.1.0.txt
41
- # path/to/file-0.2.0.txt
42
- # path/to/another_file.txt
43
- # }.extend Minimap
44
- #
45
- # paths.minimap
46
- # # => [
47
- # # ['file-0.1.0', 'path/to/file-0.1.0.txt'],
48
- # # ['file-0.2.0', 'path/to/file-0.2.0.txt'],
49
- # # ['another_file','path/to/another_file.txt']]
50
- #
51
- def minimap
52
- hash = {}
53
- map = []
54
- each {|entry| map << (hash[minikey(entry)] = [entry]) }
55
- Tap::Root.minimize(hash.keys) do |key, mini_key|
56
- hash[key].unshift mini_key
57
- end
58
-
59
- map
60
- end
61
-
62
- # Returns the first entry whose minikey mini-matches the input, or nil if
63
- # no such entry exists.
64
- #
65
- # paths = %w{
66
- # path/to/file-0.1.0.txt
67
- # path/to/file-0.2.0.txt
68
- # path/to/another_file.txt
69
- # }.extend Minimap
70
- #
71
- # paths.minimatch('file-0.2.0') # => 'path/to/file-0.2.0.txt'
72
- # paths.minimatch('file-0.3.0') # => nil
73
- #
74
- def minimatch(key)
75
- each do |entry|
76
- return entry if Tap::Root.minimal_match?(minikey(entry), key)
77
- end
78
- nil
79
- end
80
-
81
- protected
82
-
83
- # A hook to convert a non-path entry into a path for minimap and
84
- # minimatch. Returns the entry by default.
85
- def minikey(entry)
86
- entry
87
- end
88
- end
89
- end
90
- end