tap 0.12.4 → 0.17.0

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.
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