viaduct 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1 +1,2 @@
1
1
  Gemfile.lock
2
+ tmp/
data/Gemfile CHANGED
@@ -1,3 +1,9 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
+
5
+ group :test, :development do
6
+ gem 'guard'
7
+ gem 'guard-rspec'
8
+ gem 'rb-fsevent', '~> 0.9'
9
+ end
data/Guardfile CHANGED
@@ -1,4 +1,4 @@
1
- guard 'rspec', :version => 2 do
1
+ guard 'rspec' do
2
2
  watch(%r{^spec/.+_spec\.rb$})
3
3
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
4
  watch('spec/spec_helper.rb') { "spec" }
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License
2
2
 
3
- Copyright (c) 2010-2012Mitchell Hashimoto and John Bender
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
- * Source: [https://github.com/slack/viaduct](https://github.com/slack/viaduct)
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
- Use the middleware pattern in your application.
7
+ * Source: [https://github.com/slack/viaduct](https://github.com/slack/viaduct)
6
8
 
7
- Extracted from the very excellent [Vagrant](http://vagrantup.com) Mitchell Hashimoto and John Bender
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
- $ bundle exec rake
107
+ $ bundle exec rake
26
108
 
27
109
  Or automatically run tests with guard
28
110
 
29
- $ bundle exec guard
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
@@ -1,19 +1,16 @@
1
1
  module Viaduct
2
2
  class Runner
3
- def initialize(globals=nil, &block)
4
- @globals = globals || {}
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 registered action." if !callable || !callable.respond_to?(:call)
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)
@@ -1,3 +1,3 @@
1
1
  module Viaduct
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -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($stderr)
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) { described_class.new }
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.3
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: 2012-11-19 00:00:00.000000000 Z
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: