viaduct 0.0.3 → 0.1.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 +1 -0
- data/Gemfile +6 -0
- data/Guardfile +1 -1
- data/LICENSE +2 -2
- data/README.md +87 -7
- data/lib/viaduct/runner.rb +3 -6
- data/lib/viaduct/version.rb +1 -1
- data/lib/viaduct/warden.rb +1 -1
- data/spec/integration_spec.rb +64 -0
- data/spec/runner_spec.rb +1 -23
- data/viaduct.gemspec +0 -4
- metadata +8 -53
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Guardfile
CHANGED
data/LICENSE
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License
|
2
2
|
|
3
|
-
Copyright (c) 2010-
|
3
|
+
Copyright (c) 2010-2012 Mitchell Hashimoto and John Bender
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
THE SOFTWARE.
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# Viaduct
|
2
2
|
|
3
|
-
|
3
|
+
Use middleware in your application. Catch exceptions and walk back up the stack!
|
4
|
+
|
5
|
+
Mitchell also created the [middlware](https://github.com/mitchellh/middleware) gem, but it did not contain the warden code which is what interested me the most. Thus, viaduct.
|
4
6
|
|
5
|
-
|
7
|
+
* Source: [https://github.com/slack/viaduct](https://github.com/slack/viaduct)
|
6
8
|
|
7
|
-
Extracted from
|
9
|
+
Extracted from Mitchell Hashimoto and John Bender's very excellent [Vagrant](http://vagrantup.com).
|
8
10
|
|
9
11
|
## Installation
|
10
12
|
|
@@ -20,21 +22,99 @@ Or install it yourself as:
|
|
20
22
|
|
21
23
|
$ gem install viaduct
|
22
24
|
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
If you've spent any time using [rack](http://rack.github.io/) Viaduct will be very familiar.
|
28
|
+
|
29
|
+
Simply:
|
30
|
+
|
31
|
+
1. Define middlware classes that respond to `new` and `call`
|
32
|
+
2. Create your middleware stack with `Viaduct::Builder`
|
33
|
+
3. Run your stack with `Viaduct::Runner`
|
34
|
+
|
35
|
+
For a few examples see the [integration example spec](spec/integration_spec.rb).
|
36
|
+
|
37
|
+
Let's define two middlewares, one that appends text to the environment and one that removes an element.
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
class Add
|
41
|
+
def initialize(app, env)
|
42
|
+
@app, @env = app, env
|
43
|
+
end
|
44
|
+
|
45
|
+
def call(env)
|
46
|
+
env[:data] << "adding"
|
47
|
+
@app.call(env)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class Remove
|
52
|
+
def initialize(app, env)
|
53
|
+
@app, @env = app, env
|
54
|
+
end
|
55
|
+
|
56
|
+
def call(env)
|
57
|
+
env[:data].shift
|
58
|
+
@app.call(env)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
Organize these into a sequence:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
stack = Viaduct::Builder.new do
|
67
|
+
use Add
|
68
|
+
use Remove
|
69
|
+
use Add
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
Then execute that sequence by calling `Viaduct::Runner.run`:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
env = { data: [] }
|
77
|
+
result = Viaduct::Runner.run(stack, env})
|
78
|
+
#=> { data: ['adding'] }
|
79
|
+
```
|
80
|
+
|
81
|
+
### Handling exceptions
|
82
|
+
|
83
|
+
`Viaduct::Runner` is responsible for the execution of your sequence. The first argument to `run` should be either a sequence from `Viaduct::Builder` or a ruby class that responds to `call`.
|
84
|
+
|
85
|
+
Runner will hand the `env` hash to each of your middlwares, handling any excpetions. In the event that any down-stream middlware raises, Viaduct will walk back up the stack calling `recover` on each middleware see [handling exceptions example](spec/integration_spec.rb).
|
86
|
+
|
87
|
+
### Debugging
|
88
|
+
|
89
|
+
If you pass in an instance of `Logger` to `Viaduct::Runner` (or something that looks like a logger) Viaduct will add happily log execution information:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
sequence = Viaduct::Builder.new do
|
93
|
+
use Robust
|
94
|
+
use Flaky
|
95
|
+
end
|
96
|
+
|
97
|
+
Viaduct::Runner.run(sequence, logger: Logger.new($stderr))
|
98
|
+
#I, [2013-04-19T22:28:29.931249 #847] INFO -- : Calling action: #<Robust:0x007fb20255bf98>
|
99
|
+
#I, [2013-04-19T22:28:29.931329 #847] INFO -- : Calling action: #<Flaky:0x007fb20255bf48>
|
100
|
+
#E, [2013-04-19T22:28:29.931404 #847] ERROR -- : Error occurred: I'm having trouble
|
101
|
+
#I, [2013-04-19T22:28:29.931441 #847] INFO -- : Calling recover: #<Robust:0x007fb20255bf98>
|
102
|
+
#E, [2013-04-19T22:28:29.931488 #847] ERROR -- : Error occurred: I'm having trouble
|
103
|
+
```
|
104
|
+
|
23
105
|
## Tests
|
24
106
|
|
25
|
-
|
107
|
+
$ bundle exec rake
|
26
108
|
|
27
109
|
Or automatically run tests with guard
|
28
110
|
|
29
|
-
|
111
|
+
$ bundle exec guard
|
30
112
|
|
31
113
|
## Releasing
|
32
114
|
|
33
115
|
$ gem install gem-release
|
34
116
|
$ gem bump -trv patch
|
35
117
|
|
36
|
-
## Usage
|
37
|
-
|
38
118
|
## Contributing
|
39
119
|
|
40
120
|
1. Fork it
|
data/lib/viaduct/runner.rb
CHANGED
@@ -1,19 +1,16 @@
|
|
1
1
|
module Viaduct
|
2
2
|
class Runner
|
3
|
-
def
|
4
|
-
|
5
|
-
@lazy_globals = block
|
3
|
+
def self.run(app, options=nil)
|
4
|
+
new.run(app, options)
|
6
5
|
end
|
7
6
|
|
8
7
|
def run(callable_id, options=nil)
|
9
8
|
callable = callable_id
|
10
9
|
callable = Builder.new.use(callable_id) if callable_id.kind_of?(Class)
|
11
|
-
raise ArgumentError, "Argument to run must be a callable object or
|
10
|
+
raise ArgumentError, "Argument to run must be a callable object or known class." if !callable || !callable.respond_to?(:call)
|
12
11
|
|
13
12
|
# Create the initial environment with the options given
|
14
13
|
environment = Environment.new
|
15
|
-
environment.merge!(@globals)
|
16
|
-
environment.merge!(@lazy_globals.call) if @lazy_globals
|
17
14
|
environment.merge!(options || {})
|
18
15
|
|
19
16
|
callable.call(environment)
|
data/lib/viaduct/version.rb
CHANGED
data/lib/viaduct/warden.rb
CHANGED
@@ -17,7 +17,7 @@ module Viaduct
|
|
17
17
|
def initialize(actions, env)
|
18
18
|
@stack = []
|
19
19
|
@actions = actions.map { |m| finalize_action(m, env) }
|
20
|
-
@logger = env.has_key?(:logger) ? env[:logger] : Logger.new(
|
20
|
+
@logger = env.has_key?(:logger) ? env[:logger] : Logger.new(nil)
|
21
21
|
end
|
22
22
|
|
23
23
|
def call(env)
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "a simple set of middlwares" do
|
4
|
+
class Add
|
5
|
+
def initialize(app, env); @app, @env = app, env; end
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
env[:data] << "adding"
|
9
|
+
@app.call(env)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Remove
|
14
|
+
def initialize(app, env); @app, @env = app, env; end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
env[:data].shift
|
18
|
+
@app.call(env)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "works" do
|
23
|
+
stack = Viaduct::Builder.new do
|
24
|
+
use Add
|
25
|
+
use Remove
|
26
|
+
use Add
|
27
|
+
end
|
28
|
+
|
29
|
+
env = Viaduct::Runner.run(stack, {data: []})
|
30
|
+
env[:data].should == ['adding']
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "handling exceptions" do
|
35
|
+
class Robust
|
36
|
+
def initialize(app, env); @app, @env = app, env; end
|
37
|
+
|
38
|
+
def call(env)
|
39
|
+
@app.call(env)
|
40
|
+
end
|
41
|
+
|
42
|
+
def recover(env)
|
43
|
+
env[:logger].error "I got this!"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Flaky
|
48
|
+
class OMG < StandardError; end
|
49
|
+
|
50
|
+
def initialize(app, env); @app, @env = app, env; end
|
51
|
+
|
52
|
+
def call(env)
|
53
|
+
raise OMG.new("I'm having trouble")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
let(:sequence) { Viaduct::Builder.new { use Robust; use Flaky } }
|
58
|
+
|
59
|
+
it "has a chance to handle exceptions" do
|
60
|
+
expect {
|
61
|
+
Viaduct::Runner.run(sequence, { logger: Logger.new(nil) })
|
62
|
+
}.to raise_error Flaky::OMG
|
63
|
+
end
|
64
|
+
end
|
data/spec/runner_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Viaduct::Runner do
|
4
|
-
let(:instance) {
|
4
|
+
let(:instance) { Viaduct::Runner.new }
|
5
5
|
|
6
6
|
it "should raise an error if an invalid callable is given" do
|
7
7
|
expect { instance.run(7) }.to raise_error(ArgumentError, /must be a callable/)
|
@@ -34,26 +34,4 @@ describe Viaduct::Runner do
|
|
34
34
|
instance.run(callable, "data" => "foo")
|
35
35
|
result.should == "foo"
|
36
36
|
end
|
37
|
-
|
38
|
-
it "should pass global options into the hash" do
|
39
|
-
result = nil
|
40
|
-
callable = lambda do |env|
|
41
|
-
result = env["data"]
|
42
|
-
end
|
43
|
-
|
44
|
-
instance = described_class.new("data" => "bar")
|
45
|
-
instance.run(callable)
|
46
|
-
result.should == "bar"
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should yield the block passed to the init method to get lazy loaded globals" do
|
50
|
-
result = nil
|
51
|
-
callable = lambda do |env|
|
52
|
-
result = env["data"]
|
53
|
-
end
|
54
|
-
|
55
|
-
instance = described_class.new { { "data" => "bar" } }
|
56
|
-
instance.run(callable)
|
57
|
-
result.should == "bar"
|
58
|
-
end
|
59
37
|
end
|
data/viaduct.gemspec
CHANGED
@@ -16,8 +16,4 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
|
-
|
20
|
-
gem.add_development_dependency "rake"
|
21
|
-
gem.add_development_dependency "guard"
|
22
|
-
gem.add_development_dependency "rspec", "~> 2.10.0"
|
23
19
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: viaduct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,56 +9,8 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: rake
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '0'
|
22
|
-
type: :development
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ! '>='
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0'
|
30
|
-
- !ruby/object:Gem::Dependency
|
31
|
-
name: guard
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
|
-
requirements:
|
35
|
-
- - ! '>='
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
version: '0'
|
38
|
-
type: :development
|
39
|
-
prerelease: false
|
40
|
-
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
|
-
requirements:
|
43
|
-
- - ! '>='
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: '0'
|
46
|
-
- !ruby/object:Gem::Dependency
|
47
|
-
name: rspec
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
|
-
requirements:
|
51
|
-
- - ~>
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: 2.10.0
|
54
|
-
type: :development
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ~>
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 2.10.0
|
12
|
+
date: 2013-04-20 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
62
14
|
description: Build stuff with middlware.
|
63
15
|
email:
|
64
16
|
- jhansen@slack.io
|
@@ -83,6 +35,7 @@ files:
|
|
83
35
|
- lib/viaduct/warden.rb
|
84
36
|
- spec/builder_spec.rb
|
85
37
|
- spec/environment_spec.rb
|
38
|
+
- spec/integration_spec.rb
|
86
39
|
- spec/runner_spec.rb
|
87
40
|
- spec/spec_helper.rb
|
88
41
|
- spec/warden_spec.rb
|
@@ -94,17 +47,17 @@ rdoc_options: []
|
|
94
47
|
require_paths:
|
95
48
|
- lib
|
96
49
|
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
50
|
requirements:
|
99
51
|
- - ! '>='
|
100
52
|
- !ruby/object:Gem::Version
|
101
53
|
version: '0'
|
102
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
54
|
none: false
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
56
|
requirements:
|
105
57
|
- - ! '>='
|
106
58
|
- !ruby/object:Gem::Version
|
107
59
|
version: '0'
|
60
|
+
none: false
|
108
61
|
requirements: []
|
109
62
|
rubyforge_project:
|
110
63
|
rubygems_version: 1.8.24
|
@@ -114,6 +67,8 @@ summary: Extracted from vagrant, viaduct makes it easy to build up middlware.
|
|
114
67
|
test_files:
|
115
68
|
- spec/builder_spec.rb
|
116
69
|
- spec/environment_spec.rb
|
70
|
+
- spec/integration_spec.rb
|
117
71
|
- spec/runner_spec.rb
|
118
72
|
- spec/spec_helper.rb
|
119
73
|
- spec/warden_spec.rb
|
74
|
+
has_rdoc:
|