jeanine 0.4.0 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: d62b1858b952c8c8b7575f4a5c8ff60d9401e846d6d9fe9d302573052715706c
4
- data.tar.gz: fd9d260653e2164bd98fc333dedcbfedf1e58fd0f7feb33d84435406668a76df
2
+ SHA1:
3
+ metadata.gz: 00f439386000e4e03fde175cf305429a84809cc0
4
+ data.tar.gz: 2c19abd0a152c6240c2e57beb0cf3cedf520ed93
5
5
  SHA512:
6
- metadata.gz: bcfb247647f312eb473cf7681b1415dd7cdd828f545711cdb5e7cf641c69127d832617e952ece9f83daf1c09e391624efc70acd7259aa3ad1d168a01b93aa135
7
- data.tar.gz: 6afa5f33deb9c2a2094e317bdd5b755aa184a97c7378da944cc73968c4069d17b3e8c37b8f996efb7cd81b8af115aaed13406e45afd9bd5e1382225513c44bbc
6
+ metadata.gz: 205ed5845e02c18b59014cc5616f0fadc0f67b448a45c0cfcded08af17516a7e0b1beba07cb107a2a9dda2232b6404112b65dda00aecf0b97569df44bb15a030
7
+ data.tar.gz: 0f4fff626a3151825c605026bb68cafcf701aa05753fb06ac76086fc79f7b9e83ce975a51d4fc161e75cd0672dcfde975b4b4bcd343113923754a24ef09e5c19
@@ -0,0 +1,228 @@
1
+ # Jeanine
2
+
3
+ A Ruby micro-web-framework that gives you enough training wheels to be productive, while being as nearly as fast as Rack itself.
4
+
5
+ Its design (and some parts of the code) is influenced by/inherited from (thanks!) Ruby on Rails, Rack::App, Hobbit, and Cuba. Without them this is nothing.
6
+
7
+ ## Name
8
+
9
+ Named after my mom. Because she was the best.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'jeanine'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle install
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install jeanine
26
+
27
+ ## Basic usage
28
+
29
+ Drop this into `config.ru`:
30
+
31
+ ```ruby
32
+ require 'bundler/setup'
33
+ require 'jeanine'
34
+
35
+ class App < Jeanine::App
36
+ root do
37
+ "Hello world"
38
+ end
39
+ end
40
+
41
+ run App
42
+ ```
43
+
44
+ `$ rackup`
45
+
46
+ ## Advanced usage
47
+
48
+ ```ruby
49
+ class App < Jeanine::App
50
+ path "/posts" do
51
+ get do
52
+ if request.json?
53
+ render json: []
54
+ else
55
+ "Posts index"
56
+ end
57
+ end
58
+ get "new" do
59
+ "Posts new"
60
+ end
61
+ post do
62
+ "Posts post"
63
+ end
64
+ path ":id" do
65
+ get do
66
+ "Posts #{params[:id]}"
67
+ end
68
+ match via: [:put, :patch] do
69
+ "Posts #{request.via} #{params[:id]}"
70
+ end
71
+ delete do
72
+ "Posts delete #{params[:id]}"
73
+ end
74
+ path "/comments" do
75
+ get do
76
+ "Posts #{params[:id]} comments"
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ ```
83
+
84
+ ## Plugins
85
+
86
+ ### Callbacks
87
+
88
+ Supports `before` and `after` callbacks (same DSL):
89
+
90
+ ```
91
+ class App < Jeanine::App
92
+ plugin :Callbacks
93
+ before do
94
+ puts "All"
95
+ end
96
+ before /posts/ do
97
+ puts "Before posts"
98
+ end
99
+ before /posts\/\d*/, /comments\/\d*/ do
100
+ puts "Before posts/:id, comments/:id"
101
+ response.headers['X-Thing-Id'] = params[:id]
102
+ end
103
+ end
104
+ ```
105
+
106
+ ### Rendering
107
+
108
+ Basic support for rendering. Be explicit.
109
+
110
+ ```ruby
111
+ class App < Jeanine::App
112
+ plugin :Rendering
113
+ # loads views/root.html.erb and views/layouts/application.html.erb
114
+ root do
115
+ @title = "My cool app"
116
+ render template: "root.html.erb", layout: "application.html.erb"
117
+ end
118
+ end
119
+ ```
120
+
121
+ ### Sessions
122
+
123
+ Uses Rack's session management.
124
+
125
+ ```ruby
126
+ class App < Jeanine::App
127
+ plugin :Session
128
+ root do
129
+ session[:uid] = SecureRandom.hex
130
+ end
131
+ end
132
+ ```
133
+
134
+ ### Error handling
135
+
136
+ ```ruby
137
+ class App < Jeanine::App
138
+ plugin :Resucable
139
+ rescue_from NoMethodError, RuntimeError do |exception|
140
+ response.status = 500
141
+ "Oh no!"
142
+ end
143
+ rescue_from StandardError, with: :handle_error!
144
+ root do
145
+ @title = "My cool app"
146
+ raise NoMethodError
147
+ render template: "root.html.erb", layout: "application.html.erb"
148
+ end
149
+
150
+ private
151
+
152
+ def handle_error!(exception)
153
+ response.status = 500
154
+ render template: "error.html.erb"
155
+ end
156
+ end
157
+ ```
158
+
159
+ ## Development
160
+
161
+ ### Ideologies
162
+
163
+ * No meaningless metaprogramming = fast
164
+
165
+ ## Benchmarks
166
+
167
+ ### Requests/second
168
+
169
+ Benched on a Intel Core i7-8700B / 64GB RAM.
170
+
171
+ ```
172
+ Framework Requests/sec % from best
173
+ ----------------------------------------------
174
+ rack 17299.31 100.00%
175
+ jeanine 16022.71 92.62%
176
+ rack-response 15462.50 89.38%
177
+ syro 15416.13 89.11%
178
+ watts 15307.52 88.49%
179
+ roda 14550.56 84.11%
180
+ hanami-router 14342.92 82.91%
181
+ cuba 14246.23 82.35%
182
+ hobbit 14132.20 81.69%
183
+ rambutan 12526.40 72.41%
184
+ rack-app 11696.66 67.61%
185
+ flame 7931.61 45.85%
186
+ rails-metal 7761.75 44.87%
187
+ sinatra 4616.81 26.69%
188
+ grape 2401.66 13.88%
189
+ hobby 1805.93 10.44%
190
+ rails-api 1593.77 9.21%
191
+ ```
192
+
193
+ ### Memory
194
+
195
+ ```
196
+ Framework Allocs/Req Memsize/Req
197
+ --------------------------------------
198
+ rack 40 3408
199
+ roda 43 4016
200
+ syro 44 4288
201
+ cuba 44 4056
202
+ watts 46 3648
203
+ hobbit 48 4416
204
+ jeanine 52 4576
205
+ hobby 52 5416
206
+ rack-response 55 5128
207
+ rails-metal 59 5848
208
+ hanami-router 63 5184
209
+ rambutan 79 6944
210
+ rack-app 80 8424
211
+ flame 115 9648
212
+ sinatra 179 13440
213
+ grape 250 26704
214
+ rails-api 383 34949
215
+ ```
216
+
217
+ ## Todo
218
+
219
+ * Callback constraints
220
+ * File downloads
221
+
222
+ ## Contributing
223
+
224
+ Bug reports and pull requests are welcome on GitHub at https://github.com/joshmn/jeanine.
225
+
226
+ ## License
227
+
228
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/jeanine/cli'
4
+
5
+ Jeanine::CLI.new(ARGV).execute
@@ -1,18 +1,14 @@
1
+ require 'rack'
2
+
1
3
  require 'forwardable'
