amqp-utils 0.0.1 → 0.2.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/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ .sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/Rakefile CHANGED
@@ -1,4 +1,68 @@
1
- require 'config/requirements'
2
- require 'config/hoe' # setup Hoe + all gem configuration
3
-
4
- Dir['tasks/**/*.rake'].each { |rake| load rake }
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "amqp-utils"
8
+ gem.summary = %Q{Command line utilities for interacting with AMQP compliant queues}
9
+ gem.description = %Q{Command line utilies for interacting with AMQP compliant queues.
10
+ The intention is provide simple management tools that can be used to complete ad hoc
11
+ housework on an AMQP queue. In addition, simple scripts can be layered over the tools
12
+ when needed.}
13
+ gem.email = "dougbarth@gmail.com"
14
+ gem.homepage = "http://github.com/dougbarth/amqp-utils"
15
+ gem.authors = ["Doug Barth"]
16
+ gem.rubyforge_project = "amqp-utils"
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+
19
+ gem.add_dependency('tmm1-amqp', '~> 0.6.4')
20
+ gem.add_dependency('trollop', '~> 1.10.2')
21
+ gem.add_dependency('facets', '~> 2.7.0')
22
+ gem.add_dependency('clio', '~> 0.3.0')
23
+ gem.add_dependency('json', '~> 1.1.6')
24
+ end
25
+ Jeweler::RubyforgeTasks.new do |rubyforge|
26
+ rubyforge.doc_task = "rdoc"
27
+ end
28
+ rescue LoadError
29
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
30
+ end
31
+
32
+ require 'rake/testtask'
33
+ Rake::TestTask.new(:test) do |test|
34
+ test.libs << 'lib' << 'test'
35
+ test.pattern = 'test/**/*_test.rb'
36
+ test.verbose = true
37
+ end
38
+
39
+ begin
40
+ require 'rcov/rcovtask'
41
+ Rcov::RcovTask.new do |test|
42
+ test.libs << 'test'
43
+ test.pattern = 'test/**/*_test.rb'
44
+ test.verbose = true
45
+ end
46
+ rescue LoadError
47
+ task :rcov do
48
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
49
+ end
50
+ end
51
+
52
+ task :test => :check_dependencies
53
+
54
+ task :default => :test
55
+
56
+ require 'rake/rdoctask'
57
+ Rake::RDocTask.new do |rdoc|
58
+ if File.exist?('VERSION')
59
+ version = File.read('VERSION')
60
+ else
61
+ version = ""
62
+ end
63
+
64
+ rdoc.rdoc_dir = 'rdoc'
65
+ rdoc.title = "amqp-utils #{version}"
66
+ rdoc.rdoc_files.include('README*')
67
+ rdoc.rdoc_files.include('lib/**/*.rb')
68
+ end
data/TODO.txt ADDED
@@ -0,0 +1,7 @@
1
+ [x] fix amqp-enqueue message count
2
+ [x] detect commandline ARGV when no queue is specified bring up help
3
+ [x] amqp-stat hangs when no queue specified
4
+ [x] amqp-enqueue inspect error when message not specified
5
+ [o] amqp-dequeue hangs on exit
6
+ [o] setup.rb seems to install command.rb in wrong location
7
+ [o] gem create
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,79 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{amqp-utils}
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Doug Barth"]
12
+ s.date = %q{2009-11-13}
13
+ s.description = %q{Command line utilies for interacting with AMQP compliant queues.
14
+ The intention is provide simple management tools that can be used to complete ad hoc
15
+ housework on an AMQP queue. In addition, simple scripts can be layered over the tools
16
+ when needed.}
17
+ s.email = %q{dougbarth@gmail.com}
18
+ s.executables = ["amqp-deleteq", "amqp-dequeue", "amqp-enqueue", "amqp-peek", "amqp-pop", "amqp-purge", "amqp-statq"]
19
+ s.extra_rdoc_files = [
20
+ "README.txt"
21
+ ]
22
+ s.files = [
23
+ ".gitignore",
24
+ "History.txt",
25
+ "License.txt",
26
+ "README.txt",
27
+ "Rakefile",
28
+ "TODO.txt",
29
+ "VERSION",
30
+ "amqp-utils.gemspec",
31
+ "bin/amqp-deleteq",
32
+ "bin/amqp-dequeue",
33
+ "bin/amqp-enqueue",
34
+ "bin/amqp-peek",
35
+ "bin/amqp-pop",
36
+ "bin/amqp-purge",
37
+ "bin/amqp-statq",
38
+ "lib/amqp_utils.rb",
39
+ "lib/amqp_utils/command.rb",
40
+ "lib/amqp_utils/message_formatter.rb",
41
+ "test/test_amqp_utils.rb",
42
+ "test/test_helper.rb"
43
+ ]
44
+ s.homepage = %q{http://github.com/dougbarth/amqp-utils}
45
+ s.rdoc_options = ["--charset=UTF-8"]
46
+ s.require_paths = ["lib"]
47
+ s.rubyforge_project = %q{amqp-utils}
48
+ s.rubygems_version = %q{1.3.5}
49
+ s.summary = %q{Command line utilities for interacting with AMQP compliant queues}
50
+ s.test_files = [
51
+ "test/test_amqp_utils.rb",
52
+ "test/test_helper.rb"
53
+ ]
54
+
55
+ if s.respond_to? :specification_version then
56
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
57
+ s.specification_version = 3
58
+
59
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
60
+ s.add_runtime_dependency(%q<tmm1-amqp>, ["~> 0.6.4"])
61
+ s.add_runtime_dependency(%q<trollop>, ["~> 1.10.2"])
62
+ s.add_runtime_dependency(%q<facets>, ["~> 2.7.0"])
63
+ s.add_runtime_dependency(%q<clio>, ["~> 0.3.0"])
64
+ s.add_runtime_dependency(%q<json>, ["~> 1.1.6"])
65
+ else
66
+ s.add_dependency(%q<tmm1-amqp>, ["~> 0.6.4"])
67
+ s.add_dependency(%q<trollop>, ["~> 1.10.2"])
68
+ s.add_dependency(%q<facets>, ["~> 2.7.0"])
69
+ s.add_dependency(%q<clio>, ["~> 0.3.0"])
70
+ s.add_dependency(%q<json>, ["~> 1.1.6"])
71
+ end
72
+ else
73
+ s.add_dependency(%q<tmm1-amqp>, ["~> 0.6.4"])
74
+ s.add_dependency(%q<trollop>, ["~> 1.10.2"])
75
+ s.add_dependency(%q<facets>, ["~> 2.7.0"])
76
+ s.add_dependency(%q<clio>, ["~> 0.3.0"])
77
+ s.add_dependency(%q<json>, ["~> 1.1.6"])
78
+ end
79
+ end
data/bin/amqp-deleteq CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/ruby
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  require File.dirname(__FILE__) + '/../lib/amqp_utils/command'
4
4
 
@@ -7,12 +7,16 @@ class QueueDeleteCommand < AmqpUtils::Command
7
7
  options.banner %Q{
8
8
  |Deletes the supplied queues.
9
9
  |
10
- | #{command_name} <queue>[, <another queue>, ...]
10
+ | #{command_name} <queue> [<another queue> ...]
11
11
  }.margin
12
12
  end
13
13
 
14
+ def validate
15
+ raise "need at least one queue name" unless args[0] && !args[0].empty?
16
+ end
17
+
14
18
  def execute
15
- @queues = ARGV
19
+ @queues = args
16
20
  def @queues.delete_or_stop
17
21
  queue = pop
18
22
  if queue
data/bin/amqp-dequeue CHANGED
@@ -1,28 +1,40 @@
1
- #!/usr/bin/ruby
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  require File.dirname(__FILE__) + '/../lib/amqp_utils/command'
4
+ require File.dirname(__FILE__) + '/../lib/amqp_utils/message_formatter'
4
5
 
5
6
  class DequeueCommand < AmqpUtils::Command
6
7
  def prepare_options(options)
7
8
  options.banner %Q{
8
9
  |Removes messages from the supplied queues and displays them on STDOUT.
9
10
  |
10
- | #{command_name} <queue>[, <another queue>, ...]
11
+ | #{command_name} <queue> [<another queue> ...]
12
+ |
13
+ |Dequeue options:
11
14
  }.margin
15
+ options.opt :format, 'The format that the messages should be displayed as',
16
+ :short => :none, :default => 'pretty'
17
+ options.opt :quiet, 'Suppresses non-message content output',
18
+ :short => 'q', :default => false
19
+ end
20
+
21
+ def validate
22
+ raise "need at least one queue name" if args.empty?
12
23
  end
13
24
 
14
25
  def execute
15
- @queues = ARGV
26
+ @queues = args
27
+ @formatter = AmqpUtils::MessageFormatter.for_type(options[:format])
28
+
16
29
  @queues.each do |queue|
17
- puts "Dequeueing from #{queue}..."
30
+ puts "Dequeueing from #{queue} (^C to stop)..." unless options[:quiet]
18
31
  mq = MQ.new
19
32
 
20
33
  process_message = lambda do |header, message|
21
- puts "(#{queue})"
22
- puts " Header: #{header.properties.inspect}"
23
- puts " Message: #{message.inspect}"
34
+ puts "(#{queue})" unless options[:quiet]
35
+ @formatter.generate(STDOUT, header, message)
24
36
  end
25
- mq.queue(queue).subscribe &process_message
37
+ mq.queue(queue).subscribe(&process_message)
26
38
  end
27
39
  end
28
40
  end
data/bin/amqp-enqueue CHANGED
@@ -1,6 +1,7 @@
1
- #!/usr/bin/ruby
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  require File.dirname(__FILE__) + '/../lib/amqp_utils/command'
4
+ require 'clio/progressbar'
4
5
 
5
6
  class EnqueueCommand < AmqpUtils::Command
6
7
  def prepare_options(options)
@@ -11,28 +12,35 @@ class EnqueueCommand < AmqpUtils::Command
11
12
  |
12
13
  |Enqueue options:
13
14
  }.margin
