envoy 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in envoy.gemspec
4
+ gemspec
@@ -0,0 +1,50 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ envoy (0.0.1)
5
+ broach (= 0.2.1)
6
+ i18n (~> 0.5.0)
7
+ pony (= 1.1)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ activesupport (3.0.3)
13
+ broach (0.2.1)
14
+ json (~> 1.4)
15
+ nap (~> 0.3)
16
+ diff-lcs (1.1.2)
17
+ fakeweb (1.3.0)
18
+ i18n (0.5.0)
19
+ json (1.4.6)
20
+ mail (2.2.11)
21
+ activesupport (>= 2.3.6)
22
+ i18n (~> 0.5.0)
23
+ mime-types (~> 1.16)
24
+ treetop (~> 1.4.8)
25
+ mime-types (1.16)
26
+ nap (0.4)
27
+ polyglot (0.3.1)
28
+ pony (1.1)
29
+ mail (> 2.0)
30
+ rspec (2.1.0)
31
+ rspec-core (~> 2.1.0)
32
+ rspec-expectations (~> 2.1.0)
33
+ rspec-mocks (~> 2.1.0)
34
+ rspec-core (2.1.0)
35
+ rspec-expectations (2.1.0)
36
+ diff-lcs (~> 1.1.2)
37
+ rspec-mocks (2.1.0)
38
+ treetop (1.4.9)
39
+ polyglot (>= 0.3.1)
40
+
41
+ PLATFORMS
42
+ ruby
43
+
44
+ DEPENDENCIES
45
+ broach (= 0.2.1)
46
+ envoy!
47
+ fakeweb (= 1.3.0)
48
+ i18n (~> 0.5.0)
49
+ pony (= 1.1)
50
+ rspec (~> 2.1.0)
data/README ADDED
@@ -0,0 +1,43 @@
1
+ A simple, extendable messaging system
2
+
3
+ Usage
4
+
5
+ require 'envoy'
6
+
7
+ # Create a new messenger
8
+ messenger = Envoy::Messenger.new
9
+
10
+ # Define some transports
11
+ messenger.transports.each do |transport|
12
+ transport.add_transport(:campfire, :account => 'foo', :token => 'bar', :room => 'my_room')
13
+ end
14
+
15
+ OR
16
+
17
+ messenger.transport(:campfire, :account => 'foo', :token => 'bar', :room => 'my_room')
18
+
19
+ # Add some messages
20
+ messenger.messages.each do |message|
21
+ message.add_message(:name => 'Start deployment message', :subject => "Carlos started deployment of branch foo to production at #{Time.now}")
22
+ message.add_message(:name => 'End deployment message', :subject => "Carlos ended deployment of branch foo to production at #{Time.now}")
23
+ end
24
+
25
+ Email and Campfire Transports are included. Create your own by inheriting from Envoy::Transport
26
+
27
+ OR
28
+
29
+ messenger.message(:name => 'Start deployment message', :subject => "Carlos started deployment of branch foo to production at #{Time.now}")
30
+
31
+ # Deliver messages one at a time
32
+
33
+ messenger.deliver_start_deployment_message
34
+
35
+ AND THEN
36
+
37
+ messenger.deliver_end_deployment_message
38
+
39
+ OR
40
+
41
+ # Deliver all messages
42
+
43
+ messenger.deliver_all_messages
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "envoy/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "envoy"
7
+ s.version = Envoy::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Carlos Rodriguez"]
10
+ s.email = ["carlos@eddorre.com"]
11
+ s.homepage = "http://github.com/eddorre/envoy"
12
+ s.summary = %q{A simple, extendable messaging system built for deployments}
13
+ s.description = %q{A simple, extendable messaging system built for deployments}
14
+
15
+ s.rubyforge_project = "envoy"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency "broach", "0.2.1"
23
+ s.add_dependency "i18n", "~> 0.5.0"
24
+ s.add_dependency "pony", "1.1"
25
+
26
+ s.add_development_dependency "rspec", "~> 2.1.0"
27
+ s.add_development_dependency "fakeweb", "1.3.0"
28
+ end
@@ -0,0 +1,3 @@
1
+ require 'envoy/messenger'
2
+ require 'envoy/transport'
3
+ require 'envoy/message'
@@ -0,0 +1,12 @@
1
+ module Envoy
2
+ class Message
3
+ attr_accessor :name, :body, :subject, :options
4
+
5
+ def initialize(name, subject, body = nil, options = {})
6
+ self.name = name
7
+ self.body = body
8
+ self.subject = subject
9
+ self.options = options
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,78 @@
1
+ module Envoy
2
+ class NoTransportError < StandardError; end
3
+
4
+ class Messenger
5
+ attr_accessor :_transports, :_messages, :_sent_messages
6
+
7
+ def initialize
8
+ self._transports = []
9
+ self._messages = []
10
+ self._sent_messages = []
11
+ end
12
+
13
+ def transports(transport_options = {}, &block)
14
+ if !transport_options.empty?
15
+ raise ArgumentError if !transport_options.is_a?(Hash) and return
16
+ self._transports << self.transport(transport_options)
17
+ else
18
+ yield self if block_given?
19
+ end
20
+ end
21
+
22
+ def transport(transport_options = {})
23
+ transport_name = transport_options.delete(:name).to_s.capitalize
24
+ begin
25
+ transport_instance = Module.const_get("Envoy").const_get(transport_name).new(transport_options)
26
+ rescue
27
+ raise NoTransportError, "No transport exists for #{transport_name}" and return
28
+ end
29
+ self._transports << transport_instance
30
+ end
31
+ alias :add_transport :transport
32
+
33
+ def deliver_messages
34
+ self._messages.each do |message|
35
+ self._transports.each do |transport|
36
+ self.deliver_message(transport, message)
37
+ end
38
+ end
39
+ end
40
+
41
+ def deliver_message(transport, message)
42
+ unless self._sent_messages.include?({ :transport => transport, :message => message })
43
+ response = transport.send_message(message)
44
+ self._sent_messages << { :transport => transport, :message => message } if response
45
+ end
46
+ end
47
+
48
+ def messages(message_options = {}, &block)
49
+ if !message_options.empty?
50
+ raise ArgumentError if !message_options.is_a?(Hash) and return
51
+ self._messages << self.message(message_options)
52
+ else
53
+ yield self if block_given?
54
+ end
55
+ end
56
+
57
+ def message(message_options = {})
58
+ message_options.symbolize_keys!
59
+ self._messages << Envoy::Message.new(message_options[:name], message_options[:subject],
60
+ message_options[:body], message_options[:options])
61
+ end
62
+ alias :add_message :message
63
+
64
+ def method_missing(method, *args)
65
+ message = self._messages.select do |message|
66
+ message.name.to_s.gsub(' ', '_').downcase == method.to_s.gsub('deliver_', '')
67
+ end.first
68
+
69
+ unless message.nil?
70
+ self._transports.each do |transport|
71
+ self.deliver_message(transport, message)
72
+ end
73
+ else
74
+ super
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,118 @@
1
+ require 'broach'
2
+ require 'pony'
3
+ require 'i18n'
4
+ require 'net/http'
5
+ require 'uri'
6
+
7
+ module Envoy
8
+ class Transport
9
+ class SendError < RuntimeError
10
+ attr_accessor :message, :created_at
11
+
12
+ def initialize(message, created_at)
13
+ self.message = message
14
+ self.created_at = created_at
15
+ end
16
+ end
17
+
18
+ attr_accessor :errors
19
+
20
+ def initialize(*args)
21
+ raise NotImplementedError, "This is an abstract class. You cannot instantiate this class directly."
22
+ end
23
+
24
+ def errors
25
+ @errors ||= []
26
+ end
27
+ end
28
+
29
+ class Campfire < Transport
30
+ attr_accessor :account, :token, :room, :use_ssl
31
+
32
+ def initialize(options = {})
33
+ self.account = options[:account]
34
+ self.room = options[:room]
35
+ self.token = options[:token]
36
+ self.use_ssl = options[:use_ssl]
37
+ end
38
+
39
+ def send_message(message)
40
+ Broach.settings = { 'account' => @account, 'token' => @token, 'use_ssl' => @use_ssl }
41
+ Broach.speak(self.room, message.body || message.subject)
42
+
43
+ return true
44
+
45
+ rescue Broach::APIError => error
46
+ self.errors << SendError.new(error, Time.now)
47
+ return false
48
+ end
49
+ end
50
+
51
+ class Webhook < Transport
52
+ attr_accessor :url, :headers
53
+
54
+ def initialize(options = {})
55
+ self.url = options[:url]
56
+ self.headers = options[:headers] || {}
57
+ end
58
+
59
+ def send_message(message)
60
+ url = URI.parse(@url)
61
+ request = Net::HTTP::Post.new(url.path)
62
+ request.body = message.options
63
+
64
+ @headers.each do |k,v|
65
+ request.add_field k,v
66
+ end
67
+
68
+ response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)}
69
+
70
+ case response
71
+ when Net::HTTPSuccess, Net::HTTPFound
72
+ return true
73
+ else
74
+ return false
75
+ end
76
+
77
+ rescue URI::InvalidURIError, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse,
78
+ Net::HTTPHeaderSyntaxError, Net::ProtocolError => error
79
+ self.errors << SendError.new(error, Time.now)
80
+ return false
81
+ end
82
+ end
83
+
84
+ class Email < Transport
85
+ attr_accessor :host, :username, :password, :sender, :to, :port, :ssl, :authentication
86
+
87
+ def initialize(options = {})
88
+ self.host = options[:host]
89
+ self.username = options[:username]
90
+ self.sender = options[:sender]
91
+ self.to = options[:to]
92
+ self.port = options[:port] || 25
93
+ self.ssl = options[:ssl] || false
94
+ self.authentication = options[:authentication] || nil
95
+ end
96
+
97
+ def send_message(message)
98
+ if @host.to_sym == :sendmail
99
+ Pony.mail(:from => (@sender.nil? ? 'Envoy Messenger <envoymessenger@localhost>' : @sender),
100
+ :to => (@to.is_a?(String) ? @to : @to.join(',')),
101
+ :via => :sendmail, :body => message.body || message.subject, :subject => message.subject)
102
+ else
103
+ Pony.mail(:from => (@sender.nil? ? 'Envoy Messenger <envoymessenger@localhost>' : @sender),
104
+ :to => (@to.is_a?(String) ? @to : @to.join(',')), :via => :smtp, :via_options =>
105
+ {
106
+ :address => @host, :port => @port, :enable_starttls_auto => @ssl, :user_name => @username,
107
+ :password => @password, :authentication => @authentication, :body => message.body || message.subject, :subject => message.subject
108
+ })
109
+ end
110
+
111
+ return true
112
+
113
+ rescue StandardError => error
114
+ self.errors << SendError.new(error, Time.now)
115
+ return false
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,3 @@
1
+ module Envoy
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,115 @@
1
+ require 'envoy'
2
+ include Envoy
3
+
4
+ describe Messenger do
5
+ before(:each) do
6
+ @messenger = Messenger.new
7
+ end
8
+
9
+ it "should create a new instance of a messenger" do
10
+ @messenger.is_a?(Messenger).should be_true
11
+ end
12
+
13
+ describe "Adding messages" do
14
+ it "should add an instance of a message" do
15
+ @messenger.message(:name => 'Test message', :subject => 'Test subject')
16
+ @messenger._messages.first.is_a?(Message).should be_true
17
+ end
18
+
19
+ it "should add a message with add_message method" do
20
+ @messenger.add_message(:name => 'Test message', :subject => 'Test subject')
21
+ @messenger._messages.size.should == 1
22
+ end
23
+
24
+ it "should add two messages" do
25
+ @messenger.messages do |message|
26
+ message.add_message(:name => 'Test message', :subject => 'Test subject')
27
+ message.add_message(:name => 'Test message 2', :subject => 'Test subject 2')
28
+ end
29
+ @messenger._messages.size.should == 2
30
+ end
31
+
32
+ it "should add two messages with the same name" do
33
+ @messenger.messages do |message|
34
+ message.add_message(:name => 'Test message', :subject => 'Test subject')
35
+ message.add_message(:name => 'Test message', :subject => 'Test subject')
36
+ end
37
+ @messenger._messages.size.should == 2
38
+ end
39
+ end
40
+
41
+ describe "Adding transports" do
42
+ it "should add an instance of a transport" do
43
+ @messenger.transport(:name => :email, :host => :sendmail, :to => 'carlos@eddorre.com')
44
+ @messenger._transports.first.is_a?(Transport).should be_true
45
+ end
46
+
47
+ it "should add a transport with add_transport method" do
48
+ @messenger.add_transport(:name => :email, :host => :sendmail, :to => 'carlos@eddorre.com')
49
+ @messenger._transports.size.should == 1
50
+ end
51
+
52
+ it "should add two transports" do
53
+ @messenger.transports do |transport|
54
+ transport.add_transport(:name => :email, :host => :sendmail, :to => 'carlos@eddorre.com')
55
+ transport.add_transport(:name => :campfire)
56
+ end
57
+
58
+ @messenger._transports.size.should == 2
59
+ end
60
+
61
+ it "should raise an exception when a transport doesn't exist" do
62
+ lambda { @messenger.transport(:name => :foo) }.should raise_error(Envoy::NoTransportError)
63
+ end
64
+ end
65
+
66
+ describe "Delivering messages" do
67
+ it "should deliver a message by name" do
68
+ Pony.stub!(:mail)
69
+ @messenger.add_message(:name => 'Test message', :subject => 'Test subject')
70
+ @messenger.add_transport(:name => :email, :host => :sendmail, :to => 'carlos@eddorre.com')
71
+ @messenger._transports.first.should_receive(:send_message)
72
+
73
+ @messenger.deliver_test_message
74
+ end
75
+
76
+ it "should deliver a message by name when the name is passed as a symbol" do
77
+ Pony.stub!(:mail)
78
+ @messenger.add_message(:name => :test_message, :subject => 'Test subject')
79
+ @messenger.add_transport(:name => :email, :host => :sendmail, :to => 'carlos@eddorre.com')
80
+ @messenger._transports.first.should_receive(:send_message)
81
+
82
+ @messenger.deliver_test_message
83
+ end
84
+
85
+ it "should deliver all messages" do
86
+ Pony.stub!(:mail)
87
+ @messenger.add_message(:name => 'Test message', :subject => 'Test subject')
88
+ @messenger.add_transport(:name => :email, :host => :sendmail, :to => 'carlos@eddorre.com')
89
+ @messenger._transports.first.should_receive(:send_message).with(@messenger._messages.first)
90
+
91
+ @messenger.deliver_messages
92
+ end
93
+
94
+ it "should not re-send the same message more than once" do
95
+ Pony.stub!(:mail)
96
+ @messenger.add_message(:name => 'Test message', :subject => 'Test subject')
97
+ @messenger.add_transport(:name => :email, :host => :sendmail, :to => 'carlos@eddorre.com')
98
+ @messenger._transports.first.should_receive(:send_message).with(@messenger._messages.first).once.and_return(true)
99
+
100
+ @messenger.deliver_messages
101
+ @messenger.deliver_messages
102
+ end
103
+
104
+ it "should deliver messages through two transports when delivering all messages" do
105
+ Pony.stub!(:mail)
106
+ Broach.stub!(:speak).and_return(true)
107
+ @messenger.add_message(:name => 'Test message', :subject => 'Test subject')
108
+ @messenger.add_transport(:name => :email, :host => :sendmail, :to => 'carlos@eddorre.com')
109
+ @messenger.add_transport(:name => :campfire)
110
+
111
+ @messenger.deliver_messages
112
+ @messenger._sent_messages.size.should == 2
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,115 @@
1
+ require 'envoy'
2
+ require 'fakeweb'
3
+ include Envoy
4
+
5
+ describe Transport do
6
+ before(:each) do
7
+ @message = Message.new('Test message', 'this is a test message')
8
+ end
9
+
10
+ describe "Campfire Transport" do
11
+ it "should send a message through broach" do
12
+ transport = Campfire.new(:account => 'foo', :token => 'bar', :room => 'meep')
13
+ Broach.should_receive(:speak).with(transport.room, @message.subject)
14
+ transport.send_message(@message)
15
+ end
16
+ end
17
+
18
+ describe "Email Transport" do
19
+ before(:each) do
20
+ @transport = Envoy::Email.new
21
+ @transport.to = 'carlos@eddorre.com'
22
+ end
23
+
24
+ it "should send a message through pony" do
25
+ @transport.host = :sendmail
26
+ Pony.should_receive(:mail)
27
+ @transport.send_message(@message)
28
+ end
29
+
30
+ it "should send a message through pony with sendmail" do
31
+ @transport.host = :sendmail
32
+
33
+
34
+ Pony.should_receive(:mail).with(:via => :sendmail, :from => 'Envoy Messenger <envoymessenger@localhost>',
35
+ :to => 'carlos@eddorre.com', :body => @message.subject, :subject => @message.subject)
36
+
37
+ @transport.send_message(@message)
38
+ end
39
+
40
+ it "should send a message through pony using SMTP" do
41
+ @transport.host = 'mail.eddorre.com'
42
+
43
+ Pony.should_receive(:mail).with(:from => 'Envoy Messenger <envoymessenger@localhost>', :to => 'carlos@eddorre.com', :via => :smtp, :via_options => { :address => @transport.host,
44
+ :port => 25, :enable_starttls_auto => false, :user_name => nil, :password => nil, :authentication => nil,
45
+ :body => @message.subject, :subject => @message.subject })
46
+
47
+ @transport.send_message(@message)
48
+ end
49
+
50
+ it "should send a message through pony with multiple recipients" do
51
+ @transport.to = ['carlos@eddorre.com', 'hello@eddorre.com']
52
+ @transport.host = :sendmail
53
+
54
+ Pony.should_receive(:mail).with(:via => :sendmail, :from => 'Envoy Messenger <envoymessenger@localhost>',
55
+ :to => 'carlos@eddorre.com,hello@eddorre.com', :body => @message.subject, :subject => @message.subject)
56
+
57
+ @transport.send_message(@message)
58
+ end
59
+
60
+ it "should send a message through pony with a set sender" do
61
+ @transport.host = :sendmail
62
+ @transport.sender = 'carlos@eddorre.com'
63
+
64
+ Pony.should_receive(:mail).with(:via => :sendmail, :from => 'carlos@eddorre.com',
65
+ :to => 'carlos@eddorre.com', :body => @message.subject, :subject => @message.subject)
66
+
67
+ @transport.send_message(@message)
68
+ end
69
+
70
+ it "should return false when an exception is triggered when attempting to send through pony" do
71
+ @transport.host = :sendmail
72
+ @transport.sender = 'carlos@eddorre.com'
73
+ @transport.to = 'carlos@eddorre.com'
74
+
75
+ Pony.stub!(:mail).and_raise(ArgumentError)
76
+
77
+ @transport.send_message(@message).should == false
78
+ end
79
+
80
+ it "should return true when there is no exception triggered when attempting to send through pony" do
81
+ @transport.host = :sendmail
82
+ @transport.sender = 'carlos@eddorre.com'
83
+ @transport.to = 'carlos@eddorre.com'
84
+
85
+ Pony.stub!(:mail).and_return(true)
86
+
87
+ @transport.send_message(@message).should == true
88
+ end
89
+ end
90
+
91
+ describe "Webhook Transport" do
92
+ before(:each) do
93
+ @transport = Envoy::Webhook.new
94
+ @transport.url = 'http://foo.com/'
95
+ end
96
+
97
+ it "should send a message to the webhook URL and return true when the service returns 200" do
98
+ FakeWeb.register_uri(:post, 'http://foo.com', :body => "OK", :status => ["200", "OK"])
99
+ @transport.send_message(@message).should == true
100
+ end
101
+
102
+ it "should send a message to the webhook url and return false when the service doesn't return a 200" do
103
+ FakeWeb.register_uri(:post, 'http://foo.com', :body => "Nothing here", :status => ["404", "Not Found"])
104
+ @transport.send_message(@message).should == false
105
+ end
106
+
107
+ it "should add errors to the transport when an exception is raised" do
108
+ Net::HTTP.stub!(:start).and_raise(Timeout::Error)
109
+ FakeWeb.register_uri(:post, 'http://foo.com', :body => "Nothing here", :status => ["404", "Not Found"])
110
+ @transport.send_message @message
111
+
112
+ @transport.errors.should_not be_nil
113
+ end
114
+ end
115
+ end
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: envoy
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Carlos Rodriguez
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-12-17 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: broach
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - "="
28
+ - !ruby/object:Gem::Version
29
+ hash: 21
30
+ segments:
31
+ - 0
32
+ - 2
33
+ - 1
34
+ version: 0.2.1
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: i18n
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 11
46
+ segments:
47
+ - 0
48
+ - 5
49
+ - 0
50
+ version: 0.5.0
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: pony
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - "="
60
+ - !ruby/object:Gem::Version
61
+ hash: 13
62
+ segments:
63
+ - 1
64
+ - 1
65
+ version: "1.1"
66
+ type: :runtime
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ name: rspec
70
+ prerelease: false
71
+ requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ hash: 11
77
+ segments:
78
+ - 2
79
+ - 1
80
+ - 0
81
+ version: 2.1.0
82
+ type: :development
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ name: fakeweb
86
+ prerelease: false
87
+ requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - "="
91
+ - !ruby/object:Gem::Version
92
+ hash: 27
93
+ segments:
94
+ - 1
95
+ - 3
96
+ - 0
97
+ version: 1.3.0
98
+ type: :development
99
+ version_requirements: *id005
100
+ description: A simple, extendable messaging system built for deployments
101
+ email:
102
+ - carlos@eddorre.com
103
+ executables: []
104
+
105
+ extensions: []
106
+
107
+ extra_rdoc_files: []
108
+
109
+ files:
110
+ - .gitignore
111
+ - Gemfile
112
+ - Gemfile.lock
113
+ - README
114
+ - Rakefile
115
+ - envoy.gemspec
116
+ - lib/envoy.rb
117
+ - lib/envoy/message.rb
118
+ - lib/envoy/messenger.rb
119
+ - lib/envoy/transport.rb
120
+ - lib/envoy/version.rb
121
+ - spec/messenger_spec.rb
122
+ - spec/transport_spec.rb
123
+ has_rdoc: true
124
+ homepage: http://github.com/eddorre/envoy
125
+ licenses: []
126
+
127
+ post_install_message:
128
+ rdoc_options: []
129
+
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ none: false
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ hash: 3
138
+ segments:
139
+ - 0
140
+ version: "0"
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ none: false
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ hash: 3
147
+ segments:
148
+ - 0
149
+ version: "0"
150
+ requirements: []
151
+
152
+ rubyforge_project: envoy
153
+ rubygems_version: 1.3.7
154
+ signing_key:
155
+ specification_version: 3
156
+ summary: A simple, extendable messaging system built for deployments
157
+ test_files:
158
+ - spec/messenger_spec.rb
159
+ - spec/transport_spec.rb