2
4
  require 'logger'
3
5
 
4
6
  require "jeanine/version"
5
7
  require 'jeanine/core_ext'
6
- require 'jeanine/router'
7
- require 'jeanine/app'
8
- require 'tilt'
9
8
 
10
9
  module Jeanine
11
- def self.view_paths
12
- @_view_paths ||= Set.new(["views"])
13
- end
14
- def self.tilt_cache
15
- @title_cache ||= Tilt::Cache.new
10
+ def self._installed_plugins
11
+ @_installed_plugins ||= []
16
12
  end
17
13
 
18
14
  def self.logger
@@ -26,4 +22,7 @@ module Jeanine
26
22
  def self.router
27
23
  @router ||= Router.new
28
24
  end
25
+
26
+ autoload :Router, 'jeanine/router'
27
+ autoload :App, 'jeanine/app'
29
28
  end
@@ -1,26 +1,35 @@
1
- require 'jeanine/callbacks'
2
1
  require 'jeanine/mimes'
3
2
  require 'jeanine/request'
4
- require 'jeanine/rescuing'
5
3
  require 'jeanine/response'
6
- require 'jeanine/renderer'
7
4
  require 'jeanine/routing'
8
- require 'jeanine/session'
9
- require 'jeanine/view_paths'
10
5
 