14
- options.opt :persistent, 'Mark messages as persistent.'
15
+ options.opt :persistent, 'Mark messages as persistent.', :short => :none
15
16
  options.opt :count, 'Number of times the message should be published.', :type => :int, :default => 1
16
17
  end
17
18
 
19
+ def validate
20
+ raise "need a queue to publish to" unless args[0] && !args[0].empty?
21
+ raise "need a message to publish" unless args[1] && !args[1].empty?
22
+ end
23
+
18
24
  def execute
19
- @queue = ARGV[0]
20
- @message = ARGV[1]
25
+ @queue, @message = args
21
26
 
22
27
  publisher = EM.spawn do |queue, message, messages, options|
28
+ @progress ||= Clio::Progressbar.new('Enqueuing', options[:count])
29
+
23
30
  if messages > 0
24
31
  @mq ||= MQ.new
25
32
  @mq.queue(queue, :durable => true, :auto_delete => false).
26
33
  publish(message, :persistent => options.persistent)
27
34
 
28
- print '.'; STDOUT.flush
35
+ @progress.inc
29
36
  publisher.notify(queue, message, messages - 1, options)
30
37
  else
38
+ @progress.finish
31
39
  EM.next_tick { AMQP.stop { EM.stop } }
32
40
  end
33
41
  end
