pipeline.rb 0.0.1
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.
- checksums.yaml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +25 -0
- data/LINCENSE +21 -0
- data/README.md +141 -0
- data/example/Gemfile +12 -0
- data/example/Gemfile.lock +52 -0
- data/example/README.md +38 -0
- data/example/app.rb +29 -0
- data/example/config/amqp.json +5 -0
- data/example/config/smtp.json +9 -0
- data/example/config/smtp.local.json +4 -0
- data/example/tasks.rb +11 -0
- data/lib/pipeline/client.rb +98 -0
- data/lib/pipeline/plugin.rb +63 -0
- data/lib/pipeline/tasks.rb +16 -0
- data/lib/pipeline/version.rb +3 -0
- data/pipeline.rb.gemspec +20 -0
- data/spec/data/app/config/amqp.json +5 -0
- data/spec/data/app/config/smtp.json +8 -0
- data/spec/data/app/config/smtp.local.json +4 -0
- data/spec/data/app/config/test.json +3 -0
- data/spec/plugin_spec.rb +42 -0
- data/spec/spec_helper.rb +3 -0
- metadata +81 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 197e078f9b2e93718eedbde53a8c453536c166a2
|
4
|
+
data.tar.gz: ff87a1819aacea18aa67db93c54c1364d14d388e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 90ab0ea4b657163aaf74ffd388377ac730e073292a56ccfab08fe9ea70f60d1e091dc6ed5205729b107bc22593e4725f0e2ce2ea4173231fb4d77d9b2ecd848d
|
7
|
+
data.tar.gz: 8e176b651fc34d7d05e18d510214c9967f5e867bcd6c40997377abf5603f1a1392f0e1b79fd6284eb399235d7b361921fef458142979e969e118b1e317b74a31
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
pipeline.rb (0.0.1)
|
5
|
+
amq-client
|
6
|
+
|
7
|
+
GEM
|
8
|
+
specs:
|
9
|
+
amq-client (1.0.4)
|
10
|
+
amq-protocol (>= 1.9.0)
|
11
|
+
eventmachine
|
12
|
+
amq-protocol (1.9.2)
|
13
|
+
diff-lcs (1.2.5)
|
14
|
+
eventmachine (1.0.3)
|
15
|
+
rspec-core (2.14.7)
|
16
|
+
rspec-expectations (2.14.4)
|
17
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
18
|
+
|
19
|
+
PLATFORMS
|
20
|
+
ruby
|
21
|
+
|
22
|
+
DEPENDENCIES
|
23
|
+
pipeline.rb!
|
24
|
+
rspec-core
|
25
|
+
rspec-expectations
|
data/LINCENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 @botanicus
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
# About
|
2
|
+
|
3
|
+
Plugin pipeline infrastructure connected **through RabbitMQ**. The plugins are just **normal Ruby gems**.
|
4
|
+
|
5
|
+
```
|
6
|
+
Instance(s) of plugin 1 -> RabbitMQ broker -> Instance(s) of plugin 2
|
7
|
+
```
|
8
|
+
|
9
|
+
It uses `amq.topic` exchange, so **you can use globs** to consume from within a plugin or a custom script. So if you want to see all the messages going through the system, simply create a queue a bind it to `amq.topic` with routing key `#`. Need all the events? `#event#`. Easy as that.
|
10
|
+
|
11
|
+
# Why?
|
12
|
+
|
13
|
+
It's been proved over and over that splitting app into services and is the way to go, because:
|
14
|
+
|
15
|
+
* It's **easier to maintain** such app.
|
16
|
+
* **Rewriting components** is easy.
|
17
|
+
* It's **easy to scale** by adding more consumers of given service.
|
18
|
+
* It's **easy to inspect** what's going on.
|
19
|
+
* It's much **easier to split work** on the project between multiple developers.
|
20
|
+
* You can **restart services without losing any data**, as they are kept in RabbitMQ.
|
21
|
+
* You don't have to introduce any code dependencies: just consume given queue and publish to another one.
|
22
|
+
|
23
|
+
# Settings
|
24
|
+
|
25
|
+
Pipeline.rb uses JSON for configuration.
|
26
|
+
|
27
|
+
The cool thing is it supports global and local configuration. That means for instance if you want to configure a database, you're probably going to use the same database drivers on either development machine or on production server.
|
28
|
+
|
29
|
+
So first let's create a global configuration file `config/database.json`:
|
30
|
+
|
31
|
+
```json
|
32
|
+
{
|
33
|
+
"adapter": "mysql",
|
34
|
+
"username": "mysql",
|
35
|
+
"database": "example"
|
36
|
+
}
|
37
|
+
```
|
38
|
+
|
39
|
+
And now the local `config/database.local.json`:
|
40
|
+
|
41
|
+
```json
|
42
|
+
{
|
43
|
+
"password": "ae28cd87adb5c385117f89e9bd452d18"
|
44
|
+
}
|
45
|
+
```
|
46
|
+
|
47
|
+
Don't forget to ignore the local settings `.gitignore`:
|
48
|
+
|
49
|
+
```
|
50
|
+
config/*.local.json
|
51
|
+
```
|
52
|
+
|
53
|
+
# HOWTO
|
54
|
+
|
55
|
+
Pipeline.rb expects you to provide AMQP configuration, so it knows how to connect to RabbitMQ:
|
56
|
+
|
57
|
+
`config/amqp.json`:
|
58
|
+
|
59
|
+
```json
|
60
|
+
{
|
61
|
+
"vhost": "example",
|
62
|
+
"user": "example",
|
63
|
+
}
|
64
|
+
```
|
65
|
+
|
66
|
+
`config/amqp.local.json`:
|
67
|
+
|
68
|
+
```json
|
69
|
+
{
|
70
|
+
"password": "ae28cd87adb5c385117f89e9bd452d18"
|
71
|
+
}
|
72
|
+
```
|
73
|
+
|
74
|
+
Don't forget to ignore the local settings `.gitignore`:
|
75
|
+
|
76
|
+
```
|
77
|
+
config/*.local.json
|
78
|
+
```
|
79
|
+
|
80
|
+
Shop for plugins and add them to your `Gemfile`:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
source 'https://rubygems.org'
|
84
|
+
|
85
|
+
# The app uses pipeline.rb itself.
|
86
|
+
gem 'pipeline.rb'
|
87
|
+
|
88
|
+
# Tasks.
|
89
|
+
gem 'nake'
|
90
|
+
|
91
|
+
# Existing pipeline.rb plugins.
|
92
|
+
group(:plugins) do
|
93
|
+
gem 'mail_queue'
|
94
|
+
end
|
95
|
+
```
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
#!/usr/bin/env bundle exec ruby
|
99
|
+
|
100
|
+
require 'nake/runner'
|
101
|
+
|
102
|
+
# Load all the plugins.
|
103
|
+
Bundler.require(:plugins)
|
104
|
+
|
105
|
+
# Tasks: declare.
|
106
|
+
require 'pipeline/tasks'
|
107
|
+
|
108
|
+
Nake.run
|
109
|
+
```
|
110
|
+
|
111
|
+
Now run `./tasks.rb declare` to declare all the required queues.
|
112
|
+
|
113
|
+
And finally create your app:
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
require 'mail_queue'
|
117
|
+
|
118
|
+
# This is already loaded,
|
119
|
+
# but just to make it clear
|
120
|
+
# that the app is actually
|
121
|
+
# just another plugin.
|
122
|
+
require 'pipeline/plugin'
|
123
|
+
|
124
|
+
class App < Pipeline::Plugin
|
125
|
+
def run
|
126
|
+
EM.add_timer(0.5) do
|
127
|
+
client.publish("Hello World!", 'emails.random')
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
And finally run it all:
|
134
|
+
|
135
|
+
1. Start RabbitMQ.
|
136
|
+
2. Start `bin/mail_queue.rb` to send your emails.
|
137
|
+
3. Run your app.
|
138
|
+
|
139
|
+
# Deployment
|
140
|
+
|
141
|
+
TODO: Show example Upstart scripts.
|
data/example/Gemfile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Local Machine
|
4
|
+
# bundle config local.pipeline-mail_queue ~/Dropbox/Code/pipeline-plugins/mail_queue
|
5
|
+
# bundle config local.pipeline.rb ~/Dropbox/Code/sources/pipeline.rb
|
6
|
+
# bundle config local.nake ~/Dropbox/Code/sources/nake
|
7
|
+
gem 'pipeline.rb', github: 'botanicus/pipeline.rb', branch: 'master'
|
8
|
+
gem 'nake', github: 'botanicus/nake', branch: 'master'
|
9
|
+
|
10
|
+
group(:plugins) do
|
11
|
+
gem 'pipeline-mail_queue', github: 'botanicus/pipeline-mail_queue', branch: 'master'
|
12
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/botanicus/nake.git
|
3
|
+
revision: 6361daacec1caa6af9e12e7e52e0fcb6cf1b91ac
|
4
|
+
branch: master
|
5
|
+
specs:
|
6
|
+
nake (0.0.9.5)
|
7
|
+
term-ansicolor
|
8
|
+
|
9
|
+
GIT
|
10
|
+
remote: git://github.com/botanicus/pipeline-mail_queue.git
|
11
|
+
revision: 5f860a6a01de0a85f181e918f1432c05a20b5b37
|
12
|
+
branch: master
|
13
|
+
specs:
|
14
|
+
pipeline-mail_queue (0.0.1)
|
15
|
+
mail
|
16
|
+
pipeline.rb
|
17
|
+
|
18
|
+
GIT
|
19
|
+
remote: git://github.com/botanicus/pipeline.rb.git
|
20
|
+
revision: 345259bc7bc48b8e3a5cc6e8e2594aaefe2bfa96
|
21
|
+
branch: master
|
22
|
+
specs:
|
23
|
+
pipeline.rb (0.0.1)
|
24
|
+
amq-client
|
25
|
+
|
26
|
+
GEM
|
27
|
+
remote: https://rubygems.org/
|
28
|
+
specs:
|
29
|
+
amq-client (1.0.4)
|
30
|
+
amq-protocol (>= 1.9.0)
|
31
|
+
eventmachine
|
32
|
+
amq-protocol (1.9.2)
|
33
|
+
eventmachine (1.0.3)
|
34
|
+
mail (2.5.4)
|
35
|
+
mime-types (~> 1.16)
|
36
|
+
treetop (~> 1.4.8)
|
37
|
+
mime-types (1.25.1)
|
38
|
+
polyglot (0.3.3)
|
39
|
+
term-ansicolor (1.2.2)
|
40
|
+
tins (~> 0.8)
|
41
|
+
tins (0.13.1)
|
42
|
+
treetop (1.4.15)
|
43
|
+
polyglot
|
44
|
+
polyglot (>= 0.3.1)
|
45
|
+
|
46
|
+
PLATFORMS
|
47
|
+
ruby
|
48
|
+
|
49
|
+
DEPENDENCIES
|
50
|
+
nake!
|
51
|
+
pipeline-mail_queue!
|
52
|
+
pipeline.rb!
|
data/example/README.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# About
|
2
|
+
|
3
|
+
# Setup
|
4
|
+
|
5
|
+
## Set Up and Run RabbitMQ
|
6
|
+
|
7
|
+
```bash
|
8
|
+
rabbitmqctl add_user example ae28cd87adb5c385117f89e9bd452d18
|
9
|
+
rabbitmqctl add_vhost example
|
10
|
+
rabbitmqctl set_permissions -p example example '.*' '.*' '.*'
|
11
|
+
```
|
12
|
+
|
13
|
+
## Fill In Your Gmail Details
|
14
|
+
|
15
|
+
`config/smtp.local.json`
|
16
|
+
|
17
|
+
```json
|
18
|
+
{
|
19
|
+
"user_name": "you@gmail.com",
|
20
|
+
"password": "password",
|
21
|
+
}
|
22
|
+
```
|
23
|
+
|
24
|
+
## Run Bundler
|
25
|
+
|
26
|
+
`bundle install`
|
27
|
+
|
28
|
+
## Declare Queues
|
29
|
+
|
30
|
+
`./tasks.rb declare`
|
31
|
+
|
32
|
+
## Run `mail_queue` Consumer
|
33
|
+
|
34
|
+
`bundle exec mail_queue.rb`
|
35
|
+
|
36
|
+
## Run The App
|
37
|
+
|
38
|
+
`./app.rb`
|
data/example/app.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env bundle exec ruby
|
2
|
+
|
3
|
+
require 'mail_queue'
|
4
|
+
|
5
|
+
# This is already loaded,
|
6
|
+
# but just to make it clear
|
7
|
+
# that the app is actually
|
8
|
+
# just another plugin.
|
9
|
+
require 'pipeline/plugin'
|
10
|
+
|
11
|
+
$receiver_email = (ARGV.shift || abort("Usage: #{$0} [receiver_email"))
|
12
|
+
|
13
|
+
class App < Pipeline::Plugin
|
14
|
+
def run
|
15
|
+
email = Mail.new do
|
16
|
+
from 'james@101ideas.cz'
|
17
|
+
to $receiver_email
|
18
|
+
subject "Hello World!"
|
19
|
+
body "Hello World!"
|
20
|
+
end
|
21
|
+
|
22
|
+
EM.add_periodic_timer(1.5) do
|
23
|
+
puts "~ Publishing #{email.inspect}"
|
24
|
+
client.publish(email.to_s, 'emails.random')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
App.run(Dir.pwd)
|
data/example/tasks.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'amq/client'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
# We aren't handling TCP connection lost, since this is running on the same machine.
|
6
|
+
# It means, however, that if we restart the broker, we have to restart all the services manually.
|
7
|
+
module Pipeline
|
8
|
+
class Client
|
9
|
+
def self.boot(config)
|
10
|
+
client = self.new
|
11
|
+
|
12
|
+
# Next tick, so we can use it with Thin.
|
13
|
+
EM.next_tick do
|
14
|
+
client.connect(config.merge(adapter: 'eventmachine'))
|
15
|
+
|
16
|
+
# Set up signals.
|
17
|
+
['INT', 'TERM'].each do |signal|
|
18
|
+
Signal.trap(signal) do
|
19
|
+
puts "~ Received #{signal} signal, terminating."
|
20
|
+
client.disconnect { EM.stop }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
client
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
@on_open_callbacks = Array.new
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :connection, :channel, :exchange, :on_open_callbacks
|
33
|
+
def connect(opts)
|
34
|
+
@connection = AMQ::Client.connect(opts)
|
35
|
+
@channel = AMQ::Client::Channel.new(@connection, 1)
|
36
|
+
|
37
|
+
@connection.on_open do
|
38
|
+
puts "~ Connected to RabbitMQ."
|
39
|
+
|
40
|
+
@channel.open do
|
41
|
+
self.on_open_callbacks.each do |callback|
|
42
|
+
callback.call
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def exchange
|
49
|
+
@exchange ||= AMQ::Client::Exchange.new(@connection, @channel, 'amq.topic')
|
50
|
+
end
|
51
|
+
|
52
|
+
def declare_queue(name, routing_key)
|
53
|
+
queue = AMQ::Client::Queue.new(@connection, @channel, name)
|
54
|
+
|
55
|
+
self.on_open do
|
56
|
+
queue.declare(false, true, false, true) do
|
57
|
+
# puts "~ Queue #{queue.name.inspect} is ready"
|
58
|
+
end
|
59
|
+
|
60
|
+
queue.bind(self.exchange.name, routing_key) do
|
61
|
+
puts "~ Queue #{queue.name} is now bound to #{self.exchange.name} with routing key #{routing_key}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
queue
|
66
|
+
end
|
67
|
+
|
68
|
+
def consumer(name, routing_key = name, &block)
|
69
|
+
queue = self.declare_queue(name, routing_key)
|
70
|
+
|
71
|
+
queue.consume(true) do |consume_ok|
|
72
|
+
puts "Subscribed for messages routed to #{queue.name}, consumer tag is #{consume_ok.consumer_tag}, using no-ack mode"
|
73
|
+
|
74
|
+
queue.on_delivery do |basic_deliver, header, payload|
|
75
|
+
block.call(payload, header, basic_deliver)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# This runs after the channel is open.
|
81
|
+
# TODO: Why amq-client doesn't support adding multiple callbacks?
|
82
|
+
def on_open(&block)
|
83
|
+
if @channel.status == :opening
|
84
|
+
self.on_open_callbacks << block
|
85
|
+
else
|
86
|
+
block.call
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def publish(*args)
|
91
|
+
self.exchange.publish(*args)
|
92
|
+
end
|
93
|
+
|
94
|
+
def disconnect(&block)
|
95
|
+
@connection.disconnect(&block)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'pathname'
|
3
|
+
require 'pipeline/client'
|
4
|
+
|
5
|
+
module Pipeline
|
6
|
+
class Plugin
|
7
|
+
def self.plugins
|
8
|
+
@@plugins ||= Array.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.inherited(subclass)
|
12
|
+
Pipeline::Plugin.plugins << subclass
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.run(root)
|
16
|
+
plugin = self.new(root)
|
17
|
+
|
18
|
+
Dir.chdir(plugin.root.to_s) do
|
19
|
+
EM.run do
|
20
|
+
# First runs next tick from Client.boot.
|
21
|
+
EM.next_tick do
|
22
|
+
plugin.run!
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :root
|
29
|
+
def initialize(root)
|
30
|
+
@root = Pathname.new(root)
|
31
|
+
@config = Hash.new
|
32
|
+
|
33
|
+
self.client
|
34
|
+
end
|
35
|
+
|
36
|
+
def config(key)
|
37
|
+
@config[key] ||= begin
|
38
|
+
path = self.root.join("config/#{key}.json")
|
39
|
+
data = JSON.parse(path.read)
|
40
|
+
|
41
|
+
path = self.root.join("config/#{key}.local.json")
|
42
|
+
data.merge!(JSON.parse(path.read)) if path.exist?
|
43
|
+
|
44
|
+
data.reduce(Hash.new) do |buffer, (key, value)|
|
45
|
+
buffer.merge!(key.to_sym => value)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def client
|
51
|
+
@client ||= Pipeline::Client.boot(self.config('amqp'))
|
52
|
+
end
|
53
|
+
|
54
|
+
def run!
|
55
|
+
self.client.on_open do
|
56
|
+
EM.add_timer(0.1) do # Oh my, yeah, whatever, it's for now only, dammit!
|
57
|
+
puts "~ Running #{self.class}#run."
|
58
|
+
self.run
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'nake'
|
2
|
+
|
3
|
+
Nake::Task.new(:queues) do |task|
|
4
|
+
task.define do
|
5
|
+
Pipeline::Plugin.plugins.each do |plugin|
|
6
|
+
puts "#{plugin}: #{plugin::QUEUES.inspect rescue []}"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
Nake::Task.new(:declare) do |task|
|
13
|
+
task.define do
|
14
|
+
abort "Still on the TODO list.\nFor now, just run all the consumers and everything gets declared at runtime."
|
15
|
+
end
|
16
|
+
end
|
data/pipeline.rb.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env gem build
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
|
4
|
+
|
5
|
+
require 'pipeline/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = 'pipeline.rb'
|
9
|
+
s.version = Pipeline::VERSION
|
10
|
+
s.authors = ['@botanicus']
|
11
|
+
s.homepage = 'http://github.com/botanicus/pipeline.rb'
|
12
|
+
s.summary = "Plugin pipeline infrastructure connected through RabbitMQ."
|
13
|
+
s.description = "#{s.summary}. Asynchronous and robust. Also contains configuration system."
|
14
|
+
s.email = 'james@101ideas.cz'
|
15
|
+
s.files = Dir.glob('**/*')
|
16
|
+
s.license = 'MIT'
|
17
|
+
s.require_paths = ['lib']
|
18
|
+
|
19
|
+
s.add_dependency 'amq-client'
|
20
|
+
end
|
data/spec/plugin_spec.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'pipeline/plugin'
|
4
|
+
|
5
|
+
describe Pipeline::Plugin do
|
6
|
+
describe '#new(root)' do
|
7
|
+
it "takes one argument which is the root directory" do
|
8
|
+
expect { described_class.new(File.join(Dir.pwd, 'spec', 'data', 'app')) }.not_to raise_error
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#root' do
|
13
|
+
subject { described_class.new(File.join(Dir.pwd, 'spec', 'data', 'app')) }
|
14
|
+
|
15
|
+
it "returns path to the root directory" do
|
16
|
+
subject.root.should be_kind_of(Pathname)
|
17
|
+
subject.root.to_s.should match('pipeline.rb/spec/data/app')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#config' do
|
22
|
+
subject { described_class.new(File.join(Dir.pwd, 'spec', 'data', 'app')) }
|
23
|
+
|
24
|
+
let(:config) { subject.config('smtp') }
|
25
|
+
|
26
|
+
it "contains the global settings" do
|
27
|
+
config[:address].should eql('smtp.gmail.com')
|
28
|
+
end
|
29
|
+
|
30
|
+
it "contains the global settings" do
|
31
|
+
config[:password].should eql('password.local')
|
32
|
+
end
|
33
|
+
|
34
|
+
it "overrides the global settings by the local settings" do
|
35
|
+
config[:user_name].should eql('user.local')
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should not require local settings" do
|
39
|
+
subject.config('test')[:local].should be_false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pipeline.rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- '@botanicus'
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-01-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: amq-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: Plugin pipeline infrastructure connected through RabbitMQ.. Asynchronous
|
28
|
+
and robust. Also contains configuration system.
|
29
|
+
email: james@101ideas.cz
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- example/app.rb
|
35
|
+
- example/config/amqp.json
|
36
|
+
- example/config/smtp.json
|
37
|
+
- example/config/smtp.local.json
|
38
|
+
- example/Gemfile
|
39
|
+
- example/Gemfile.lock
|
40
|
+
- example/README.md
|
41
|
+
- example/tasks.rb
|
42
|
+
- Gemfile
|
43
|
+
- Gemfile.lock
|
44
|
+
- lib/pipeline/client.rb
|
45
|
+
- lib/pipeline/plugin.rb
|
46
|
+
- lib/pipeline/tasks.rb
|
47
|
+
- lib/pipeline/version.rb
|
48
|
+
- LINCENSE
|
49
|
+
- pipeline.rb.gemspec
|
50
|
+
- README.md
|
51
|
+
- spec/data/app/config/amqp.json
|
52
|
+
- spec/data/app/config/smtp.json
|
53
|
+
- spec/data/app/config/smtp.local.json
|
54
|
+
- spec/data/app/config/test.json
|
55
|
+
- spec/plugin_spec.rb
|
56
|
+
- spec/spec_helper.rb
|
57
|
+
homepage: http://github.com/botanicus/pipeline.rb
|
58
|
+
licenses:
|
59
|
+
- MIT
|
60
|
+
metadata: {}
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
requirements: []
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 2.0.3
|
78
|
+
signing_key:
|
79
|
+
specification_version: 4
|
80
|
+
summary: Plugin pipeline infrastructure connected through RabbitMQ.
|
81
|
+
test_files: []
|