midler 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f2237664840e88240019d59937eb343b6e109f7c
4
+ data.tar.gz: 8369600f8a0ae3b9b26890378e991842b2446138
5
+ SHA512:
6
+ metadata.gz: bd98a7aa3a7465ae44468292a789002e6db8afee3c820d56ab5c29b02a26bb39f2311710b6c9072317fea4241a13eaf83802155e3b21784fa0cb5ee4c9d5c13b
7
+ data.tar.gz: d775a38ce73e3f5000a984f7b257591e6b1c045d8cfbcb90a5de93b2c9a7a4c8daacd7eacc8cb55b2a7b76e8b80a6bc6c4febc432148ccc2c5cf50a1bba9f430
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in midler.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # Midler
2
+
3
+ This is a fork of [Middleware](https://github.com/mitchellh/middleware) that allows multiple env arguments, and is fully backward compatible. Refer to the parent gem for additional documentation.
4
+
5
+ ![Recite: "boil, boil, toil and trouble..."](midler.jpg)
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'midler'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install midler
22
+
23
+ ## Variadic Middleware Usage
24
+
25
+ This is where this fork of the gem really shines. We can now pass variadic arguments in place of env. For example, we can now call the stack with a `request` and `response` for this express-style webserver example.
26
+
27
+ ```ruby
28
+ class JsonResponse
29
+ def initialize(app)
30
+ @app = app
31
+ end
32
+
33
+ def call(request, response)
34
+ Logger.info { "Received #{request[:body]} from request" }
35
+ response[:accept] = "application/json"
36
+ @app.call(request, response)
37
+ end
38
+ end
39
+
40
+ stack = Midler::Builder.new do
41
+ use JsonResponse
42
+ use Authenticate
43
+ use Authorized
44
+ end
45
+
46
+ # Run it!
47
+ stack.call(request, response)
48
+ ```
49
+
50
+ ## Singular Env Usage
51
+
52
+ Once you create a basic middleware, you can use the builder to
53
+ have a nice DSL to build middleware stacks. Calling the middleware
54
+ is simple, as well.
55
+
56
+ ```ruby
57
+ # Basic middleware that just prints the inbound and
58
+ # outbound steps.
59
+ class Trace
60
+ def initialize(app, value)
61
+ @app = app
62
+ @value = value
63
+ end
64
+
65
+ def call(env)
66
+ puts "--> #{@value}"
67
+ @app.call(env)
68
+ puts "<-- #{@value}"
69
+ end
70
+ end
71
+
72
+ # Build the actual middleware stack which runs a sequence
73
+ # of slightly different versions of our middleware.
74
+ stack = Midler::Builder.new do
75
+ use Trace, "A"
76
+ use Trace, "B"
77
+ use Trace, "C"
78
+ end
79
+
80
+ # Run it!
81
+ stack.call(nil)
82
+ ```
83
+
84
+ And the output:
85
+
86
+ ```
87
+ --> A
88
+ --> B
89
+ --> C
90
+ <-- C
91
+ <-- B
92
+ <-- A
93
+ ```
94
+
95
+ ## Development
96
+
97
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
98
+
99
+ ## Contributing
100
+
101
+ 1. Fork it ( https://github.com/film42/midler/fork )
102
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
103
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
104
+ 4. Push to the branch (`git push origin my-new-feature`)
105
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
4
+
5
+ # RSpec test task
6
+ RSpec::Core::RakeTask.new
7
+
8
+ # Make sure the default is to run RSpec
9
+ task :default => "spec"
@@ -0,0 +1,135 @@
1
+ module Midler
2
+ # This provides a DSL for building up a stack of middlewares.
3
+ #
4
+ # This code is based heavily off of `Rack::Builder` and
5
+ # `ActionDispatch::MiddlewareStack` in Rack and Rails, respectively.
6
+ #
7
+ # # Usage
8
+ #
9
+ # Building a middleware stack is very easy:
10
+ #
11
+ # app = Midler::Builder.new do
12
+ # use A
13
+ # use B
14
+ # end
15
+ #
16
+ # # Call the middleware
17
+ # app.call(7)
18
+ #
19
+ class Builder
20
+ # Initializes the builder. An optional block can be passed which
21
+ # will be evaluated in the context of the instance.
22
+ #
23
+ # Example:
24
+ #
25
+ # Builder.new do
26
+ # use A
27
+ # use B
28
+ # end
29
+ #
30
+ # @param [Hash] opts Options hash
31
+ # @option opts [Class] :runner_class The class to wrap the middleware stack
32
+ # in which knows how to run them.
33
+ # @yield [] Evaluated in this instance which allows you to use methods
34
+ # like {#use} and such.
35
+ def initialize(opts=nil, &block)
36
+ opts ||= {}
37
+ @runner_class = opts[:runner_class] || Runner
38
+ instance_eval(&block) if block_given?
39
+ end
40
+
41
+ # Returns a mergeable version of the builder. If `use` is called with
42
+ # the return value of this method, then the stack will merge, instead
43
+ # of being treated as a separate single middleware.
44
+ def flatten
45
+ lambda do |*envs|
46
+ self.call(*envs)
47
+ end
48
+ end
49
+
50
+ # Adds a middleware class to the middleware stack. Any additional
51
+ # args and a block, if given, are saved and passed to the initializer
52
+ # of the middleware.
53
+ #
54
+ # @param [Class] middleware The middleware class
55
+ def use(middleware, *args, &block)
56
+ if middleware.kind_of?(Builder)
57
+ # Merge in the other builder's stack into our own
58
+ self.stack.concat(middleware.stack)
59
+ else
60
+ self.stack << [middleware, args, block]
61
+ end
62
+
63
+ self
64
+ end
65
+
66
+ # Inserts a middleware at the given index or directly before the
67
+ # given middleware object.
68
+ def insert(index, middleware, *args, &block)
69
+ index = self.index(index) unless index.is_a?(Integer)
70
+ stack.insert(index, [middleware, args, block])
71
+ end
72
+
73
+ alias_method :insert_before, :insert
74
+
75
+ # Inserts a middleware after the given index or middleware object.
76
+ def insert_after(index, middleware, *args, &block)
77
+ index = self.index(index) unless index.is_a?(Integer)
78
+ raise "no such middleware to insert after: #{index.inspect}" unless index
79
+ insert(index + 1, middleware, *args, &block)
80
+ end
81
+
82
+ # Replaces the given middlware object or index with the new
83
+ # middleware.
84
+ def replace(index, middleware, *args, &block)
85
+ if index.is_a?(Integer)
86
+ delete(index)
87
+ insert(index, middleware, *args, &block)
88
+ else
89
+ insert_before(index, middleware, *args, &block)
90
+ delete(index)
91
+ end
92
+ end
93
+
94
+ # Deletes the given middleware object or index
95
+ def delete(index)
96
+ index = self.index(index) unless index.is_a?(Integer)
97
+ stack.delete_at(index)
98
+ end
99
+
100
+ # Runs the builder stack with the given environments.
101
+ def call(*envs)
102
+ envs = [nil] if envs.empty?
103
+ to_app.call(*envs)
104
+ end
105
+
106
+ protected
107
+
108
+ # Returns the numeric index for the given middleware object.
109
+ #
110
+ # @param [Object] object The item to find the index for
111
+ # @return [Integer]
112
+ def index(object)
113
+ stack.each_with_index do |item, i|
114
+ return i if item[0] == object
115
+ end
116
+
117
+ nil
118
+ end
119
+
120
+ # Returns the current stack of middlewares. You probably won't
121
+ # need to use this directly, and it's recommended that you don't.
122
+ #
123
+ # @return [Array]
124
+ def stack
125
+ @stack ||= []
126
+ end
127
+
128
+ # Converts the builder stack to a runnable action sequence.
129
+ #
130
+ # @return [Object] A callable object
131
+ def to_app
132
+ @runner_class.new(stack.dup)
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,69 @@
1
+ module Midler
2
+ # This is a basic runner for middleware stacks. This runner does
3
+ # the default expected behavior of running the middleware stacks
4
+ # in order, then reversing the order.
5
+ class Runner
6
+ # A middleware which does nothing
7
+ EMPTY_MIDDLEWARE = lambda { |*envs| }
8
+
9
+ # Build a new middleware runner with the given middleware
10
+ # stack.
11
+ #
12
+ # Note: This class usually doesn't need to be used directly.
13
+ # Instead, take a look at using the {Builder} class, which is
14
+ # a much friendlier way to build up a middleware stack.
15
+ #
16
+ # @param [Array] stack An array of the middleware to run.
17
+ def initialize(stack)
18
+ # We need to take the stack of middleware and initialize them
19
+ # all so they call the proper next middleware.
20
+ @kickoff = build_call_chain(stack)
21
+ end
22
+
23
+ # Run the middleware stack with the given state bag.
24
+ #
25
+ # @param [Object] env The state to pass into as the initial
26
+ # environment data. This is usual a hash of some sort.
27
+ def call(*envs)
28
+ # We just call the kickoff middleware, which is responsible
29
+ # for properly calling the next middleware, and so on and so
30
+ # forth.
31
+ @kickoff.call(*envs)
32
+ end
33
+
34
+ protected
35
+
36
+ # This takes a stack of middlewares and initializes them in a way
37
+ # that each middleware properly calls the next middleware.
38
+ def build_call_chain(stack)
39
+ # We need to instantiate the middleware stack in reverse
40
+ # order so that each middleware can have a reference to
41
+ # the next middleware it has to call. The final middleware
42
+ # is always the empty middleware, which does nothing but return.
43
+ stack.reverse.inject(EMPTY_MIDDLEWARE) do |next_middleware, current_middleware|
44
+ # Unpack the actual item
45
+ klass, args, block = current_middleware
46
+
47
+ # Default the arguments to an empty array. Otherwise in Ruby 1.8
48
+ # a `nil` args will actually pass `nil` into the class. Not what
49
+ # we want!
50
+ args ||= []
51
+
52
+ if klass.is_a?(Class)
53
+ # If the klass actually is a class, then instantiate it with
54
+ # the app and any other arguments given.
55
+ klass.new(next_middleware, *args, &block)
56
+ elsif klass.respond_to?(:call)
57
+ # Make it a lambda which calls the item then forwards up
58
+ # the chain.
59
+ lambda do |*envs|
60
+ klass.call(*envs)
61
+ next_middleware.call(*envs)
62
+ end
63
+ else
64
+ raise "Invalid middleware, doesn't respond to `call`: #{action.inspect}"
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,3 @@
1
+ module Midler
2
+ VERSION = "0.1.0"
3
+ end
data/lib/midler.rb ADDED
@@ -0,0 +1,3 @@
1
+ require "midler/version"
2
+ require "midler/builder"
3
+ require "midler/runner"
data/midler.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'midler/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "midler"
8
+ spec.version = Midler::VERSION
9
+ spec.authors = ["Garrett Thornburg"]
10
+ spec.email = ["garrett.thornburg@mx.com"]
11
+ spec.summary = "A variadic fork of the middleware gem"
12
+ spec.description = "A variadic fork of the middleware gem"
13
+ spec.homepage = "https://github.com/film42/midler"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_development_dependency "bundler", "~> 1.8"
20
+ spec.add_development_dependency "rake", "~> 10.0"
21
+ spec.add_development_dependency "rspec-core", "~> 2.8.0"
22
+ spec.add_development_dependency "rspec-expectations", "~> 2.8.0"
23
+ spec.add_development_dependency "rspec-mocks", "~> 2.8.0"
24
+ end
data/midler.jpg ADDED
Binary file
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: midler
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Garrett Thornburg
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.8'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-core
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.8.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.8.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-expectations
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 2.8.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 2.8.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec-mocks
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 2.8.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 2.8.0
83
+ description: A variadic fork of the middleware gem
84
+ email:
85
+ - garrett.thornburg@mx.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".travis.yml"
93
+ - Gemfile
94
+ - README.md
95
+ - Rakefile
96
+ - lib/midler.rb
97
+ - lib/midler/builder.rb
98
+ - lib/midler/runner.rb
99
+ - lib/midler/version.rb
100
+ - midler.gemspec
101
+ - midler.jpg
102
+ homepage: https://github.com/film42/midler
103
+ licenses:
104
+ - MIT
105
+ metadata: {}
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 2.4.3
123
+ signing_key:
124
+ specification_version: 4
125
+ summary: A variadic fork of the middleware gem
126
+ test_files: []