34
42
 
35
- publisher.notify(@queue, @message, options.count, options)
43
+ publisher.notify(@queue, @message, options[:count], options)
36
44
  end
37
45
  end
38
46
 
data/bin/amqp-peek CHANGED
@@ -1,6 +1,7 @@
1
- #!/usr/bin/ruby
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  require File.dirname(__FILE__) + '/../lib/amqp_utils/command'
4
+ require File.dirname(__FILE__) + '/../lib/amqp_utils/message_formatter'
4
5
 
5
6
  class PeekCommand < AmqpUtils::Command
6
7
  def prepare_options(options)
@@ -12,22 +13,26 @@ class PeekCommand < AmqpUtils::Command
12
13
  | NOTE: This operation does have side effects on the server. The message is
13
14
  | placed at the end of the queue after returning from this method. The
14
15
  | message is also marked as being redelivered.
16
+ |
17
+ |Peek options:
15
18
  }.margin
19
+ options.opt :format, 'The format that the messages should be displayed as',
20
+ :short => :none, :default => 'pretty'
21
+ end
22
+
23
+ def validate
24
+ raise "need a queue name" unless args[0] && !args[0].empty?
16
25
  end
17
26
 
18
27
  def execute
19
28
  @queue = args[0]
29
+ @formatter = AmqpUtils::MessageFormatter.for_type(options[:format])
20
30
 
