tap 0.12.0 → 0.12.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History +8 -0
- data/README +1 -0
- data/lib/tap/tasks/core_dump.rb +57 -0
- data/lib/tap/tasks/dump.rb +115 -60
- data/lib/tap/tasks/load.rb +6 -93
- metadata +3 -2
data/History
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 0.12.1 / 2009-02-18
|
2
|
+
|
3
|
+
Maintenance release with updates to Dump and Load tasks.
|
4
|
+
|
5
|
+
* refactored Dump as CoreDump
|
6
|
+
* implemented a simple yaml Dump
|
7
|
+
* simplified Load
|
8
|
+
|
1
9
|
== 0.12.0 / 2009-02-17
|
2
10
|
|
3
11
|
As of the 0.12.0 release, Tap is distributed as several independent modules
|
data/README
CHANGED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Tap
|
2
|
+
module Tasks
|
3
|
+
# :startdoc::manifest dumps the application
|
4
|
+
#
|
5
|
+
# A dump task to print the application data to a file or IO. Currently the
|
6
|
+
# dump result is only useful for viewing results. In the future the core
|
7
|
+
# dump will be reloadable so a terminated app may restart execution.
|
8
|
+
#
|
9
|
+
# A core dump may be used in a terminal round to capture all the unhandled
|
10
|
+
# results from previous rounds; if no filepath is specified, the results
|
11
|
+
# are printed to stdout.
|
12
|
+
#
|
13
|
+
# % tap run -- [tasks] --+ core_dump FILEPATH
|
14
|
+
#
|
15
|
+
class CoreDump < Tap::FileTask
|
16
|
+
|
17
|
+
config :date, true, &c.switch # include a date
|
18
|
+
config :date_format, '%Y-%m-%d %H:%M:%S' # the date format
|
19
|
+
config :info, true, &c.switch # dump the app state information
|
20
|
+
config :aggregator, true, &c.switch # dump aggregator results
|
21
|
+
config :audit, true, &c.switch # include the audit trails with results
|
22
|
+
|
23
|
+
def process(target=$stdout)
|
24
|
+
case target
|
25
|
+
when IO then dump_to(target)
|
26
|
+
when String
|
27
|
+
log_basename(:dump, target)
|
28
|
+
prepare(target)
|
29
|
+
File.open(target, "wb") {|file| dump_to(file) }
|
30
|
+
else
|
31
|
+
raise "cannot dump to: #{target.inspect}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def dump_to(io)
|
36
|
+
io.puts "# date: #{Time.now.strftime(date_format)}" if date
|
37
|
+
io.puts "# info: #{app.info}" if info
|
38
|
+
|
39
|
+
if aggregator
|
40
|
+
trails = []
|
41
|
+
results = {}
|
42
|
+
app.aggregator.to_hash.each_pair do |src, _results|
|
43
|
+
results["#{src} (#{src.object_id})"] = _results.collect {|_audit| _audit.value }
|
44
|
+
_results.each {|_audit| trails << _audit.dump }
|
45
|
+
end
|
46
|
+
|
47
|
+
if audit
|
48
|
+
io.puts "# audit:"
|
49
|
+
trails.each {|trail| io.puts "# #{trail.gsub("\n", "\n# ")}"}
|
50
|
+
end
|
51
|
+
|
52
|
+
YAML::dump(results, io)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/tap/tasks/dump.rb
CHANGED
@@ -1,61 +1,116 @@
|
|
1
|
-
module Tap
|
2
|
-
module Tasks
|
3
|
-
# :startdoc::manifest the default dump task
|
4
|
-
#
|
5
|
-
# A dump task to print
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# is specified, the
|
11
|
-
#
|
12
|
-
# % tap run -- [
|
13
|
-
#
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
#
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
1
|
+
module Tap
|
2
|
+
module Tasks
|
3
|
+
# :startdoc::manifest the default dump task
|
4
|
+
#
|
5
|
+
# A dump task to print results as YAML. Unlike most tasks, dump arguments
|
6
|
+
# do not enque to the task; instead the arguments are used to setup a
|
7
|
+
# dump and the dump uses whatever results come to them in a workflow.
|
8
|
+
#
|
9
|
+
# Multiple dumps to the same file append rather than overwrite. If no file
|
10
|
+
# is specified, the dump goes to $stdout.
|
11
|
+
#
|
12
|
+
# % tap run -- [task] --: dump FILEPATH
|
13
|
+
#
|
14
|
+
# :startdoc::manifest-
|
15
|
+
#
|
16
|
+
# Dumps are organized so that arguments passed on the command line are
|
17
|
+
# directed at setup rather than process. Moreover, process will always
|
18
|
+
# receive the audits passed to _execute, rather than the audit values.
|
19
|
+
# This allows a user to provide setup arguments (such as a dump path)
|
20
|
+
# on the command line, and provides dump the opportunity to inspect
|
21
|
+
# audit trails.
|
22
|
+
#
|
23
|
+
class Dump < Tap::FileTask
|
24
|
+
class << self
|
25
|
+
|
26
|
+
# Same as an ordinary parse!, except the arguments normally reserved for
|
27
|
+
# executing the task are used to call setup. The return will always be
|
28
|
+
# an instance and an empty array.
|
29
|
+
def parse!(argv=ARGV, app=Tap::App.instance)
|
30
|
+
instance, args = super
|
31
|
+
instance.setup(*args)
|
32
|
+
[instance, []]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
config :date_format, '%Y-%m-%d %H:%M:%S' # the date format
|
37
|
+
config :audit, true, &c.switch # include the audit trails
|
38
|
+
config :date, true, &c.switch # include a date
|
39
|
+
|
40
|
+
# The dump target, by default $stdout. Target may be a filepath,
|
41
|
+
# in which case dumps append the file.
|
42
|
+
attr_accessor :target
|
43
|
+
|
44
|
+
def initialize(config={}, name=nil, app=App.instance, target=$stdout)
|
45
|
+
super(config, name, app)
|
46
|
+
@target = target
|
47
|
+
end
|
48
|
+
|
49
|
+
# Setup self with the input target. Setup is typically called from
|
50
|
+
# parse! and receives arguments passed from the command line.
|
51
|
+
def setup(path=target)
|
52
|
+
@target = path
|
53
|
+
end
|
54
|
+
|
55
|
+
# Overrides the standard _execute to send process the audits and not
|
56
|
+
# the audit values. This allows process to inspect audit trails.
|
57
|
+
def _execute(*inputs)
|
58
|
+
resolve_dependencies
|
59
|
+
|
60
|
+
previous = []
|
61
|
+
inputs.collect! do |input|
|
62
|
+
if input.kind_of?(Support::Audit)
|
63
|
+
previous << input
|
64
|
+
input.value
|
65
|
+
else
|
66
|
+
previous << Support::Audit.new(nil, input)
|
67
|
+
input
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# this is the overridden part
|
72
|
+
send(method_name, *previous)
|
73
|
+
audit = Support::Audit.new(self, inputs, previous)
|
74
|
+
|
75
|
+
if complete_block = on_complete_block || app.on_complete_block
|
76
|
+
complete_block.call(audit)
|
77
|
+
else
|
78
|
+
app.aggregator.store(audit)
|
79
|
+
end
|
80
|
+
|
81
|
+
audit
|
82
|
+
end
|
83
|
+
|
84
|
+
# Prints the _audit to the target. The return value of process is
|
85
|
+
# not recorded in the audit trail.
|
86
|
+
def process(*_audits)
|
87
|
+
open_io do |io|
|
88
|
+
if date
|
89
|
+
io.puts "# date: #{Time.now.strftime(date_format)}"
|
90
|
+
end
|
91
|
+
|
92
|
+
_audits.each do |_audit|
|
93
|
+
if audit
|
94
|
+
io.puts "# audit:"
|
95
|
+
io.puts "# #{_audit.dump.gsub("\n", "\n# ")}"
|
96
|
+
end
|
97
|
+
|
98
|
+
YAML::dump(_audit.value, io)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
protected
|
104
|
+
|
105
|
+
# helper to open and yield the io specified by target. open_io
|
106
|
+
# ensures file targets are closed when the block returns.
|
107
|
+
def open_io # :nodoc:
|
108
|
+
case target
|
109
|
+
when IO, StringIO then yield(target)
|
110
|
+
when String then File.open(target, 'a') {|io| yield(io) }
|
111
|
+
else raise "cannot open target: #{target.inspect}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
61
116
|
end
|
data/lib/tap/tasks/load.rb
CHANGED
@@ -2,110 +2,23 @@ module Tap
|
|
2
2
|
module Tasks
|
3
3
|
# :startdoc::manifest the default load task
|
4
4
|
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
# to other tasks.
|
5
|
+
# Loads YAML-formatted data and makes the result available for other tasks.
|
6
|
+
# Load is typically used as a gateway task to other tasks.
|
8
7
|
#
|
9
8
|
# % tap run -- load FILEPATH --: [task]
|
10
9
|
#
|
11
|
-
# Load can select items from Hash or Array objects using one or more keys
|
12
|
-
# when only a subset is desired. By default items are selected using [].
|
13
|
-
# For more flexible selection, use match.
|
14
|
-
#
|
15
|
-
# Match converts each of the keys to a Regexp. For hashes, all values
|
16
|
-
# with a matching key will be selected. For arrays, any item matching
|
17
|
-
# a regexp will be selected.
|
18
|
-
#
|
19
|
-
# Use the flags to flatten, compact, sort (etc) results before passing
|
20
|
-
# them on to the next task.
|
21
10
|
class Load < Tap::Task
|
22
11
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
config :sort, false, :short => :s, &c.switch # sort results
|
28
|
-
#config :preview, false, :short => :p, &c.switch # logs result
|
29
|
-
|
30
|
-
# Loads the input as YAML and selects objects using keys. Input may
|
31
|
-
# be an IO, StringIO, or a filepath. If keys are empty, the loaded
|
32
|
-
# object is returned directly.
|
33
|
-
#
|
34
|
-
# ==== Key Selection
|
35
|
-
# Keys select items from the loaded object using [] (ie obj[key]).
|
36
|
-
# If match==true, the behavior is different; each string key is
|
37
|
-
# converted into a Regexp and then arrays select items that match
|
38
|
-
# key:
|
39
|
-
#
|
40
|
-
# results = []
|
41
|
-
# array.each {|i| results << i if i =~ key}
|
42
|
-
#
|
43
|
-
# While hashes select values where the key matches key:
|
44
|
-
#
|
45
|
-
# results = []
|
46
|
-
# hash.each_pair {|k,v| results << v if k =~ key}
|
47
|
-
#
|
48
|
-
# Other objects raise an error when match is true.
|
49
|
-
#
|
50
|
-
# ==== Post Processing
|
51
|
-
# After loading/key selection, the results may be processed (in this
|
52
|
-
# order) using flatten, compact, unique, and sort, each performing as
|
53
|
-
# you would expect.
|
54
|
-
#
|
55
|
-
def process(input, *keys)
|
56
|
-
|
57
|
-
# load the input
|
58
|
-
obj = case input
|
12
|
+
# Loads the input as YAML. Input may be an IO, StringIO, or a filepath.
|
13
|
+
# The loaded object is returned directly.
|
14
|
+
def process(input)
|
15
|
+
case input
|
59
16
|
when StringIO, IO
|
60
17
|
YAML.load(input.read)
|
61
18
|
else
|
62
19
|
log :load, input
|
63
20
|
YAML.load_file(input)
|
64
21
|
end
|
65
|
-
|
66
|
-
# select results by key
|
67
|
-
results = case
|
68
|
-
when keys.empty? then obj
|
69
|
-
when match
|
70
|
-
regexps = keys.collect {|key| Regexp.new(key.to_s) }
|
71
|
-
select_matching(obj, regexps)
|
72
|
-
else
|
73
|
-
keys.collect do |key|
|
74
|
-
index = key.kind_of?(String) ? YAML.load(key) : key
|
75
|
-
obj[index]
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
# post-process results
|
80
|
-
results = results.flatten if flatten
|
81
|
-
results = results.compact if compact
|
82
|
-
results = results.uniq if unique
|
83
|
-
results = results.sort if sort
|
84
|
-
|
85
|
-
#if preview
|
86
|
-
# should be a log or something
|
87
|
-
#puts results.inspect
|
88
|
-
#end
|
89
|
-
|
90
|
-
results
|
91
|
-
end
|
92
|
-
|
93
|
-
protected
|
94
|
-
|
95
|
-
# selects items from obj which match one of the regexps.
|
96
|
-
def select_matching(obj, regexps) # :nodoc:
|
97
|
-
case obj
|
98
|
-
when Array
|
99
|
-
obj.select {|item| regexps.any? {|r| item =~ r} }
|
100
|
-
when Hash
|
101
|
-
results = []
|
102
|
-
obj.each_pair do |key, value|
|
103
|
-
results << value if regexps.any? {|r| key =~ r}
|
104
|
-
end
|
105
|
-
results
|
106
|
-
else
|
107
|
-
raise ArgumentError, "cannot match keys from a #{obj.class}"
|
108
|
-
end
|
109
22
|
end
|
110
23
|
end
|
111
24
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.12.
|
4
|
+
version: 0.12.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simon Chiang
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-02-
|
12
|
+
date: 2009-02-18 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -96,6 +96,7 @@ files:
|
|
96
96
|
- lib/tap/support/templater.rb
|
97
97
|
- lib/tap/support/versions.rb
|
98
98
|
- lib/tap/task.rb
|
99
|
+
- lib/tap/tasks/core_dump.rb
|
99
100
|
- lib/tap/tasks/dump.rb
|
100
101
|
- lib/tap/tasks/load.rb
|
101
102
|
- lib/tap/test.rb
|