padrino-core 0.11.3 → 0.11.4
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 +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
|