21
31
  mq = MQ.new
22
-
23
32
  mq.queue(@queue).pop(:ack => true) do |header, message|
24
33
  if message
25
34
  puts "(#{@queue})"
26
- puts " Header: "
27
- header.properties.each do |key, value|
28
- puts " #{key.inspect} => #{value.inspect}"
29
- end
30
- puts " Message: #{message.inspect}"
35
+ @formatter.generate(STDOUT, header, message)
31
36
  else
32
37
  puts "(#{@queue}) empty"
33
38
  end
data/bin/amqp-pop CHANGED
@@ -1,6 +1,7 @@
1
- #!/usr/bin/ruby
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  require File.dirname(__FILE__) + '/../lib/amqp_utils/command'
4
+ require File.dirname(__FILE__) + '/../lib/amqp_utils/message_formatter'
4
5
 
5
6
  class PopCommand < AmqpUtils::Command
6
7
  def prepare_options(options)
@@ -8,21 +9,26 @@ class PopCommand < AmqpUtils::Command
8
9
  |Pops a single message from the queue.
9
10
  |
10
11
  | #{command_name} <queue>
12
+ |
13
+ |Pop options:
11
14
  }.margin
15
+ options.opt :format, 'The format that the messages should be displayed as',
16
+ :short => :none, :default => 'pretty'
17
+ end
18
+
19
+ def validate
20
+ raise "need a queue name" unless args[0] && !args[0].empty?
12
21
  end
13
22
 
14
23
  def execute
15
24
  @queue = args[0]
25
+ @formatter = AmqpUtils::MessageFormatter.for_type(options[:format])
16
26
 
17
27
  mq = MQ.new
18
28
  mq.queue(@queue).pop do |header, message|
19
29
  if message
20
30
  puts "(#{@queue})"
21
- puts " Header: "
22
- header.properties.each do |key, value|
23
- puts " #{key.inspect} => #{value.inspect}"
24
- end
25
- puts " Message: #{message.inspect}"
31
+ @formatter.generate(STDOUT, header, message)
26
32
  else
27
33
  puts "(#{@queue}) empty"
28
34
  end
data/bin/amqp-purge ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../lib/amqp_utils/command'
4
+
5
+ # Monkey patching in purge support.
6
+ #
7
+ # TODO: submit this change back to the AMQP project.
8
+ class MQ::Queue
9
+ def purge(options = {})
10
+ @mq.callback {
11
+ @mq.send Protocol::Queue::Purge.new({:queue => name,
12
+ :nowait => true}.merge(options))
13
+ }
14
+ end
15
+ end
16
+
17
+ class PurgeCommand < AmqpUtils::Command
18
+ def prepare_options(options)
19
+ options.banner %Q{
20
+ |Removes all messages from the supplied queues.
21
+ |
22
+ | #{command_name} <queue> [<another queue> ...]
23
+ }.margin
24
+ end
25
+
26
+ def validate
27
+ raise "need at least one queue name" if args.empty?
28
+ end
29
+
30
+ def execute
31
+ mq = MQ.new
32
+ @queues = args
33
+ purge_one = lambda do
34
+ queue = @queues.shift
35
+ puts "Purging #{queue}..."
36
+ mq.queue(queue).purge
37
+ if @queues.empty?
38
+ AMQP.stop { EM.stop }
39
+ else
40
+ EM.next_tick(&purge_one)
41
+ end
42
+ end
43
+ EM.next_tick(&purge_one)
44
+ end
45
+ end
46
+
47
+ PurgeCommand.run
data/bin/amqp-statq CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/ruby
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  require File.dirname(__FILE__) + '/../lib/amqp_utils/command'
4
4
 
