tap 0.12.4 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History +34 -0
- data/README +62 -41
- data/bin/tap +36 -40
- data/cmd/console.rb +14 -6
- data/cmd/manifest.rb +62 -58
- data/cmd/run.rb +49 -31
- data/doc/API +84 -0
- data/doc/Class Reference +83 -115
- data/doc/Examples/Command Line +36 -0
- data/doc/Examples/Workflow +40 -0
- data/lib/tap/app.rb +293 -214
- data/lib/tap/app/node.rb +43 -0
- data/lib/tap/app/queue.rb +77 -0
- data/lib/tap/app/stack.rb +16 -0
- data/lib/tap/app/state.rb +22 -0
- data/lib/tap/constants.rb +2 -2
- data/lib/tap/env.rb +400 -314
- data/lib/tap/env/constant.rb +227 -0
- data/lib/tap/env/gems.rb +63 -0
- data/lib/tap/env/manifest.rb +89 -0
- data/lib/tap/env/minimap.rb +292 -0
- data/lib/tap/{support → env}/string_ext.rb +2 -2
- data/lib/tap/exe.rb +113 -125
- data/lib/tap/join.rb +175 -0
- data/lib/tap/joins.rb +9 -0
- data/lib/tap/joins/switch.rb +44 -0
- data/lib/tap/joins/sync.rb +99 -0
- data/lib/tap/root.rb +100 -491
- data/lib/tap/root/utils.rb +220 -0
- data/lib/tap/{support → root}/versions.rb +31 -29
- data/lib/tap/schema.rb +248 -0
- data/lib/tap/schema/parser.rb +413 -0
- data/lib/tap/schema/utils.rb +82 -0
- data/lib/tap/support/intern.rb +19 -6
- data/lib/tap/support/templater.rb +8 -3
- data/lib/tap/task.rb +175 -171
- data/lib/tap/tasks/dump.rb +58 -0
- data/lib/tap/tasks/load.rb +62 -0
- metadata +30 -73
- data/cmd/destroy.rb +0 -27
- data/cmd/generate.rb +0 -27
- data/doc/Command Reference +0 -105
- data/doc/Syntax Reference +0 -234
- data/doc/Tutorial +0 -348
- data/lib/tap/dump.rb +0 -142
- data/lib/tap/file_task.rb +0 -384
- data/lib/tap/generator/arguments.rb +0 -13
- data/lib/tap/generator/base.rb +0 -176
- data/lib/tap/generator/destroy.rb +0 -60
- data/lib/tap/generator/generate.rb +0 -93
- data/lib/tap/generator/generators/command/command_generator.rb +0 -21
- data/lib/tap/generator/generators/command/templates/command.erb +0 -32
- data/lib/tap/generator/generators/config/config_generator.rb +0 -98
- data/lib/tap/generator/generators/generator/generator_generator.rb +0 -37
- data/lib/tap/generator/generators/generator/templates/task.erb +0 -27
- data/lib/tap/generator/generators/generator/templates/test.erb +0 -26
- data/lib/tap/generator/generators/root/root_generator.rb +0 -84
- data/lib/tap/generator/generators/root/templates/MIT-LICENSE +0 -22
- data/lib/tap/generator/generators/root/templates/README +0 -14
- data/lib/tap/generator/generators/root/templates/Rakefile +0 -84
- data/lib/tap/generator/generators/root/templates/Rapfile +0 -11
- data/lib/tap/generator/generators/root/templates/gemspec +0 -27
- data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +0 -3
- data/lib/tap/generator/generators/task/task_generator.rb +0 -25
- data/lib/tap/generator/generators/task/templates/task.erb +0 -14
- data/lib/tap/generator/generators/task/templates/test.erb +0 -19
- data/lib/tap/generator/manifest.rb +0 -20
- data/lib/tap/generator/preview.rb +0 -69
- data/lib/tap/load.rb +0 -64
- data/lib/tap/spec.rb +0 -41
- data/lib/tap/support/aggregator.rb +0 -65
- data/lib/tap/support/audit.rb +0 -333
- data/lib/tap/support/constant.rb +0 -143
- data/lib/tap/support/constant_manifest.rb +0 -126
- data/lib/tap/support/dependencies.rb +0 -54
- data/lib/tap/support/dependency.rb +0 -44
- data/lib/tap/support/executable.rb +0 -198
- data/lib/tap/support/executable_queue.rb +0 -125
- data/lib/tap/support/gems.rb +0 -43
- data/lib/tap/support/join.rb +0 -144
- data/lib/tap/support/joins.rb +0 -12
- data/lib/tap/support/joins/switch.rb +0 -27
- data/lib/tap/support/joins/sync_merge.rb +0 -38
- data/lib/tap/support/manifest.rb +0 -171
- data/lib/tap/support/minimap.rb +0 -90
- data/lib/tap/support/node.rb +0 -176
- data/lib/tap/support/parser.rb +0 -450
- data/lib/tap/support/schema.rb +0 -385
- data/lib/tap/support/shell_utils.rb +0 -67
- data/lib/tap/test.rb +0 -77
- data/lib/tap/test/assertions.rb +0 -38
- data/lib/tap/test/env_vars.rb +0 -29
- data/lib/tap/test/extensions.rb +0 -73
- data/lib/tap/test/file_test.rb +0 -362
- data/lib/tap/test/file_test_class.rb +0 -15
- data/lib/tap/test/regexp_escape.rb +0 -87
- data/lib/tap/test/script_test.rb +0 -46
- data/lib/tap/test/script_tester.rb +0 -115
- data/lib/tap/test/subset_test.rb +0 -260
- data/lib/tap/test/subset_test_class.rb +0 -99
- data/lib/tap/test/tap_test.rb +0 -109
- data/lib/tap/test/utils.rb +0 -231
@@ -1,22 +0,0 @@
|
|
1
|
-
Copyright (c) <%= Time.now.year %>, <copyright holders>
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person
|
4
|
-
obtaining a copy of this software and associated documentation
|
5
|
-
files (the "Software"), to deal in the Software without
|
6
|
-
restriction, including without limitation the rights to use,
|
7
|
-
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
-
copies of the Software, and to permit persons to whom the
|
9
|
-
Software is furnished to do so, subject to the following
|
10
|
-
conditions:
|
11
|
-
|
12
|
-
The above copyright notice and this permission notice shall be
|
13
|
-
included in all copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
-
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
-
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
-
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
-
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
-
OTHER DEALINGS IN THE SOFTWARE.
|
@@ -1,84 +0,0 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'rake/testtask'
|
3
|
-
require 'rake/rdoctask'
|
4
|
-
require 'rake/gempackagetask'
|
5
|
-
|
6
|
-
#
|
7
|
-
# Gem specification
|
8
|
-
#
|
9
|
-
|
10
|
-
def gemspec
|
11
|
-
data = File.read('<%= project_name %>.gemspec')
|
12
|
-
spec = nil
|
13
|
-
Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
|
14
|
-
spec
|
15
|
-
end
|
16
|
-
|
17
|
-
Rake::GemPackageTask.new(gemspec) do |pkg|
|
18
|
-
pkg.need_tar = true
|
19
|
-
end
|
20
|
-
|
21
|
-
desc 'Prints the gemspec manifest.'
|
22
|
-
task :print_manifest do
|
23
|
-
# collect files from the gemspec, labeling
|
24
|
-
# with true or false corresponding to the
|
25
|
-
# file existing or not
|
26
|
-
files = gemspec.files.inject({}) do |files, file|
|
27
|
-
files[File.expand_path(file)] = [File.exists?(file), file]
|
28
|
-
files
|
29
|
-
end
|
30
|
-
|
31
|
-
# gather non-rdoc/pkg files for the project
|
32
|
-
# and add to the files list if they are not
|
33
|
-
# included already (marking by the absence
|
34
|
-
# of a label)
|
35
|
-
Dir.glob("**/*").each do |file|
|
36
|
-
next if file =~ /^(rdoc|pkg|backup)/ || File.directory?(file)
|
37
|
-
|
38
|
-
path = File.expand_path(file)
|
39
|
-
files[path] = ["", file] unless files.has_key?(path)
|
40
|
-
end
|
41
|
-
|
42
|
-
# sort and output the results
|
43
|
-
files.values.sort_by {|exists, file| file }.each do |entry|
|
44
|
-
puts "%-5s %s" % entry
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
#
|
49
|
-
# Documentation tasks
|
50
|
-
#
|
51
|
-
|
52
|
-
desc 'Generate documentation.'
|
53
|
-
Rake::RDocTask.new(:rdoc) do |rdoc|
|
54
|
-
spec = gemspec
|
55
|
-
|
56
|
-
rdoc.rdoc_dir = 'rdoc'
|
57
|
-
rdoc.options.concat(spec.rdoc_options)
|
58
|
-
rdoc.rdoc_files.include( spec.extra_rdoc_files )
|
59
|
-
|
60
|
-
files = spec.files.select {|file| file =~ /^lib.*\.rb$/}
|
61
|
-
rdoc.rdoc_files.include( files )
|
62
|
-
|
63
|
-
# Using CDoc to template your RDoc will result in configurations being
|
64
|
-
# listed with documentation in a subsection following attributes. Not
|
65
|
-
# necessary, but nice.
|
66
|
-
require 'cdoc'
|
67
|
-
rdoc.template = 'cdoc/cdoc_html_template'
|
68
|
-
rdoc.options << '--fmt' << 'cdoc'
|
69
|
-
end
|
70
|
-
|
71
|
-
#
|
72
|
-
# Test tasks
|
73
|
-
#
|
74
|
-
|
75
|
-
desc 'Default: Run tests.'
|
76
|
-
task :default => :test
|
77
|
-
|
78
|
-
desc 'Run tests.'
|
79
|
-
Rake::TestTask.new(:test) do |t|
|
80
|
-
t.test_files = Dir.glob( File.join('test', ENV['pattern'] || '**/*_test.rb') )
|
81
|
-
t.verbose = true
|
82
|
-
t.warning = true
|
83
|
-
end
|
84
|
-
|
@@ -1,11 +0,0 @@
|
|
1
|
-
require 'tap/declarations'
|
2
|
-
|
3
|
-
module <%= project_name.camelize %>
|
4
|
-
extend Rap::Declarations
|
5
|
-
|
6
|
-
# ::desc your basic goodnight moon task
|
7
|
-
# Says goodnight with a configurable message.
|
8
|
-
task(:goodnight, :obj, :message => 'goodnight') do |task, args|
|
9
|
-
puts "#{task.message} #{args.obj}"
|
10
|
-
end
|
11
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
Gem::Specification.new do |s|
|
2
|
-
s.name = "<%= project_name %>"
|
3
|
-
s.version = "0.0.1"
|
4
|
-
#s.author = "Your Name Here"
|
5
|
-
#s.email = "your.email@pubfactory.edu"
|
6
|
-
#s.homepage = "http://rubyforge.org/projects/<%= project_name %>/"
|
7
|
-
s.platform = Gem::Platform::RUBY
|
8
|
-
s.summary = "<%= project_name %>"
|
9
|
-
s.require_path = "lib"
|
10
|
-
#s.rubyforge_project = "<%= project_name %>"
|
11
|
-
s.add_dependency("tap", "= <%= Tap::VERSION %>")
|
12
|
-
s.has_rdoc = true
|
13
|
-
s.rdoc_options.concat %W{--main README -S -N --title <%= project_name.capitalize %>}
|
14
|
-
|
15
|
-
# list extra rdoc files here.
|
16
|
-
s.extra_rdoc_files = %W{
|
17
|
-
<%= history ? " History\n" : '' %>
|
18
|
-
README
|
19
|
-
<%= license ? " MIT-LICENSE\n" : '' %>
|
20
|
-
}
|
21
|
-
|
22
|
-
# list the files you want to include here. you can
|
23
|
-
# check this manifest using 'rap print_manifest'
|
24
|
-
s.files = %W{
|
25
|
-
tap.yml
|
26
|
-
}
|
27
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module Tap::Generator::Generators
|
2
|
-
|
3
|
-
# :startdoc: Tap::Generator::Generators::TaskGenerator::generator a task and test
|
4
|
-
#
|
5
|
-
# Generates a new Tap::Task and an associated test file.
|
6
|
-
class TaskGenerator < Tap::Generator::Base
|
7
|
-
|
8
|
-
config :test, true, &c.switch # specifies creation of a test file
|
9
|
-
|
10
|
-
def manifest(m, const_name)
|
11
|
-
const = Tap::Support::Constant.new(const_name.camelize)
|
12
|
-
|
13
|
-
task_path = path('lib', "#{const.path}.rb")
|
14
|
-
m.directory File.dirname(task_path)
|
15
|
-
m.template task_path, "task.erb", :const => const
|
16
|
-
|
17
|
-
if test
|
18
|
-
test_path = path('test', "#{const.path}_test.rb")
|
19
|
-
m.directory File.dirname(test_path)
|
20
|
-
m.template test_path, "test.erb", :const => const
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
<% redirect do |target| %># <%= const.name %>::manifest <replace with manifest summary>
|
2
|
-
# <replace with command line description>
|
3
|
-
|
4
|
-
# <%= const.const_name %> Documentation
|
5
|
-
class <%= const.const_name %> < Tap::Task
|
6
|
-
|
7
|
-
# <config file documentation>
|
8
|
-
config :message, 'goodnight' # a sample config
|
9
|
-
|
10
|
-
def process(name)
|
11
|
-
log message, name
|
12
|
-
"#{message} #{name}"
|
13
|
-
end
|
14
|
-
end <% module_nest(const.nesting, ' ') { target } end %>
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), '<%= '../' * const.nesting_depth %>tap_test_helper.rb')
|
2
|
-
require '<%= const.path %>'
|
3
|
-
|
4
|
-
class <%= const.name %>Test < Test::Unit::TestCase
|
5
|
-
acts_as_tap_test
|
6
|
-
|
7
|
-
def test_<%= const.basename %>
|
8
|
-
task = <%= const.name %>.new :message => "goodnight"
|
9
|
-
|
10
|
-
# a simple test
|
11
|
-
assert_equal({:message => 'goodnight'}, task.config)
|
12
|
-
assert_equal "goodnight moon", task.process("moon")
|
13
|
-
|
14
|
-
# a more complex test
|
15
|
-
task.execute("moon")
|
16
|
-
assert_equal ["goodnight moon"], app.results(task)
|
17
|
-
assert_audit_equal [[nil, "moon"], [task, "goodnight moon"]], app._results(task)[0]
|
18
|
-
end
|
19
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module Tap
|
2
|
-
module Generator
|
3
|
-
|
4
|
-
# Manifest records methods called upon it using method_missing. These
|
5
|
-
# actions are replayed on a generator in order (for generate) or in
|
6
|
-
# reverse order (for destroy).
|
7
|
-
class Manifest
|
8
|
-
|
9
|
-
# Makes a new Manifest. Method calls on self are recorded to actions.
|
10
|
-
def initialize(actions)
|
11
|
-
@actions = actions
|
12
|
-
end
|
13
|
-
|
14
|
-
# Records an action.
|
15
|
-
def method_missing(action, *args, &block)
|
16
|
-
@actions << [action, args, block]
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
|
3
|
-
module Tap
|
4
|
-
module Generator
|
5
|
-
|
6
|
-
# Preview is a testing module designed so that process will return an array
|
7
|
-
# of relative filepaths for the created files/directories (which are easy
|
8
|
-
# to specify in a test). Preview also collects the content of created files
|
9
|
-
# to be tested as needed.
|
10
|
-
#
|
11
|
-
# class Sample < Tap::Generator::Base
|
12
|
-
# def manifest(m)
|
13
|
-
# dir = path('dir')
|
14
|
-
#
|
15
|
-
# m.directory dir
|
16
|
-
# m.file(File.join(dir, 'file.txt')) {|io| io << "content"}
|
17
|
-
# end
|
18
|
-
# end
|
19
|
-
#
|
20
|
-
# These assertions will pass:
|
21
|
-
#
|
22
|
-
# s = Sample.new.extend Preview
|
23
|
-
# assert_equal %w{
|
24
|
-
# dir
|
25
|
-
# dir/file.txt
|
26
|
-
# }, s.process
|
27
|
-
#
|
28
|
-
# assert_equal "content", s.preview['dir/file.txt']
|
29
|
-
#
|
30
|
-
# Note that relative filepaths are relative to destination_root.
|
31
|
-
module Preview
|
32
|
-
|
33
|
-
# A hash of (relative_path, content) pairs representing
|
34
|
-
# content built to files.
|
35
|
-
attr_accessor :preview
|
36
|
-
|
37
|
-
def self.extended(base) # :nodoc:
|
38
|
-
base.instance_variable_set(:@preview, {})
|
39
|
-
end
|
40
|
-
|
41
|
-
# Returns the path of path, relative to destination_root. If path
|
42
|
-
# is destination_root, '.' will be returned.
|
43
|
-
def relative_path(path)
|
44
|
-
path = Root.relative_filepath(destination_root, path, destination_root) || path
|
45
|
-
path.empty? ? "." : path
|
46
|
-
end
|
47
|
-
|
48
|
-
# Returns the relative path of the target.
|
49
|
-
def directory(target, options={})
|
50
|
-
relative_path(target)
|
51
|
-
end
|
52
|
-
|
53
|
-
# Returns the relative path of the target. If a block is given,
|
54
|
-
# the block will be called with a StringIO and the results stored
|
55
|
-
# in builds.
|
56
|
-
def file(target, options={})
|
57
|
-
target = relative_path(target)
|
58
|
-
|
59
|
-
if block_given?
|
60
|
-
io = StringIO.new
|
61
|
-
yield(io)
|
62
|
-
preview[target] = io.string
|
63
|
-
end
|
64
|
-
|
65
|
-
target
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
data/lib/tap/load.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
|
3
|
-
module Tap
|
4
|
-
# :startdoc::manifest the default load task
|
5
|
-
#
|
6
|
-
# Loads data from the input IO; string data is simply passed through. Load
|
7
|
-
# is typically used as a gateway to other tasks.
|
8
|
-
#
|
9
|
-
# % tap run -- load string --: [task]
|
10
|
-
#
|
11
|
-
# Note that load takes $stdin by default, so you can pipe or redirect data
|
12
|
-
# into to a workflow like so:
|
13
|
-
#
|
14
|
-
# % echo 'hello' | tap run -- load --: dump --audit
|
15
|
-
# # audit:
|
16
|
-
# # o-[tap/load] "hello\n"
|
17
|
-
# # o-[tap/dump] ["hello\n"]
|
18
|
-
# #
|
19
|
-
# hello
|
20
|
-
#
|
21
|
-
# % tap run -- load --: dump --audit < 'somefile.txt'
|
22
|
-
# # audit:
|
23
|
-
# # o-[tap/load] "contents of somefile\n"
|
24
|
-
# # o-[tap/dump] ["contents of somefile\n"]
|
25
|
-
# #
|
26
|
-
# contents of somefile
|
27
|
-
#
|
28
|
-
# ::manifest-
|
29
|
-
#
|
30
|
-
# Load serves as a baseclass for more complicated load tasks. A YAML load
|
31
|
-
# task (see {tap-tasks}[http://tap.rubyforge.org/tap-tasks]) looks like this:
|
32
|
-
#
|
33
|
-
# class Yaml < Tap::Load
|
34
|
-
# def load(io)
|
35
|
-
# YAML.load(io)
|
36
|
-
# end
|
37
|
-
# end
|
38
|
-
#
|
39
|
-
class Load < Tap::Task
|
40
|
-
|
41
|
-
# The default process simply reads the input data and returns it.
|
42
|
-
# See load.
|
43
|
-
def process(input=$stdin)
|
44
|
-
# read on an empty stdin ties up the command line;
|
45
|
-
# this facilitates the intended behavior
|
46
|
-
if input == $stdin && input.stat.size == 0
|
47
|
-
input = ''
|
48
|
-
end
|
49
|
-
|
50
|
-
case input
|
51
|
-
when StringIO, IO
|
52
|
-
load(input)
|
53
|
-
else
|
54
|
-
load(StringIO.new(input))
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# Loads data from the io; the return of load is the return of process. By
|
59
|
-
# default load simply reads data from io.
|
60
|
-
def load(io)
|
61
|
-
io.read
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
data/lib/tap/spec.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
$:.unshift File.expand_path("#{File.dirname(__FILE__)}/..")
|
2
|
-
require 'tap/test/extensions'
|
3
|
-
|
4
|
-
require 'rubygems'
|
5
|
-
require 'minitest/spec'
|
6
|
-
|
7
|
-
# :stopdoc:
|
8
|
-
class MiniTest::Unit::TestCase
|
9
|
-
extend Tap::Test::Extensions
|
10
|
-
|
11
|
-
class << self
|
12
|
-
# Causes a test suite to be skipped. If a message is given, it will
|
13
|
-
# print and notify the user the test suite has been skipped.
|
14
|
-
def skip_test(msg=nil)
|
15
|
-
@@test_suites.delete(self)
|
16
|
-
puts "Skipping #{self}#{msg.empty? ? '' : ': ' + msg}"
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
# Infers the test root directory from the calling file.
|
22
|
-
# 'some_class.rb' => 'some_class'
|
23
|
-
# 'some_class_test.rb' => 'some_class'
|
24
|
-
def test_root_dir # :nodoc:
|
25
|
-
# caller[1] is considered the calling file (which should be the test case)
|
26
|
-
# note that caller entries are like this:
|
27
|
-
# ./path/to/file.rb:10
|
28
|
-
# ./path/to/file.rb:10:in 'method'
|
29
|
-
|
30
|
-
calling_file = caller[1].gsub(/:\d+(:in .*)?$/, "")
|
31
|
-
calling_file.chomp(File.extname(calling_file)).chomp("_spec")
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def method_name
|
36
|
-
@method_name ||= name.gsub(/\s/, "_").gsub(/^test_/, "")
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
MiniTest::Unit.autorun
|
41
|
-
# :startdoc:
|
@@ -1,65 +0,0 @@
|
|
1
|
-
module Tap
|
2
|
-
module Support
|
3
|
-
|
4
|
-
# Aggregator allows thread-safe collection of Audits, organized by
|
5
|
-
# Audit#key.
|
6
|
-
#
|
7
|
-
# a = Audit.new(:key, 'a')
|
8
|
-
# b = Audit.new(:key, 'b')
|
9
|
-
#
|
10
|
-
# agg = Aggregator.new
|
11
|
-
# agg.store(a)
|
12
|
-
# agg.store(b)
|
13
|
-
# agg.retrieve(:key) # => [a, b]
|
14
|
-
#
|
15
|
-
class Aggregator < Monitor
|
16
|
-
|
17
|
-
# Creates a new Aggregator.
|
18
|
-
def initialize
|
19
|
-
super
|
20
|
-
@hash = {}
|
21
|
-
end
|
22
|
-
|
23
|
-
# Clears self of all audits. Returns the existing audits as a hash
|
24
|
-
# of (key, audits) pairs.
|
25
|
-
def clear
|
26
|
-
synchronize do
|
27
|
-
current, @hash = @hash, {}
|
28
|
-
current
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# The total number of audits recorded in self.
|
33
|
-
def size
|
34
|
-
synchronize { @hash.values.inject(0) {|sum, array| sum + array.length} }
|
35
|
-
end
|
36
|
-
|
37
|
-
# True if size == 0
|
38
|
-
def empty?
|
39
|
-
synchronize { size == 0 }
|
40
|
-
end
|
41
|
-
|
42
|
-
# Stores the Audit according to _audit.key.
|
43
|
-
def store(_audit)
|
44
|
-
synchronize { (@hash[_audit.key] ||= []) << _audit }
|
45
|
-
end
|
46
|
-
|
47
|
-
# Retreives all audits for the specified key.
|
48
|
-
def retrieve(key)
|
49
|
-
synchronize { @hash[key] }
|
50
|
-
end
|
51
|
-
|
52
|
-
# Retreives all audits for the input keys, joined as an array.
|
53
|
-
def retrieve_all(*keys)
|
54
|
-
synchronize do
|
55
|
-
keys.collect {|src| @hash[src] }.flatten.compact
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# Converts self to a hash of (key, audits) pairs.
|
60
|
-
def to_hash
|
61
|
-
synchronize { @hash.dup }
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|