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