padrino-core 0.11.3 → 0.11.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.rdoc +5 -5
- data/lib/padrino-core.rb +3 -9
- data/lib/padrino-core/application.rb +39 -35
- data/lib/padrino-core/application/flash.rb +7 -7
- data/lib/padrino-core/application/rendering.rb +136 -139
- data/lib/padrino-core/application/rendering/extensions/erubis.rb +15 -6
- data/lib/padrino-core/application/routing.rb +371 -369
- data/lib/padrino-core/application/showexceptions.rb +13 -12
- data/lib/padrino-core/caller.rb +40 -40
- data/lib/padrino-core/cli/adapter.rb +4 -4
- data/lib/padrino-core/cli/base.rb +40 -39
- data/lib/padrino-core/cli/rake.rb +2 -2
- data/lib/padrino-core/cli/rake_tasks.rb +2 -4
- data/lib/padrino-core/command.rb +2 -2
- data/lib/padrino-core/loader.rb +14 -15
- data/lib/padrino-core/locale/cs.yml +0 -1
- data/lib/padrino-core/locale/da.yml +0 -1
- data/lib/padrino-core/locale/de.yml +0 -1
- data/lib/padrino-core/locale/en.yml +0 -1
- data/lib/padrino-core/locale/es.yml +1 -2
- data/lib/padrino-core/locale/fr.yml +2 -3
- data/lib/padrino-core/locale/hu.yml +1 -2
- data/lib/padrino-core/locale/it.yml +0 -1
- data/lib/padrino-core/locale/ja.yml +1 -2
- data/lib/padrino-core/locale/lv.yml +0 -1
- data/lib/padrino-core/locale/nl.yml +0 -1
- data/lib/padrino-core/locale/no.yml +0 -2
- data/lib/padrino-core/locale/pl.yml +0 -1
- data/lib/padrino-core/locale/pt_br.yml +0 -1
- data/lib/padrino-core/locale/ro.yml +0 -1
- data/lib/padrino-core/locale/ru.yml +0 -1
- data/lib/padrino-core/locale/sv.yml +0 -1
- data/lib/padrino-core/locale/tr.yml +0 -1
- data/lib/padrino-core/locale/uk.yml +0 -1
- data/lib/padrino-core/locale/zh_cn.yml +0 -1
- data/lib/padrino-core/locale/zh_tw.yml +0 -1
- data/lib/padrino-core/logger.rb +26 -27
- data/lib/padrino-core/module.rb +3 -3
- data/lib/padrino-core/mounter.rb +59 -59
- data/lib/padrino-core/reloader.rb +23 -23
- data/lib/padrino-core/router.rb +10 -13
- data/lib/padrino-core/server.rb +17 -19
- data/lib/padrino-core/tasks.rb +3 -3
- data/lib/padrino-core/version.rb +1 -1
- data/padrino-core.gemspec +1 -1
- data/test/test_application.rb +7 -7
- data/test/test_rendering.rb +15 -2
- data/test/test_routing.rb +34 -10
- metadata +13 -27
@@ -143,8 +143,8 @@ module Padrino
|
|
143
143
|
Padrino::Utils.unsilence_output
|
144
144
|
new_constants = ObjectSpace.new_classes(klasses)
|
145
145
|
if loaded
|
146
|
-
process_loaded_file(:file => file,
|
147
|
-
:constants => new_constants,
|
146
|
+
process_loaded_file(:file => file,
|
147
|
+
:constants => new_constants,
|
148
148
|
:files => files)
|
149
149
|
else
|
150
150
|
logger.devel "Failed to load #{file}; removing partially defined constants"
|
@@ -154,7 +154,7 @@ module Padrino
|
|
154
154
|
end
|
155
155
|
|
156
156
|
##
|
157
|
-
# Returns true if the file is defined in our padrino root
|
157
|
+
# Returns true if the file is defined in our padrino root.
|
158
158
|
#
|
159
159
|
def figure_path(file)
|
160
160
|
return file if Pathname.new(file).absolute?
|
@@ -183,13 +183,12 @@ module Padrino
|
|
183
183
|
private
|
184
184
|
|
185
185
|
###
|
186
|
-
# Clear instance variables that keep track of
|
187
|
-
# loaded features/files/mtimes
|
186
|
+
# Clear instance variables that keep track of # loaded features/files/mtimes.
|
188
187
|
#
|
189
188
|
def clear_modification_times
|
190
189
|
MTIMES.clear
|
191
190
|
end
|
192
|
-
|
191
|
+
|
193
192
|
def clear_loaded_classes
|
194
193
|
LOADED_CLASSES.each do |file, klasses|
|
195
194
|
klasses.each { |klass| remove_constant(klass) }
|
@@ -205,21 +204,21 @@ module Padrino
|
|
205
204
|
end
|
206
205
|
|
207
206
|
###
|
208
|
-
# Macro for mtime query
|
207
|
+
# Macro for mtime query.
|
209
208
|
#
|
210
209
|
def modification_time(file)
|
211
210
|
MTIMES[file]
|
212
211
|
end
|
213
212
|
|
214
213
|
###
|
215
|
-
# Macro for mtime update
|
214
|
+
# Macro for mtime update.
|
216
215
|
#
|
217
216
|
def update_modification_time(file)
|
218
217
|
MTIMES[file] = File.mtime(file)
|
219
218
|
end
|
220
219
|
|
221
220
|
###
|
222
|
-
# Tracks loaded file features/classes/constants
|
221
|
+
# Tracks loaded file features/classes/constants:
|
223
222
|
#
|
224
223
|
def process_loaded_file(*args)
|
225
224
|
options = args.extract_options!
|
@@ -236,14 +235,14 @@ module Padrino
|
|
236
235
|
end
|
237
236
|
|
238
237
|
###
|
239
|
-
# Unloads all constants in new_constants
|
238
|
+
# Unloads all constants in new_constants.
|
240
239
|
#
|
241
240
|
def unload_constants(new_constants)
|
242
241
|
new_constants.each { |klass| remove_constant(klass) }
|
243
242
|
end
|
244
243
|
|
245
244
|
###
|
246
|
-
# Safe load dependencies of a file
|
245
|
+
# Safe load dependencies of a file.
|
247
246
|
#
|
248
247
|
def reload_deps_of_file(file)
|
249
248
|
if features = LOADED_FILES.delete(file)
|
@@ -252,23 +251,23 @@ module Padrino
|
|
252
251
|
end
|
253
252
|
|
254
253
|
##
|
255
|
-
# Check if file was changed or if force a reload
|
254
|
+
# Check if file was changed or if force a reload.
|
256
255
|
#
|
257
256
|
def should_reload?(file)
|
258
257
|
MTIMES[file] && File.mtime(file) > MTIMES[file]
|
259
258
|
end
|
260
259
|
|
261
260
|
##
|
262
|
-
# Removes all classes declared in the specified file
|
261
|
+
# Removes all classes declared in the specified file.
|
263
262
|
#
|
264
263
|
def remove_loaded_file_classes(file)
|
265
264
|
if klasses = LOADED_CLASSES.delete(file)
|
266
265
|
klasses.each { |klass| remove_constant(klass) }
|
267
|
-
end
|
266
|
+
end
|
268
267
|
end
|
269
268
|
|
270
269
|
##
|
271
|
-
# Remove all loaded fatures with our file
|
270
|
+
# Remove all loaded fatures with our file.
|
272
271
|
#
|
273
272
|
def remove_loaded_file_features(file)
|
274
273
|
if features = LOADED_FILES[file]
|
@@ -277,8 +276,8 @@ module Padrino
|
|
277
276
|
end
|
278
277
|
|
279
278
|
##
|
280
|
-
# Return the mounted_apps providing the app location
|
281
|
-
# Can be an array because in one app.rb we can define multiple Padrino::
|
279
|
+
# Return the mounted_apps providing the app location.
|
280
|
+
# Can be an array because in one app.rb we can define multiple Padrino::Application.
|
282
281
|
#
|
283
282
|
def mounted_apps_of(file)
|
284
283
|
file = figure_path(file)
|
@@ -286,7 +285,7 @@ module Padrino
|
|
286
285
|
end
|
287
286
|
|
288
287
|
##
|
289
|
-
# Returns true if file is in our Padrino.root
|
288
|
+
# Returns true if file is in our Padrino.root.
|
290
289
|
#
|
291
290
|
def in_root?(file)
|
292
291
|
# This is better but slow:
|
@@ -307,7 +306,7 @@ module Padrino
|
|
307
306
|
end
|
308
307
|
|
309
308
|
##
|
310
|
-
# Creates an array of paths for use in #rotation
|
309
|
+
# Creates an array of paths for use in #rotation.
|
311
310
|
#
|
312
311
|
def files_for_rotation
|
313
312
|
files = Padrino.load_paths.map { |path| Dir["#{path}/**/*.rb"] }.flatten
|
@@ -317,8 +316,9 @@ module Padrino
|
|
317
316
|
end # self
|
318
317
|
|
319
318
|
##
|
320
|
-
# This class acts as a Rack middleware to be added to the application stack.
|
321
|
-
# check and reload for source files at the start
|
319
|
+
# This class acts as a Rack middleware to be added to the application stack.
|
320
|
+
# This middleware performs a check and reload for source files at the start
|
321
|
+
# of each request, but also respects a specified cool down time
|
322
322
|
# during which no further action will be taken.
|
323
323
|
#
|
324
324
|
class Rack
|
@@ -337,5 +337,5 @@ module Padrino
|
|
337
337
|
@app.call(env)
|
338
338
|
end
|
339
339
|
end
|
340
|
-
end
|
341
|
-
end
|
340
|
+
end
|
341
|
+
end
|
data/lib/padrino-core/router.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Padrino
|
2
2
|
##
|
3
|
-
# This class is an extended version of Rack::URLMap
|
3
|
+
# This class is an extended version of Rack::URLMap.
|
4
4
|
#
|
5
5
|
# Padrino::Router like Rack::URLMap dispatches in such a way that the
|
6
6
|
# longest paths are tried first, since they are most specific.
|
@@ -9,7 +9,7 @@ module Padrino
|
|
9
9
|
#
|
10
10
|
# * Map a path to the specified App
|
11
11
|
# * Ignore server names (this solve issues with vhost and domain aliases)
|
12
|
-
# * Use hosts instead of server name for mappings (this help us with our vhost and
|
12
|
+
# * Use hosts instead of server name for mappings (this help us with our vhost and domain aliases)
|
13
13
|
#
|
14
14
|
# @example
|
15
15
|
#
|
@@ -26,8 +26,6 @@ module Padrino
|
|
26
26
|
#
|
27
27
|
# @api semipublic
|
28
28
|
class Router
|
29
|
-
|
30
|
-
# Constructs a new route mapper instance
|
31
29
|
def initialize(*mapping, &block)
|
32
30
|
@mapping = []
|
33
31
|
mapping.each { |m| map(m) }
|
@@ -68,14 +66,14 @@ module Padrino
|
|
68
66
|
end
|
69
67
|
|
70
68
|
# The call handler setup to route a request given the mappings specified.
|
71
|
-
# @api private
|
72
69
|
def call(env)
|
73
|
-
|
70
|
+
path_info = env["PATH_INFO"].to_s
|
74
71
|
script_name = env['SCRIPT_NAME']
|
75
|
-
|
72
|
+
http_host = env['HTTP_HOST']
|
73
|
+
|
76
74
|
@mapping.each do |host, path, match, app|
|
77
|
-
next unless host.nil? ||
|
78
|
-
next unless
|
75
|
+
next unless host.nil? || http_host =~ host
|
76
|
+
next unless path_info =~ match && rest = $1
|
79
77
|
next unless rest.empty? || rest[0] == ?/
|
80
78
|
|
81
79
|
rest = "/" if rest.empty?
|
@@ -85,14 +83,13 @@ module Padrino
|
|
85
83
|
'SCRIPT_NAME' => (script_name + path),
|
86
84
|
'PATH_INFO' => rest))
|
87
85
|
end
|
88
|
-
[404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{
|
86
|
+
[404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path_info}"]]
|
89
87
|
end
|
90
88
|
|
91
89
|
private
|
92
90
|
|
93
|
-
# Sorts the mapped routes in consistent order
|
94
91
|
def sort!
|
95
92
|
@mapping = @mapping.sort_by { |h, p, m, a| -p.size }
|
96
93
|
end
|
97
|
-
end
|
98
|
-
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/padrino-core/server.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Padrino
|
2
2
|
##
|
3
3
|
# Runs the Padrino apps as a self-hosted server using:
|
4
|
-
# thin, mongrel, or
|
4
|
+
# thin, mongrel, or WEBrick in that order.
|
5
5
|
#
|
6
6
|
# @example
|
7
7
|
# Padrino.run! # with these defaults => host: "127.0.0.1", port: "3000", adapter: the first found
|
@@ -23,7 +23,7 @@ module Padrino
|
|
23
23
|
def self.start(app, opts={})
|
24
24
|
options = {}.merge(opts) # We use a standard hash instead of Thor::CoreExt::HashWithIndifferentAccess
|
25
25
|
options.symbolize_keys!
|
26
|
-
options[:Host] = options.delete(:host) || '127.0.0.1'
|
26
|
+
options[:Host] = options.delete(:host) || '127.0.0.1'
|
27
27
|
options[:Port] = options.delete(:port) || 3000
|
28
28
|
options[:AccessLog] = []
|
29
29
|
if options[:daemonize]
|
@@ -53,27 +53,25 @@ module Padrino
|
|
53
53
|
end
|
54
54
|
alias :wrapped_app :app
|
55
55
|
|
56
|
-
# The options specified to the server.
|
57
56
|
def options
|
58
57
|
@options
|
59
58
|
end
|
60
59
|
|
61
60
|
private
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
rescue NameError
|
74
|
-
end
|
61
|
+
# Detects the supported handler to use.
|
62
|
+
#
|
63
|
+
# @example
|
64
|
+
# detect_rack_handler => <ThinHandler>
|
65
|
+
#
|
66
|
+
def self.detect_rack_handler
|
67
|
+
Handlers.each do |handler|
|
68
|
+
begin
|
69
|
+
return handler if Rack::Handler.get(handler.to_s.downcase)
|
70
|
+
rescue LoadError
|
71
|
+
rescue NameError
|
75
72
|
end
|
76
|
-
fail "Server handler (#{Handlers.join(', ')}) not found."
|
77
73
|
end
|
78
|
-
|
79
|
-
end
|
74
|
+
fail "Server handler (#{Handlers.join(', ')}) not found."
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/padrino-core/tasks.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Padrino
|
2
2
|
##
|
3
3
|
# This module it's used for bootstrap with padrino rake
|
4
|
-
#
|
4
|
+
# third party tasks, in your gem/plugin/extension you
|
5
5
|
# need only do this:
|
6
6
|
#
|
7
7
|
# @example
|
@@ -17,5 +17,5 @@ module Padrino
|
|
17
17
|
def self.files
|
18
18
|
@files ||= []
|
19
19
|
end
|
20
|
-
end
|
21
|
-
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/padrino-core/version.rb
CHANGED
data/padrino-core.gemspec
CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
|
|
30
30
|
# s.post_install_message << " as shown here:\e[0m https://gist.github.com/1d36a35794dbbd664ea4"
|
31
31
|
# s.post_install_message << "\n\e[32m" + ("*" * 20) + "\n\e[0m"
|
32
32
|
|
33
|
-
s.add_dependency("tilt", "~> 1.
|
33
|
+
s.add_dependency("tilt", "~> 1.4.1")
|
34
34
|
if ENV["SINATRA_EDGE"]
|
35
35
|
s.add_dependency("sinatra")
|
36
36
|
else
|
data/test/test_application.rb
CHANGED
@@ -80,22 +80,22 @@ describe "Application" do
|
|
80
80
|
end
|
81
81
|
|
82
82
|
# compare to: test_routing: allow global provides
|
83
|
-
should "set content_type to
|
83
|
+
should "set content_type to nil if none can be determined" do
|
84
84
|
mock_app do
|
85
85
|
provides :xml
|
86
86
|
|
87
|
-
get("/foo"){ "Foo in #{content_type}" }
|
88
|
-
get("/bar"){ "Foo in #{content_type}" }
|
87
|
+
get("/foo"){ "Foo in #{content_type.inspect}" }
|
88
|
+
get("/bar"){ "Foo in #{content_type.inspect}" }
|
89
89
|
end
|
90
90
|
|
91
91
|
get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
92
|
-
assert_equal 'Foo in xml', body
|
92
|
+
assert_equal 'Foo in :xml', body
|
93
93
|
get '/foo'
|
94
|
-
assert_equal 'Foo in xml', body
|
94
|
+
assert_equal 'Foo in :xml', body
|
95
95
|
|
96
96
|
get '/bar', {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
97
|
-
assert_equal "Foo in
|
98
|
-
end
|
97
|
+
assert_equal "Foo in nil", body
|
98
|
+
end
|
99
99
|
|
100
100
|
context "errors" do
|
101
101
|
should "haven't mapped errors on development" do
|
data/test/test_rendering.rb
CHANGED
@@ -60,14 +60,14 @@ describe "Rendering" do
|
|
60
60
|
end
|
61
61
|
|
62
62
|
should 'not use layout' do
|
63
|
-
with_layout :application, "this is
|
63
|
+
with_layout :application, "this is an <%= yield %>" do
|
64
64
|
with_view :index, "index" do
|
65
65
|
mock_app do
|
66
66
|
get("/with/layout"){ render :index }
|
67
67
|
get("/without/layout"){ render :index, :layout => false }
|
68
68
|
end
|
69
69
|
get "/with/layout"
|
70
|
-
assert_equal "this is
|
70
|
+
assert_equal "this is an index", body
|
71
71
|
get "/without/layout"
|
72
72
|
assert_equal "index", body
|
73
73
|
end
|
@@ -528,5 +528,18 @@ describe "Rendering" do
|
|
528
528
|
assert ok?
|
529
529
|
assert_equal '<p><div>foo</div></p>', body.strip
|
530
530
|
end
|
531
|
+
|
532
|
+
should "render correct erb when use sinatra as middleware" do
|
533
|
+
class Bar < Sinatra::Base
|
534
|
+
get "/" do
|
535
|
+
render :erb, "<&'>"
|
536
|
+
end
|
537
|
+
end
|
538
|
+
mock_app do
|
539
|
+
use Bar
|
540
|
+
end
|
541
|
+
get "/"
|
542
|
+
assert_equal "<&'>", body
|
543
|
+
end
|
531
544
|
end
|
532
545
|
end
|
data/test/test_routing.rb
CHANGED
@@ -109,6 +109,16 @@ describe "Routing" do
|
|
109
109
|
assert_equal 'success!', body
|
110
110
|
end
|
111
111
|
|
112
|
+
should 'parse routes that include encoded slash' do
|
113
|
+
mock_app do
|
114
|
+
get('/:drive_alias/:path', :path => /.*/){
|
115
|
+
"Show #{params[:drive_alias]} and #{params[:path]}"
|
116
|
+
}
|
117
|
+
end
|
118
|
+
get("/drive%2Ffoo/some/path")
|
119
|
+
assert_equal "Show drive/foo and some/path", body
|
120
|
+
end
|
121
|
+
|
112
122
|
should 'encode params using UTF-8' do
|
113
123
|
skip unless ''.respond_to?(:encoding) # for 1.8.7
|
114
124
|
|
@@ -151,6 +161,20 @@ describe "Routing" do
|
|
151
161
|
assert_equal 404, status
|
152
162
|
end
|
153
163
|
|
164
|
+
should "parse params when use regex for parts of a route" do
|
165
|
+
mock_app do
|
166
|
+
post :index, :with => [:foo, :bar], :bar => /.+/ do
|
167
|
+
"show #{params[:foo]}"
|
168
|
+
end
|
169
|
+
|
170
|
+
get :index, :map => '/mystuff/:a_id/boing/:boing_id' do
|
171
|
+
"show #{params[:a_id]} and #{params[:boing_id]}"
|
172
|
+
end
|
173
|
+
end
|
174
|
+
get "/mystuff/5/boing/2"
|
175
|
+
assert_equal "show 5 and 2", body
|
176
|
+
end
|
177
|
+
|
154
178
|
should "not generate overlapping head urls" do
|
155
179
|
app = mock_app do
|
156
180
|
get("/main"){ "hello" }
|
@@ -1096,17 +1120,17 @@ describe "Routing" do
|
|
1096
1120
|
mock_app do
|
1097
1121
|
provides :xml
|
1098
1122
|
|
1099
|
-
get("/foo"){ "Foo in #{content_type}" }
|
1100
|
-
get("/bar"){ "Bar in #{content_type}" }
|
1123
|
+
get("/foo"){ "Foo in #{content_type.inspect}" }
|
1124
|
+
get("/bar"){ "Bar in #{content_type.inspect}" }
|
1101
1125
|
end
|
1102
1126
|
|
1103
1127
|
get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
1104
|
-
assert_equal 'Foo in xml', body
|
1128
|
+
assert_equal 'Foo in :xml', body
|
1105
1129
|
get '/foo'
|
1106
|
-
assert_equal 'Foo in xml', body
|
1130
|
+
assert_equal 'Foo in :xml', body
|
1107
1131
|
|
1108
1132
|
get '/bar', {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
1109
|
-
assert_equal 'Bar in
|
1133
|
+
assert_equal 'Bar in nil', body
|
1110
1134
|
end
|
1111
1135
|
|
1112
1136
|
should "does not allow global provides in controller" do
|
@@ -1114,18 +1138,18 @@ describe "Routing" do
|
|
1114
1138
|
controller :base do
|
1115
1139
|
provides :xml
|
1116
1140
|
|
1117
|
-
get(:foo, "/foo"){ "Foo in #{content_type}" }
|
1118
|
-
get(:bar, "/bar"){ "Bar in #{content_type}" }
|
1141
|
+
get(:foo, "/foo"){ "Foo in #{content_type.inspect}" }
|
1142
|
+
get(:bar, "/bar"){ "Bar in #{content_type.inspect}" }
|
1119
1143
|
end
|
1120
1144
|
end
|
1121
1145
|
|
1122
1146
|
get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
1123
|
-
assert_equal 'Foo in xml', body
|
1147
|
+
assert_equal 'Foo in :xml', body
|
1124
1148
|
get '/foo'
|
1125
|
-
assert_equal 'Foo in xml', body
|
1149
|
+
assert_equal 'Foo in :xml', body
|
1126
1150
|
|
1127
1151
|
get '/bar', {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
1128
|
-
assert_equal 'Bar in
|
1152
|
+
assert_equal 'Bar in nil', body
|
1129
1153
|
end
|
1130
1154
|
|
1131
1155
|
should "map non named routes in controllers" do
|