midler 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.
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: []