11
6
  module Jeanine
12
7
  class App
13
- include Session
14
- include Rescuing
15
8
  include Routing::Evaluation
16
9
 
17
10
  attr_reader :request, :response
18
11
 
12
+ def self.plugin(name)
13
+ unless Jeanine._installed_plugins.include?(name)
14
+ unless const_defined?("Jeanine::#{name}")
15
+ require "jeanine/#{name.to_s.underscore}"
16
+ end
17
+ include Kernel.const_get("Jeanine::#{name}")
18
+ Jeanine._installed_plugins << name
19
+ end
20
+ end
21
+
22
+ def self.installed_plugins
23
+ Jeanine._installed_plugins
24
+ end
25
+
26
+ # plugin :Callbacks
27
+ # plugin :Rendering
28
+ # plugin :Rescuing
29
+ # plugin :Session
30
+
19
31
  class << self
20
- include Callbacks
21
32
  include Routing::DSL
22
- include Rescuing
23
- include ViewPaths
24
33
 
25
34
  alias :_new :new
26
35
  def new(*args, &block)
@@ -47,21 +56,10 @@ module Jeanine
47
56
  end
48
57
 
49
58
  def call(env)
50
- begin
51
- @env = env
52
- @request = Jeanine::Request.new(env)
53
- @response = Jeanine::Response.new
54
- catch(:halt) { route_eval }
55
- rescue => error
56
- handler = self.class.rescue_handlers[error.class]
57
- raise error unless handler
58
- if handler.is_a?(Symbol)
59
- @response.write(send(handler, error))
60
- else
61
- @response.write(instance_exec(error, &handler))
62
- end
63
- @response.complete!
64
- end
59
+ @env = env
60
+ @request = Jeanine::Request.new(env)
61
+ @response = Jeanine::Response.new
62
+ catch(:halt) { route_eval }
65
63
  end
66
64
 
67
65
  private
@@ -74,11 +72,6 @@ module Jeanine
74
72
  end
75
73
  end
76
74
 
77
- def render(*args)
78
- @response.action_variables = instance_variables_cache
79
- Renderer.new(@response).render(*args)
80
- end
81
-
82
75
  def instance_variables_cache
83
76
  instance_variables.each_with_object({}) do |var, obj|
84
77
  obj[var] = instance_variable_get(var)
@@ -1,28 +1,105 @@
1
1
  module Jeanine
2
2
  module Callbacks
3
- def _callbacks
4
- @_callbacks ||= {
5
- before: [],
6
- after: [],
7
- before_all: [],
8
- after_all: []
9
- }
3
+ def self.included(klass)
4
+ klass.extend InstanceMethods
5
+ klass.prepend EvaluationMethods
10
6
  end
11
7
 
12
- def before(*paths, &block)
13
- _register_callback(:before, paths, &block)
14
- end
8
+ module InstanceMethods
9
+ def _callbacks
10
+ @_callbacks ||= {
11
+ before: [],
12
+ after: [],
13
+ before_all: [],
14
+ after_all: []
15
+ }
16
+ end
17
+
18
+ def before(*paths, &block)
19
+ _register_callback(:before, paths, &block)
20
+ end
21
+
22
+ def after(*paths, &block)
23
+ _register_callback(:after, paths, &block)
24
+ end
25
+
26
+ private
15
27
 
16
- def after(*paths, &block)
17
- _register_callback(:after, paths, &block)
28
+ def _register_callback(type, paths = [], &block)
29
+ if paths == []
30
+ _callbacks["#{type}_all".to_sym] << { block: block }
31
+ else
32
+ _callbacks[type] << { paths: paths, block: block }
33
+ end
34
+ end
18
35
  end
19
36
 
