jeanine 0.5.0 → 0.7.3
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 +5 -5
- data/README.md +228 -0
- data/exe/jeanine +5 -0
- data/lib/jeanine/app.rb +1 -0
- data/lib/jeanine/cli.rb +32 -0
- data/lib/jeanine/core_ext/hash.rb +15 -0
- data/lib/jeanine/generator/new/Gemfile.tt +9 -0
- data/lib/jeanine/generator/new/README.md.tt +8 -0
- data/lib/jeanine/generator/new/app.rb.tt +10 -0
- data/lib/jeanine/generator/new/config.ru.tt +3 -0
- data/lib/jeanine/generator/new/config/boot.rb.tt +5 -0
- data/lib/jeanine/generator/new/config/environment.rb.tt +1 -0
- data/lib/jeanine/generator/new/config/puma.rb.tt +35 -0
- data/lib/jeanine/request.rb +4 -0
- data/lib/jeanine/{rescuing.rb → rescuable.rb} +1 -1
- data/lib/jeanine/version.rb +1 -1
- metadata +17 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ae2f211b64bde8d5c7b65837dec687314bafedff
|
4
|
+
data.tar.gz: 119368f1a2e7ca316aba774c89cf14caa7b8b0dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59fa12a8e324f5f8d5d23ab87c7e778f8ea746b87744d3a865f29b4725e4f1d3470a75f3db2947d425f063d6edcd583ea0316ac19823f92784b9378e8162f333
|
7
|
+
data.tar.gz: 6f142f86f7b67441e35bdbffacad9cc083007333b36165f3925f27aae4132a1d72418ac73ad850c51cc366730f2e8ca1f60c8dfd737564b83f3ea09fe8cb2870
|
data/README.md
ADDED
@@ -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).
|
data/exe/jeanine
ADDED
data/lib/jeanine/app.rb
CHANGED
data/lib/jeanine/cli.rb
ADDED
@@ -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
|
@@ -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!
|
data/lib/jeanine/request.rb
CHANGED
data/lib/jeanine/version.rb
CHANGED
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
|
+
version: 0.7.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Brody
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
11
|
date: 2020-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
@@ -108,28 +108,38 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
-
description: A framework.
|
111
|
+
description: A lightning-fast, batteries-included Ruby web micro-framework.
|
112
112
|
email:
|
113
113
|
- git@josh.mn
|
114
114
|
executables: []
|
115
115
|
extensions: []
|
116
116
|
extra_rdoc_files: []
|
117
117
|
files:
|
118
|
+
- README.md
|
119
|
+
- exe/jeanine
|
118
120
|
- lib/jeanine.rb
|
119
121
|
- lib/jeanine/app.rb
|
120
122
|
- lib/jeanine/callbacks.rb
|
123
|
+
- lib/jeanine/cli.rb
|
121
124
|
- lib/jeanine/core_ext.rb
|
122
125
|
- lib/jeanine/core_ext/array.rb
|
123
126
|
- lib/jeanine/core_ext/hash.rb
|
124
127
|
- lib/jeanine/core_ext/nil_class.rb
|
125
128
|
- lib/jeanine/core_ext/string.rb
|
126
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
|
127
137
|
- lib/jeanine/headers.rb
|
128
138
|
- lib/jeanine/mimes.rb
|
129
139
|
- lib/jeanine/path_proxy.rb
|
130
140
|
- lib/jeanine/rendering.rb
|
131
141
|
- lib/jeanine/request.rb
|
132
|
-
- lib/jeanine/
|
142
|
+
- lib/jeanine/rescuable.rb
|
133
143
|
- lib/jeanine/response.rb
|
134
144
|
- lib/jeanine/router.rb
|
135
145
|
- lib/jeanine/routing.rb
|
@@ -161,8 +171,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
161
171
|
- !ruby/object:Gem::Version
|
162
172
|
version: '0'
|
163
173
|
requirements: []
|
164
|
-
|
174
|
+
rubyforge_project:
|
175
|
+
rubygems_version: 2.6.14.3
|
165
176
|
signing_key:
|
166
177
|
specification_version: 4
|
167
|
-
summary: A framework.
|
178
|
+
summary: A lightning-fast, batteries-included Ruby web micro-framework.
|
168
179
|
test_files: []
|