@@ -7,15 +7,19 @@ class QueueStatCommand < AmqpUtils::Command
7
7
  options.banner %Q{
8
8
  |Gets statistics on the queues specified.
9
9
  |
10
- | #{command_name} <queue> [<another_queue> ..]
10
+ | #{command_name} <queue> [<another_queue> ...]
11
11
  }.margin
12
12
  end
13
13
 
14
+ def validate
15
+ raise "need at least one queue name" unless args[0] && !args[0].empty?
16
+ end
17
+
14
18
  def execute
15
- @queues = ARGV
19
+ @queues = args
16
20
 
17
21
  @queues.each do |queue|
18
- MQ.new.queue(queue).status do |size, consumers|
22
+ mq.queue(queue, :passive => true).status do |size, consumers|
19
23
  puts "Queue <#{queue}>: #{size} message(s), #{consumers} consumer(s)"
20
24
 
21
25
  @queues.delete(queue)
@@ -1,10 +1,19 @@
1
1
  require File.dirname(__FILE__) + '/../amqp_utils'
2
2
 
3
3
  class AmqpUtils::Command
4
+ include Clio::Terminal
5
+
4
6
  class << self
5
7
  def run(args = ARGV)
6
8
  command = new(args)
7
9
  command.process_options
10
+
11
+ begin
12
+ command.validate
13
+ rescue RuntimeError => e
14
+ Trollop::die(e.message)
15
+ end
16
+
8
17
  command.go
9
18
  end
10
19
  end
@@ -13,25 +22,43 @@ class AmqpUtils::Command
13
22
  @args = args
14
23
  end
15
24
 
25
+ def version
26
+ IO.read(File.join(File.dirname(__FILE__), '..', '..', 'VERSION'))
27
+ end
28
+
16
29
  attr_reader :args, :options
17
30
 
18
31
  def process_options
19
32
  command = self
20
33
  @options = Trollop::options(@args) do
34
+ version(command.version)
21
35
  command.prepare_options(self) if command.respond_to?(:prepare_options)
22
36
 
23
37
  banner %Q{
24
38
  |
25
39
  |Standard options:
26
40
  }.margin
27
- opt :host, 'The AMQP host to connect to', :default => 'localhost'
28
- opt :port, 'The AMQP port to connect to', :default => 5672
29
- opt :vhost, 'The vhost to connect to', :default => '/'
30
- opt :user, 'The user name to authenticate with', :default => 'guest'
31
- opt :password, 'The password to connect with', :default => 'guest'
32
- opt :timeout, 'The connect timeout in seconds', :default => 5
33
- opt :verbose, 'Print all AMQP commands sent and received.'
41
+ opt :host, 'The AMQP host to connect to', :short => 'H', :default => 'localhost'
42
+ opt :port, 'The AMQP port to connect to', :short => 'P', :default => 5672
43
+ opt :vhost, 'The vhost to connect to', :short => 'V', :default => '/'
44
+ opt :user, 'The user name to authenticate with', :default => 'guest', :short => 'u'
45
+ opt :prompt, 'Prompt the user for a password', :short => 'p'
46
+ opt :password, 'The password to connect with.', :default => 'guest', :short => :none
47
+ conflicts(:prompt, :password)
48
+ opt :timeout, 'The connect timeout in seconds', :default => 5, :short => 't'
49
+ opt :verbose, 'Print all AMQP commands sent and received.', :short => 'v'
34
50
  end