20
- private
21
- def _register_callback(type, paths = [], &block)
22
- if paths == []
23
- _callbacks["#{type}_all".to_sym] << { block: block }
24
- else
25
- _callbacks[type] << { paths: paths, block: block }
37
+ module EvaluationMethods
38
+ def route_eval
39
+ before_find_route!
40
+ route = find_route
41
+
42
+ if route
43
+ before_evaluate_route!
44
+ result = instance_eval(&route[:block])
45
+ @response.write(result)
46
+ after_evaluate_route!
47
+ else
48
+ @response.status = 404
49
+ end
50
+ after_response!
51
+ @response.complete!
52
+ end
53
+
54
+ private
55
+
56
+ def before_find_route!
57
+ run_before_callbacks!(:before_all)
58
+ end
59
+
60
+ def before_evaluate_route!
61
+ run_before_callbacks!(:before)
62
+ end
63
+
64
+ def after_evaluate_route!
65
+ run_after_callbacks!(:after)
66
+ end
67
+
68
+ def after_response!
69
+ run_after_callbacks!(:after_all)
70
+ end
71
+
72
+ def run_before_callbacks!(type)
73
+ if type == :before_all
74
+ self.class._callbacks[type].each { |callback| eval_callback(&callback[:block]) }
75
+ else
76
+ matching_callbacks(type) do |callback|
77
+ eval_callback(&callback[:block])
78
+ end
79
+ end
80
+ end
81
+
82
+ def run_after_callbacks!(type)
83
+ if type == :after_all
84
+ self.class._callbacks[type].each { |callback| eval_callback(&callback[:block]) }
85
+ else
86
+ matching_callbacks(type) do |callback|
87
+ eval_callback(&callback[:block])
88
+ end
89
+ end
90
+ end
91
+
92
+ def matching_callbacks(type)
93
+ self.class._callbacks[type].select do |callback|
94
+ paths = callback[:paths]
95
+ if paths.detect { |path| path.match?(@request.path_info) }
96
+ yield callback
97
+ end
98
+ end
99
+ end
100
+
101
+ def eval_callback(*args, &callback)
102
+ instance_exec(*args, &callback)
26
103
  end
27
104
  end
28
105
  end
@@ -0,0 +1,32 @@
1
+ require 'fileutils'
2
+
3
+ module Jeanine
4
+ class CLI
5
+ def initialize(args)
6
+ @args = args
7
+ end
8
+
9
+ def execute
10
+ if @args[0] == 'new'
11
+ command_new!
12
+ else
13
+ $stdout.puts "I don't know how to `#{@args[0]}`. Maybe you meant `new`?"
14
+ end
15
+ end
16
+
17
+ def command_new!
18
+ FileUtils.mkdir("#{@args[1]}") unless Dir.exists?("#{@args[1]}")
19
+ FileUtils.mkdir("#{@args[1]}/config") unless Dir.exists?("#{@args[1]}/config")
20
+ relative_dir = "lib/jeanine/generator/new"
21
+ Dir.glob("lib/jeanine/generator/new/**/*.*").each do |file|
22
+ new_dir = file.gsub(relative_dir, "#{@args[1]}")[0...-3]
23
+ FileUtils.copy_file(file, new_dir)
24
+ end
25
+ relative_dir = "lib/jeanine/generator/new/config"
26
+ Dir.glob("lib/jeanine/generator/new/config/**/*.*").each do |file|
27
+ new_dir = file.gsub(relative_dir, "#{@args[1]}/config")[0...-3]
28
+ FileUtils.copy_file(file, new_dir)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -5,4 +5,19 @@ class Hash
5
5
  def reverse_merge!(other_hash)
6
6
  replace(reverse_merge(other_hash))
7
7
  end
8
+ def deep_transform_keys(&block)
9
+ result = {}
10
+ each do |key, value|
11
+ result[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys(&block) : value
12
+ end
13
+ result
14
+ end
15
+
16
+ def deep_transform_keys!(&block)
17
+ keys.each do |key|
18
+ value = delete(key)
19
+ self[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys!(&block) : value
20
+ end
21
+ self
22
+ end
8
23
  end
@@ -3,4 +3,11 @@ class String
3
3
  return nil if self.empty?
4
4
  self
5
5
  end
6
+ def underscore
7
+ self.gsub(/::/, '/').
8
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
9
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
10
+ tr("-", "_").
11
+ downcase
12
+ end
6
13
  end
@@ -1,18 +1,16 @@
1
1
  module Broding
2
- module Environment
3
- def env
4
- @_env ||= (ENV["RACK_ENV"].presence || "development")
5
- end
2
+ def env
3
+ @_env ||= (ENV["RACK_ENV"].presence || "development")
4
+ end
6
5
 
7
- def groups(*groups)
8
- hash = groups.extract_options!
9
- env = Jeanine.env
10
- groups.unshift(:default, env)
11
- groups.concat ENV["BRODY_GROUPS"].to_s.split(",")
12
- groups.concat hash.map { |k, v| k if v.map(&:to_s).include?(env) }
13
- groups.compact!
14
- groups.uniq!
15
- groups
16
- end
6
+ def groups(*groups)
7
+ hash = groups.extract_options!
8
+ env = Jeanine.env
9
+ groups.unshift(:default, env)
10
+ groups.concat ENV["BRODY_GROUPS"].to_s.split(",")
11
+ groups.concat hash.map { |k, v| k if v.map(&:to_s).include?(env) }
12
+ groups.compact!
13
+ groups.uniq!
14
+ groups
17
15
  end
18
16
  end
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ ruby "$RUBY_VERSION$"
4
+
5
+ gem "jeanine"
6
+
7
+ group :production do
8
+ gem "puma"
9
+ end
@@ -0,0 +1,8 @@
1
+ # README
2
+
3
+ Welcome to your Jeanine app.
4
+
5
+ ## Start
6
+
7
+ `$ bundle`
8
+ `$ rackup`
@@ -0,0 +1,10 @@
1
+ require_relative 'boot'
2
+
3
+ require 'jeanine'
4
+
5
+ # Require the gems listed in Gemfile, including any gems
6
+ # you've limited to :test, :development, or :production.
7
+ Bundler.require(*Jeanine.groups)
8
+
9
+ class App < ::Jeanine::App
10
+ end
@@ -0,0 +1,3 @@
1
+ require_relative './app'
2
+
3
+ run App
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
4
+
5
+ require 'bundler/setup' # Set up gems listed in the Gemfile.
@@ -0,0 +1 @@
1
+ require_relative '../app'
@@ -0,0 +1,35 @@
1
+ # Puma can serve each request in a thread from an internal thread pool.
2
+ # The `threads` method setting takes two numbers: a minimum and maximum.
3
+ # Any libraries that use thread pools should be configured to match
4
+ # the maximum value specified for Puma. Default is set to 5 threads for minimum
5
+ # and maximum; this matches the default thread size of Active Record.
6
+ #
7
+ max_threads_count = ENV.fetch("RACK_MAX_THREADS") { 5 }
8
+ min_threads_count = ENV.fetch("RACK_MIN_THREADS") { max_threads_count }
9
+ threads min_threads_count, max_threads_count
10
+
11
+ # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
12
+ #
13
+ port ENV.fetch("PORT") { 3000 }
14
+
15
+ # Specifies the `environment` that Puma will run in.
16
+ #
17
+ environment ENV.fetch("RACK_ENV") { "development" }
18
+
19
+ # Specifies the `pidfile` that Puma will use.
20
+ pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
21
+
22
+ # Specifies the number of `workers` to boot in clustered mode.
23
+ # Workers are forked web server processes. If using threads and workers together
24
+ # the concurrency of the application would be max `threads` * `workers`.
25
+ # Workers do not work on JRuby or Windows (both of which do not support
26
+ # processes).
27
+ #
28
+ # workers ENV.fetch("WEB_CONCURRENCY") { 2 }
29
+
30
+ # Use the `preload_app!` method when specifying a `workers` number.
31
+ # This directive tells Puma to first boot the application and load code
32
+ # before forking the application. This takes advantage of Copy On Write
33
+ # process behavior so workers use less memory.
34
+ #
35
+ # preload_app!
@@ -1,11 +1,15 @@
1
- require 'rack'
2
-
3
1
  module Jeanine
4
2
  class Mimes
5
3
  MimeTypeNotFound = Class.new(StandardError)
6
4
  MIME_TYPES_INVERTED = ::Rack::Mime::MIME_TYPES.invert
7
5
 
6
+ def self.loaded?
7
+ @loaded
8
+ end
9
+
8
10
  def self.load!
11
+ return if loaded?
12
+ @loaded = true
9
13
  register(:json, Rack::Mime::MIME_TYPES[".json"])
10
14
  register(:html, Rack::Mime::MIME_TYPES[".html"])
11
15
  register(:text, Rack::Mime::MIME_TYPES[".text"])
@@ -1,6 +1,15 @@
1
1
  require 'jeanine/view'
2
+ require 'jeanine/view_paths'
2
3
 
3
4
  module Jeanine
5
+ def self.view_paths
6
+ @_view_paths ||= Set.new(["views"])
7
+ end
8
+
9
+ def self.tilt_cache
10
+ @title_cache ||= Tilt::Cache.new
11
+ end
12
+
4
13
  class Renderer
5
14
  def self._renderers
6
15
  @_renderers ||= Set.new
@@ -139,4 +148,21 @@ module Jeanine
139
148
  text
140
149
  end
141
150
  end
151
+
152
+ module Rendering
153
+ def self.included(klass)
154
+ klass.extend ClassMethods
155
+ end
156
+
157
+ def render(*args)
158
+ @response.action_variables = instance_variables_cache
159
+ Renderer.new(@response).render(*args)
160
+ end
161
+
162
+ module ClassMethods
163
+ def append_view_path(path)
164
+ Jeanine.view_paths << path
165
+ end
166
+ end
167
+ end
142
168
  end
@@ -1,5 +1,4 @@
1
1
  require 'rack/request'
2
- require 'jeanine/headers'
3
2
 
4
3
  module Jeanine
5
4
  class Request < Rack::Request
@@ -17,8 +16,8 @@ module Jeanine
17
16
  super
18
17
  end
19
18
 
20
- def headers
21
- @headers ||= Jeanine::Headers.new(self)
19
+ def params
20
+ super.deep_transform_keys!(&:to_sym)
22
21
  end
23
22
 
24
23
  def post?
@@ -0,0 +1,41 @@
1
+ module Jeanine
2
+ module Rescuable
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ base.prepend InstanceMethods
6
+ end
7
+
8
+ module InstanceMethods
9
+ def call(env)
10
+ begin
11
+ super
12
+ rescue => error
13
+ handler = self.class.rescue_handlers[error.class.to_s]
14
+ raise error unless handler
15
+ if handler.is_a?(Symbol)
16
+ @response.write(send(handler, error))
17
+ else
18
+ @response.write(instance_exec(error, &handler))
19
+ end
20
+ @response.complete!
21
+ end
22
+ end
23
+ end
24
+
25
+ module ClassMethods
26
+ def rescue_from(*exceptions, with: nil, &block)
27
+ exceptions.each do |exception|
28
+ if with
29
+ rescue_handlers[exception.to_s] = with
30
+ else
31
+ rescue_handlers[exception.to_s] = block
32
+ end
33
+ end
34
+ end
35
+
36
+ def rescue_handlers
37
+ @rescue_handlers ||= {}
38
+ end
39
+ end
40
+ end
41
+ end
@@ -2,18 +2,13 @@ module Jeanine
2
2
  module Routing
3
3
  module Evaluation
4
4
  def route_eval
5
- before_find_route!
6
5
  route = find_route
7
-
8
6
  if route
9
- before_evaluate_route!
10
7
  result = instance_eval(&route[:block])
11
8
  @response.write(result)
12
- after_evaluate_route!
13
9
  else
14
10
  @response.status = 404
15
11
  end
16
- after_response!
17
12
  @response.complete!
18
13
  end
19
14
 
@@ -42,54 +37,6 @@ module Jeanine
42
37
  route
43
38
  end
44
39
 
45
- def before_find_route!
46
- run_before_callbacks!(:before_all)
47
- end
48
-
49
- def before_evaluate_route!
50
- run_before_callbacks!(:before)
51
- end
52
-
53
- def after_evaluate_route!
54
- run_after_callbacks!(:after)
55
- end
56
-
57
- def after_response!
58
- run_after_callbacks!(:after_all)
59
- end
60
-
61
- def run_before_callbacks!(type)
62
- if type == :before_all
63
- self.class._callbacks[type].each { |callback| eval_callback(&callback[:block]) }
64
- else
65
- matching_callbacks(type) do |callback|
66
- eval_callback(&callback[:block])
67
- end
68
- end
69
- end
70
-
71
- def run_after_callbacks!(type)
72
- if type == :after_all
73
- self.class._callbacks[type].each { |callback| eval_callback(&callback[:block]) }
74
- else
75
- matching_callbacks(type) do |callback|
76
- eval_callback(&callback[:block])
77
- end
78
- end
79
- end
80
-
81
- def matching_callbacks(type)
82
- self.class._callbacks[type].select do |callback|
83
- paths = callback[:paths]
84
- if paths.detect { |path| path.match?(@request.path_info) }
85
- yield callback
86
- end
87
- end
88
- end
89
-
90
- def eval_callback(*args, &callback)
91
- instance_exec(*args, &callback)
92
- end
93
40
  end
94
41
  end
95
42
  end
@@ -1,3 +1,3 @@
1
1
  module Jeanine
2
- VERSION = "0.4.0"
2
+ VERSION = "0.7.2"
3
3
  end
@@ -1,7 +1,8 @@
1
+ require 'tilt'
2
+
1
3
  module Jeanine
4
+
2
5
  module ViewPaths
3
- def append_view_path(path)
4
- Jeanine.view_paths << path
5
- end
6
+
6
7
  end
7
8
  end
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jeanine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Brody
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
11
  date: 2020-07-08 00:00:00.000000000 Z
12
12
  dependencies:
@@ -94,28 +94,52 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
- description: A framework.
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: A lightning-fast, batteries-included Ruby web micro-framework.
98
112
  email:
99
113
  - git@josh.mn
100
114
  executables: []
101
115
  extensions: []
102
116
  extra_rdoc_files: []
103
117
  files:
118
+ - README.md
119
+ - exe/jeanine
104
120
  - lib/jeanine.rb
105
121
  - lib/jeanine/app.rb
106
122
  - lib/jeanine/callbacks.rb
123
+ - lib/jeanine/cli.rb
107
124
  - lib/jeanine/core_ext.rb
108
125
  - lib/jeanine/core_ext/array.rb
109
126
  - lib/jeanine/core_ext/hash.rb
110
127
  - lib/jeanine/core_ext/nil_class.rb
111
128
  - lib/jeanine/core_ext/string.rb
112
129
  - lib/jeanine/environment.rb
130
+ - lib/jeanine/generator/new/Gemfile.tt
131
+ - lib/jeanine/generator/new/README.md.tt
132
+ - lib/jeanine/generator/new/app.rb.tt
133
+ - lib/jeanine/generator/new/config.ru.tt
134
+ - lib/jeanine/generator/new/config/boot.rb.tt
135
+ - lib/jeanine/generator/new/config/environment.rb.tt
136
+ - lib/jeanine/generator/new/config/puma.rb.tt
113
137
  - lib/jeanine/headers.rb
114
138
  - lib/jeanine/mimes.rb
115
139
  - lib/jeanine/path_proxy.rb
116
- - lib/jeanine/renderer.rb
140
+ - lib/jeanine/rendering.rb
117
141
  - lib/jeanine/request.rb
118
- - lib/jeanine/rescuing.rb
142
+ - lib/jeanine/rescuable.rb
119
143
  - lib/jeanine/response.rb
120
144
  - lib/jeanine/router.rb
121
145
  - lib/jeanine/routing.rb
@@ -147,8 +171,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
147
171
  - !ruby/object:Gem::Version
148
172
  version: '0'
149
173
  requirements: []
150
- rubygems_version: 3.0.3
174
+ rubyforge_project:
175
+ rubygems_version: 2.6.14.3
151
176
  signing_key:
152
177
  specification_version: 4
153
- summary: A framework.
178
+ summary: A lightning-fast, batteries-included Ruby web micro-framework.
154
179
  test_files: []
@@ -1,17 +0,0 @@
1
- module Jeanine
2
- module Rescuing
3
- def rescue_from(*exceptions, with: nil, &block)
4
- exceptions.each do |exception|
5
- if with
6
- rescue_handlers[exception] = with
7
- else
8
- rescue_handlers[exception] = block
9
- end
10
- end
11
- end
12
-
13
- def rescue_handlers
14
- @rescue_handlers ||= {}
15
- end
16
- end
17
- end