51
+
52
+ @args = @args.dup
53
+ ARGV.clear
54
+ end
55
+
56
+ # Called to validate that the supplied command line options and arguments
57
+ # are valid. If there is a problem with the supplied values, and exception
58
+ # should be raised.
59
+ #
60
+ # Subclasses show override this method and do their validation.
61
+ def validate
35
62
  end
36
63
 
37
64
  def command_name
@@ -39,23 +66,42 @@ class AmqpUtils::Command
39
66
  end
40
67
 
41
68
  def go
42
- EM.run do
43
- %w(host port vhost user timeout).each do |val|
44
- AMQP.settings[val.to_sym] = options[val.to_sym]
69
+ if options.prompt
70
+ options[:password] = password()
71
+ puts
72
+ end
73
+
74
+ %w(host port vhost user timeout).each do |val|
75
+ AMQP.settings[val.to_sym] = options[val.to_sym]
76
+ end
77
+ AMQP.settings[:pass] = options.password
78
+ AMQP.logging = options.verbose
79
+
80
+ trap("INT") do
81
+ if @nice_tried
82
+ EM.stop
83
+ else
84
+ AMQP.stop { EM.stop }
85
+ @nice_tried = true
45
86
  end
46
- AMQP.settings[:pass] = options.password
47
- AMQP.logging = options.verbose
48
-
49
- trap("INT") do
50
- if @nice_tried
51
- EM.stop
52
- else
53
- AMQP.stop { EM.stop }
54
- @nice_tried = true
87
+ end
88
+
89
+ EM.run do
90
+ amqp.connection_status do |status|
91
+ if status == :disconnected
92
+ Trollop::die "disconnected from #{AMQP.settings[:host]}:#{AMQP.settings[:port]}"
55
93
  end
56
94
  end
57
95
 
58
- execute
96
+ mq.callback { execute }
59
97
  end
60
98
  end
99
+
100
+ def amqp
101
+ @amqp ||= AMQP.start
102
+ end
103
+
104
+ def mq
105
+ @mq ||= MQ.new
106
+ end
61
107
  end
@@ -0,0 +1,42 @@
1
+ class AmqpUtils::MessageFormatter
2
+ class << self
3
+ @@formatters ||= {}
4
+
5
+ def for_type(format_type)
6
+ @@formatters[format_type.downcase].new
7
+ end
8
+
9
+ def register_formatter(formatter, format_type)
10
+ @@formatters[format_type.downcase] = formatter
11
+ end
12
+ end
13
+
14
+ class Base
15
+ def self.inherited(klass)
16
+ ::AmqpUtils::MessageFormatter.register_formatter(klass, klass.basename)
17
+ end
18
+ end
19
+
20
+ class Pretty < Base
21
+ def generate(io, header, message)
22
+ io.puts " Header: "
23
+ header.properties.each do |key, value|
24
+ io.puts " #{key.inspect} => #{value.inspect}"
25
+ end
26
+ io.puts " Message: #{message.inspect}"
27
+ end
28
+ end
29
+
30
+ class JSON < Base
31
+ def generate(io, header, message)
32
+ json_obj = {'header' => header.properties, 'message' => message}
33
+ io.puts ::JSON.generate(json_obj)
34
+ end
35
+ end
36
+
37
+ class Message < Base
38
+ def generate(io, header, message)
39
+ io.puts message
40
+ end
41
+ end
42
+ end
data/lib/amqp_utils.rb CHANGED
@@ -10,8 +10,16 @@ require 'rubygems'
10
10
  gem 'trollop'
11
11
  require 'trollop'
12
12
 
13
- gem 'amqp'
13
+ gem 'tmm1-amqp'
14
14
  require 'mq'
15
15
 
16
16
  gem 'facets'
17
17
  require 'facets/string/tab'
18
+ require 'facets/kernel/returning'
19
+ require 'facets/module/basename'
20
+
21
+ gem 'clio'
22
+ require 'clio/consoleutils'
23
+
24
+ gem 'json'
25
+ require 'json'