padrino-core 0.16.0.pre4 → 0.16.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 +4 -4
- data/README.rdoc +8 -8
- data/Rakefile +1 -1
- data/bin/padrino +1 -1
- data/lib/padrino-core/application/application_setup.rb +28 -26
- data/lib/padrino-core/application/authenticity_token.rb +3 -2
- data/lib/padrino-core/application/flash.rb +4 -5
- data/lib/padrino-core/application/params_protection.rb +34 -37
- data/lib/padrino-core/application/routing.rb +165 -164
- data/lib/padrino-core/application/show_exceptions.rb +5 -7
- data/lib/padrino-core/application.rb +4 -4
- data/lib/padrino-core/caller.rb +6 -7
- data/lib/padrino-core/cli/adapter.rb +4 -4
- data/lib/padrino-core/cli/base.rb +31 -32
- data/lib/padrino-core/cli/binstub.rb +9 -8
- data/lib/padrino-core/cli/console.rb +1 -1
- data/lib/padrino-core/cli/launcher.rb +45 -42
- data/lib/padrino-core/cli/rake.rb +16 -14
- data/lib/padrino-core/cli/rake_tasks.rb +18 -20
- data/lib/padrino-core/command.rb +1 -1
- data/lib/padrino-core/ext/sinatra.rb +3 -2
- data/lib/padrino-core/filter.rb +3 -3
- data/lib/padrino-core/loader.rb +10 -12
- data/lib/padrino-core/logger.rb +85 -77
- data/lib/padrino-core/mounter/application_extension.rb +2 -2
- data/lib/padrino-core/mounter.rb +33 -34
- data/lib/padrino-core/path_router/compiler.rb +8 -8
- data/lib/padrino-core/path_router/matcher.rb +11 -11
- data/lib/padrino-core/path_router/route.rb +15 -15
- data/lib/padrino-core/path_router.rb +4 -3
- data/lib/padrino-core/reloader/rack.rb +1 -1
- data/lib/padrino-core/reloader/storage.rb +12 -11
- data/lib/padrino-core/reloader.rb +18 -19
- data/lib/padrino-core/router.rb +14 -14
- data/lib/padrino-core/server.rb +20 -24
- data/lib/padrino-core/tasks.rb +0 -1
- data/lib/padrino-core/version.rb +1 -1
- data/lib/padrino-core.rb +9 -10
- data/padrino-core.gemspec +18 -18
- data/test/fixtures/app_gem/app_gem.gemspec +8 -7
- data/test/fixtures/app_gem/lib/app_gem/version.rb +1 -1
- data/test/fixtures/apps/complex.rb +6 -6
- data/test/fixtures/apps/concerned/app.rb +1 -1
- data/test/fixtures/apps/custom_dependencies/custom_dependencies.rb +3 -3
- data/test/fixtures/apps/demo_app.rb +1 -1
- data/test/fixtures/apps/demo_demo.rb +1 -1
- data/test/fixtures/apps/demo_project/api/app.rb +1 -1
- data/test/fixtures/apps/demo_project/app.rb +1 -1
- data/test/fixtures/apps/helpers/class_methods_helpers.rb +1 -0
- data/test/fixtures/apps/helpers/instance_methods_helpers.rb +1 -0
- data/test/fixtures/apps/helpers/system_helpers.rb +0 -1
- data/test/fixtures/apps/lib/myklass/mysubklass.rb +2 -2
- data/test/fixtures/apps/mountable_apps/rack_apps.rb +7 -7
- data/test/fixtures/apps/precompiled_app.rb +6 -5
- data/test/fixtures/apps/simple.rb +5 -5
- data/test/fixtures/apps/static.rb +2 -2
- data/test/fixtures/apps/stealthy/app.rb +1 -1
- data/test/fixtures/apps/stealthy/helpers/stealthy_class_helpers.rb +1 -1
- data/test/fixtures/apps/system.rb +1 -1
- data/test/fixtures/apps/system_class_methods_demo.rb +1 -1
- data/test/fixtures/apps/system_instance_methods_demo.rb +1 -1
- data/test/fixtures/dependencies/a.rb +1 -1
- data/test/fixtures/dependencies/b.rb +1 -1
- data/test/fixtures/dependencies/c.rb +1 -1
- data/test/fixtures/dependencies/circular/e.rb +2 -1
- data/test/fixtures/dependencies/d.rb +1 -1
- data/test/fixtures/dependencies/linear/i.rb +1 -1
- data/test/fixtures/dependencies/nested/l.rb +2 -2
- data/test/fixtures/dependencies/nested/m.rb +1 -1
- data/test/fixtures/dependencies/nested/qqq.rb +2 -2
- data/test/fixtures/dependencies/nested/rrr.rb +1 -1
- data/test/fixtures/dependencies/nested/sss.rb +1 -1
- data/test/fixtures/reloadable_apps/external/app/app.rb +0 -1
- data/test/fixtures/reloadable_apps/external/app/controllers/base.rb +1 -2
- data/test/fixtures/reloadable_apps/main/app.rb +2 -2
- data/test/helper.rb +2 -2
- data/test/test_application.rb +59 -60
- data/test/test_configuration.rb +2 -2
- data/test/test_core.rb +13 -13
- data/test/test_csrf_protection.rb +67 -63
- data/test/test_dependencies.rb +33 -34
- data/test/test_filters.rb +46 -47
- data/test/test_flash.rb +14 -14
- data/test/test_locale.rb +2 -2
- data/test/test_logger.rb +64 -64
- data/test/test_mounter.rb +133 -123
- data/test/test_params_protection.rb +40 -40
- data/test/test_reloader_complex.rb +23 -23
- data/test/test_reloader_external.rb +10 -10
- data/test/test_reloader_simple.rb +26 -23
- data/test/test_reloader_storage.rb +9 -12
- data/test/test_reloader_system.rb +29 -29
- data/test/test_restful_routing.rb +19 -19
- data/test/test_router.rb +126 -145
- data/test/test_routing.rb +882 -894
- metadata +6 -6
data/lib/padrino-core/logger.rb
CHANGED
|
@@ -63,14 +63,16 @@ module Padrino
|
|
|
63
63
|
# :debug:: low-level information for developers
|
|
64
64
|
# :devel:: Development-related information that is unnecessary in debug mode
|
|
65
65
|
#
|
|
66
|
-
Levels
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
66
|
+
unless defined?(Levels)
|
|
67
|
+
Levels = {
|
|
68
|
+
fatal: 4,
|
|
69
|
+
error: 3,
|
|
70
|
+
warn: 2,
|
|
71
|
+
info: 1,
|
|
72
|
+
debug: 0,
|
|
73
|
+
devel: -1
|
|
74
|
+
}
|
|
75
|
+
end
|
|
74
76
|
|
|
75
77
|
module Extensions
|
|
76
78
|
##
|
|
@@ -79,22 +81,20 @@ module Padrino
|
|
|
79
81
|
Padrino::Logger::Levels.each_pair do |name, number|
|
|
80
82
|
define_method(name) do |*args|
|
|
81
83
|
return if number < level
|
|
84
|
+
|
|
82
85
|
if args.size > 1
|
|
83
86
|
bench(args[0], args[1], args[2], name)
|
|
84
87
|
else
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
end if enable_source_location?
|
|
88
|
+
location = resolve_source_location(caller(1).shift)
|
|
89
|
+
args.unshift(location) if location && enable_source_location?
|
|
88
90
|
push(args * '', name)
|
|
89
91
|
end
|
|
90
92
|
end
|
|
91
93
|
|
|
92
|
-
define_method(:"#{name}?")
|
|
93
|
-
number >= level
|
|
94
|
-
end
|
|
94
|
+
define_method(:"#{name}?") { number >= level }
|
|
95
95
|
end
|
|
96
96
|
|
|
97
|
-
SOURCE_LOCATION_REGEXP = /^(.*?):(\d+?)(?::in `.+?')
|
|
97
|
+
SOURCE_LOCATION_REGEXP = /^(.*?):(\d+?)(?::in `.+?')?$/
|
|
98
98
|
|
|
99
99
|
##
|
|
100
100
|
# Returns true if :source_location is set to true.
|
|
@@ -109,11 +109,12 @@ module Padrino
|
|
|
109
109
|
def resolve_source_location(message)
|
|
110
110
|
path, line = *message.scan(SOURCE_LOCATION_REGEXP).first
|
|
111
111
|
return unless path && line
|
|
112
|
+
|
|
112
113
|
root = Padrino.root
|
|
113
114
|
path = File.realpath(path) if Pathname.new(path).relative?
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
return unless path.start_with?(root) && !path.start_with?(Padrino.root('vendor'))
|
|
116
|
+
|
|
117
|
+
"[#{path.gsub("#{root}/", '')}:#{line}] "
|
|
117
118
|
end
|
|
118
119
|
|
|
119
120
|
##
|
|
@@ -132,13 +133,13 @@ module Padrino
|
|
|
132
133
|
# logger.bench 'GET', started_at, '/blog/categories'
|
|
133
134
|
# # => DEBUG - GET (0.0056s) - /blog/categories
|
|
134
135
|
#
|
|
135
|
-
def bench(action, began_at, message, level
|
|
136
|
+
def bench(action, began_at, message, level = :debug, color = :yellow)
|
|
136
137
|
@_pad ||= 8
|
|
137
138
|
@_pad = action.to_s.size if action.to_s.size > @_pad
|
|
138
139
|
duration = Time.now - began_at
|
|
139
140
|
color = :red if duration > 1
|
|
140
141
|
action = colorize(action.to_s.upcase.rjust(@_pad), color)
|
|
141
|
-
duration = colorize('%0.4fs'
|
|
142
|
+
duration = colorize(Kernel.format('%0.4fs', duration), color, :bold)
|
|
142
143
|
push "#{action} (#{duration}) #{message}", level
|
|
143
144
|
end
|
|
144
145
|
|
|
@@ -223,29 +224,34 @@ module Padrino
|
|
|
223
224
|
# Padrino.logger.exception e
|
|
224
225
|
# Padrino.logger.exception(e, :short)
|
|
225
226
|
def exception(boom, verbosity = :long, level = :error)
|
|
226
|
-
return unless Levels.
|
|
227
|
+
return unless Levels.key?(level)
|
|
228
|
+
|
|
227
229
|
text = ["#{boom.class} - #{boom.message}:"]
|
|
228
230
|
trace = boom.backtrace
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
text << trace.first
|
|
234
|
-
|
|
231
|
+
|
|
232
|
+
if trace.is_a?(Array)
|
|
233
|
+
case verbosity
|
|
234
|
+
when :long then text += trace
|
|
235
|
+
when :short then text << trace.first
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
235
239
|
send level, text.join("\n ")
|
|
236
240
|
end
|
|
237
241
|
end
|
|
238
242
|
|
|
239
243
|
module Colorize
|
|
240
244
|
# Colors for levels
|
|
241
|
-
ColoredLevels
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
245
|
+
unless defined?(ColoredLevels)
|
|
246
|
+
ColoredLevels = {
|
|
247
|
+
fatal: %i[bold red],
|
|
248
|
+
error: %i[default red],
|
|
249
|
+
warn: %i[default yellow],
|
|
250
|
+
info: %i[default green],
|
|
251
|
+
debug: %i[default cyan],
|
|
252
|
+
devel: %i[default magenta]
|
|
253
|
+
}
|
|
254
|
+
end
|
|
249
255
|
|
|
250
256
|
##
|
|
251
257
|
# Colorize our level.
|
|
@@ -255,12 +261,12 @@ module Padrino
|
|
|
255
261
|
# @see Padrino::Logging::ColorizedLogger::ColoredLevels
|
|
256
262
|
#
|
|
257
263
|
def colorize(string, *colors)
|
|
258
|
-
string.colorize(:
|
|
264
|
+
string.colorize(color: colors[0], mode: colors[1])
|
|
259
265
|
end
|
|
260
266
|
|
|
261
267
|
def stylized_level(level)
|
|
262
|
-
|
|
263
|
-
[
|
|
268
|
+
colors = ColoredLevels[level].map { |color| String::Colorizer.modes[color] || String::Colorizer.colors[color] }
|
|
269
|
+
[Kernel.format("\e[%d;%dm", *colors), super, "\e[0m"].join
|
|
264
270
|
end
|
|
265
271
|
end
|
|
266
272
|
|
|
@@ -289,7 +295,7 @@ module Padrino
|
|
|
289
295
|
# :colorize_logging:: Whether or not to colorize log messages. Defaults to: true
|
|
290
296
|
#
|
|
291
297
|
# @example
|
|
292
|
-
# Padrino::Logger::Config[:development] = { :
|
|
298
|
+
# Padrino::Logger::Config[:development] = { log_level: :debug, stream: :to_file }
|
|
293
299
|
# # or you can edit our defaults
|
|
294
300
|
# Padrino::Logger::Config[:development][:log_level] = :error
|
|
295
301
|
# # or change log file path
|
|
@@ -301,34 +307,37 @@ module Padrino
|
|
|
301
307
|
#
|
|
302
308
|
# Defaults are:
|
|
303
309
|
#
|
|
304
|
-
# :production => { :
|
|
305
|
-
# :development => { :
|
|
306
|
-
# :test => { :
|
|
310
|
+
# :production => { log_level: :warn, stream: :to_file }
|
|
311
|
+
# :development => { log_level: :debug, stream: :stdout }
|
|
312
|
+
# :test => { log_level: :fatal, stream: :null }
|
|
307
313
|
#
|
|
308
314
|
# In some cases, configuring the loggers before loading the framework is necessary.
|
|
309
315
|
# You can do so by setting PADRINO_LOGGER:
|
|
310
316
|
#
|
|
311
|
-
# PADRINO_LOGGER = { :
|
|
317
|
+
# PADRINO_LOGGER = { staging: { log_level: :debug, stream: :to_file }}
|
|
312
318
|
#
|
|
313
319
|
Config = {
|
|
314
|
-
:
|
|
315
|
-
:
|
|
316
|
-
:
|
|
320
|
+
production: { log_level: :warn, stream: :to_file },
|
|
321
|
+
development: { log_level: :debug, stream: :stdout, format_datetime: '' },
|
|
322
|
+
test: { log_level: :debug, stream: :null }
|
|
317
323
|
}
|
|
318
324
|
Config.merge!(PADRINO_LOGGER) if PADRINO_LOGGER
|
|
319
325
|
|
|
320
|
-
|
|
326
|
+
def self.mutex
|
|
327
|
+
@_mutex ||= Mutex.new
|
|
328
|
+
end
|
|
329
|
+
|
|
321
330
|
def self.logger
|
|
322
331
|
(@_logger ||= nil) || setup!
|
|
323
332
|
end
|
|
324
333
|
|
|
325
334
|
def self.logger=(logger)
|
|
326
335
|
unless logger.class.ancestors.include?(Padrino::Logger::Extensions)
|
|
327
|
-
warn
|
|
328
|
-
WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and other features.
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
336
|
+
warn <<~MESSAGE
|
|
337
|
+
WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and other features.
|
|
338
|
+
To do it with a custom logger you have to manually `new_logger.extend(Padrino::Logger::Extensions)`
|
|
339
|
+
before passing to `Padrino.logger = new_logger`.
|
|
340
|
+
MESSAGE
|
|
332
341
|
end
|
|
333
342
|
@_logger = logger
|
|
334
343
|
end
|
|
@@ -348,9 +357,10 @@ WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and
|
|
|
348
357
|
config = Config[:production]
|
|
349
358
|
end
|
|
350
359
|
|
|
351
|
-
stream =
|
|
360
|
+
stream =
|
|
361
|
+
case config[:stream]
|
|
352
362
|
when :to_file
|
|
353
|
-
if filename = config[:log_path]
|
|
363
|
+
if (filename = config[:log_path])
|
|
354
364
|
filename = Padrino.root(filename) unless Pathname.new(filename).absolute?
|
|
355
365
|
if File.directory?(filename)
|
|
356
366
|
filename = File.join(filename, "#{Padrino.env}.log")
|
|
@@ -366,9 +376,9 @@ WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and
|
|
|
366
376
|
when :stdout then $stdout
|
|
367
377
|
when :stderr then $stderr
|
|
368
378
|
else config[:stream] # return itself, probabilly is a custom stream.
|
|
369
|
-
|
|
379
|
+
end
|
|
370
380
|
|
|
371
|
-
new_logger = Padrino::Logger.new(config.merge(:
|
|
381
|
+
new_logger = Padrino::Logger.new(config.merge(stream: stream))
|
|
372
382
|
new_logger.extend(Padrino::Logger::Extensions)
|
|
373
383
|
self.logger = new_logger
|
|
374
384
|
end
|
|
@@ -406,16 +416,16 @@ WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and
|
|
|
406
416
|
# Can be an encoding, false or true.
|
|
407
417
|
# If it's true, logger sanitizes to Encoding.default_external.
|
|
408
418
|
#
|
|
409
|
-
def initialize(options={})
|
|
419
|
+
def initialize(options = {})
|
|
410
420
|
@buffer = []
|
|
411
|
-
@auto_flush = options.
|
|
421
|
+
@auto_flush = options.key?(:auto_flush) ? options[:auto_flush] : true
|
|
412
422
|
@level = options[:log_level] ? Padrino::Logger::Levels[options[:log_level]] : Padrino::Logger::Levels[:debug]
|
|
413
|
-
@log = options[:stream]
|
|
423
|
+
@log = options[:stream] || $stdout
|
|
414
424
|
@log.sync = true
|
|
415
|
-
@format_datetime = options[:format_datetime] ||
|
|
416
|
-
@format_message = options[:format_message] ||
|
|
417
|
-
@log_static = options.
|
|
418
|
-
@colorize_logging = options.
|
|
425
|
+
@format_datetime = options[:format_datetime] || '%d/%b/%Y %H:%M:%S'
|
|
426
|
+
@format_message = options[:format_message] || '%s - %s %s'
|
|
427
|
+
@log_static = options.key?(:log_static) ? options[:log_static] : false
|
|
428
|
+
@colorize_logging = options.key?(:colorize_logging) ? options[:colorize_logging] : true
|
|
419
429
|
@source_location = options[:source_location]
|
|
420
430
|
@sanitize_encoding = options[:sanitize_encoding] || false
|
|
421
431
|
@sanitize_encoding = Encoding.default_external if @sanitize_encoding == true
|
|
@@ -430,10 +440,10 @@ WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and
|
|
|
430
440
|
# Flush the entire buffer to the log object.
|
|
431
441
|
#
|
|
432
442
|
def flush
|
|
433
|
-
return unless @buffer.size
|
|
434
|
-
|
|
443
|
+
return unless @buffer.size.positive?
|
|
444
|
+
self.class.mutex.synchronize do
|
|
435
445
|
@buffer.each do |line|
|
|
436
|
-
line.encode!(@sanitize_encoding, :
|
|
446
|
+
line.encode!(@sanitize_encoding, invalid: :replace, undef: :replace) if @sanitize_encoding
|
|
437
447
|
@log.write(line)
|
|
438
448
|
end
|
|
439
449
|
@buffer.clear
|
|
@@ -465,17 +475,15 @@ WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and
|
|
|
465
475
|
# The message
|
|
466
476
|
#
|
|
467
477
|
def <<(message = nil)
|
|
468
|
-
message << "\n" unless message[-1] ==
|
|
469
|
-
|
|
470
|
-
@buffer << message
|
|
471
|
-
}
|
|
478
|
+
message << "\n" unless message[-1] == "\n"
|
|
479
|
+
self.class.mutex.synchronize { @buffer << message }
|
|
472
480
|
flush if @auto_flush
|
|
473
481
|
message
|
|
474
482
|
end
|
|
475
|
-
alias
|
|
483
|
+
alias write <<
|
|
476
484
|
|
|
477
485
|
def format(message, level)
|
|
478
|
-
@format_message
|
|
486
|
+
Kernel.format(@format_message, stylized_level(level), colorize(Time.now.strftime(@format_datetime), :yellow), message.to_s.strip)
|
|
479
487
|
end
|
|
480
488
|
|
|
481
489
|
##
|
|
@@ -486,7 +494,7 @@ WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and
|
|
|
486
494
|
class Rack
|
|
487
495
|
def initialize(app, uri_root)
|
|
488
496
|
@app = app
|
|
489
|
-
@uri_root = uri_root.
|
|
497
|
+
@uri_root = uri_root.chomp('/')
|
|
490
498
|
end
|
|
491
499
|
|
|
492
500
|
def call(env)
|
|
@@ -502,17 +510,17 @@ WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and
|
|
|
502
510
|
def log(env, status, header, began_at)
|
|
503
511
|
return if env['sinatra.static_file'] && (!logger.respond_to?(:log_static) || !logger.log_static)
|
|
504
512
|
logger.bench(
|
|
505
|
-
env[
|
|
513
|
+
env['REQUEST_METHOD'],
|
|
506
514
|
began_at,
|
|
507
515
|
[
|
|
508
516
|
@uri_root.to_s,
|
|
509
|
-
env[
|
|
510
|
-
env[
|
|
517
|
+
env['PATH_INFO'],
|
|
518
|
+
env['QUERY_STRING'].empty? ? '' : "?#{env['QUERY_STRING']}",
|
|
511
519
|
' - ',
|
|
512
520
|
logger.colorize(status.to_s[0..3], :default, :bold),
|
|
513
521
|
' ',
|
|
514
522
|
code_to_name(status)
|
|
515
|
-
]
|
|
523
|
+
].join,
|
|
516
524
|
:debug,
|
|
517
525
|
:magenta
|
|
518
526
|
)
|
|
@@ -21,7 +21,7 @@ module Padrino
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def public_folder
|
|
24
|
-
@public_folder ||= trace_method(:public_folder) {
|
|
24
|
+
@public_folder ||= trace_method(:public_folder) { '' }
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def app_name
|
|
@@ -39,7 +39,7 @@ module Padrino
|
|
|
39
39
|
private
|
|
40
40
|
|
|
41
41
|
def require_dependencies
|
|
42
|
-
Padrino.require_dependencies(dependencies, :
|
|
42
|
+
Padrino.require_dependencies(dependencies, force: true)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def trace_method(method_name)
|
data/lib/padrino-core/mounter.rb
CHANGED
|
@@ -6,8 +6,8 @@ module Padrino
|
|
|
6
6
|
# Stores the name of the application (app folder name) and url mount path.
|
|
7
7
|
#
|
|
8
8
|
# @example
|
|
9
|
-
# Mounter.new(
|
|
10
|
-
# Mounter.new(
|
|
9
|
+
# Mounter.new('blog_app', app_class: 'Blog').to('/blog')
|
|
10
|
+
# Mounter.new('blog_app', app_file: '/path/to/blog/app.rb').to('/blog')
|
|
11
11
|
#
|
|
12
12
|
class Mounter
|
|
13
13
|
DEFAULT_CASCADE = [404, 405]
|
|
@@ -27,20 +27,24 @@ module Padrino
|
|
|
27
27
|
# @option options [Symbol] :app_root (Directory of :app_file)
|
|
28
28
|
# @option options [Symbol] :gem The gem to load the app from (Detected from name)
|
|
29
29
|
#
|
|
30
|
-
def initialize(name, options={})
|
|
30
|
+
def initialize(name, options = {})
|
|
31
31
|
@name = name.to_s
|
|
32
32
|
@app_class = options[:app_class] || Inflections.camelize(@name)
|
|
33
|
-
@gem = options[:gem] || Inflections.underscore(@app_class.split(
|
|
33
|
+
@gem = options[:gem] || Inflections.underscore(@app_class.split('::').first)
|
|
34
34
|
@app_file = options[:app_file] || locate_app_file
|
|
35
35
|
@app_obj = options[:app_obj] || app_constant || locate_app_object
|
|
36
|
+
|
|
36
37
|
ensure_app_file! || ensure_app_object!
|
|
37
38
|
unless padrino_application?
|
|
38
39
|
@app_obj.extend ApplicationExtension
|
|
39
40
|
@app_obj.mounter_options = options
|
|
40
41
|
end
|
|
41
|
-
|
|
42
|
-
@
|
|
43
|
-
@
|
|
42
|
+
|
|
43
|
+
@app_root = options[:app_root] || (@app_obj.respond_to?(:root) && @app_obj.root || File.dirname(@app_file))
|
|
44
|
+
@uri_root = '/'
|
|
45
|
+
@cascade = DEFAULT_CASCADE.dup if options[:cascade] == true
|
|
46
|
+
@cascade ||= options[:cascade] ? Array(options[:cascade]) : []
|
|
47
|
+
|
|
44
48
|
Padrino::Reloader.exclude_constants << @app_class
|
|
45
49
|
end
|
|
46
50
|
|
|
@@ -60,7 +64,7 @@ module Padrino
|
|
|
60
64
|
# Mounter.new("blog_app").to("/blog")
|
|
61
65
|
#
|
|
62
66
|
def to(mount_url)
|
|
63
|
-
@uri_root
|
|
67
|
+
@uri_root = mount_url
|
|
64
68
|
Padrino.insert_mounted_app(self)
|
|
65
69
|
self
|
|
66
70
|
end
|
|
@@ -113,7 +117,7 @@ module Padrino
|
|
|
113
117
|
app_obj.public_folder = Padrino.root('public', uri_root) unless public_folder_exists
|
|
114
118
|
end
|
|
115
119
|
app_obj.setup_application! # Initializes the app here with above settings.
|
|
116
|
-
router.map(:
|
|
120
|
+
router.map(to: app_obj, path: uri_root, host: app_data.app_host)
|
|
117
121
|
end
|
|
118
122
|
|
|
119
123
|
###
|
|
@@ -132,21 +136,21 @@ module Padrino
|
|
|
132
136
|
def named_routes
|
|
133
137
|
return [] unless app_obj.respond_to?(:routes)
|
|
134
138
|
|
|
135
|
-
app_obj.routes.map
|
|
139
|
+
app_obj.routes.map do |route|
|
|
136
140
|
request_method = route.request_methods.first
|
|
137
141
|
next if !route.name || request_method == 'HEAD'
|
|
138
142
|
route_name = route.name.to_s
|
|
139
143
|
route_name =
|
|
140
144
|
if route.controller
|
|
141
|
-
route_name.split(
|
|
145
|
+
route_name.split(' ', 2).map { |name| ":#{name}" }.join(', ')
|
|
142
146
|
else
|
|
143
147
|
":#{route_name}"
|
|
144
148
|
end
|
|
145
149
|
name_array = "(#{route_name})"
|
|
146
150
|
original_path = route.original_path.is_a?(Regexp) ? route.original_path.inspect : route.original_path
|
|
147
151
|
full_path = File.join(uri_root, original_path)
|
|
148
|
-
OpenStruct.new(:
|
|
149
|
-
|
|
152
|
+
OpenStruct.new(verb: request_method, identifier: route.name, name: name_array, path: full_path)
|
|
153
|
+
end.compact
|
|
150
154
|
end
|
|
151
155
|
|
|
152
156
|
##
|
|
@@ -163,19 +167,16 @@ module Padrino
|
|
|
163
167
|
# the class object for the app if defined, nil otherwise.
|
|
164
168
|
#
|
|
165
169
|
def app_constant
|
|
166
|
-
klass
|
|
167
|
-
for piece in app_class.split("::")
|
|
170
|
+
app_class.split('::').inject(Object) do |klass, piece|
|
|
168
171
|
piece = piece.to_sym
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
return
|
|
173
|
-
end
|
|
172
|
+
break unless klass.const_defined?(piece, false)
|
|
173
|
+
|
|
174
|
+
klass.const_get(piece)
|
|
174
175
|
end
|
|
175
|
-
klass
|
|
176
176
|
end
|
|
177
177
|
|
|
178
178
|
protected
|
|
179
|
+
|
|
179
180
|
##
|
|
180
181
|
# Locates and requires the file to load the app constant.
|
|
181
182
|
#
|
|
@@ -196,15 +197,13 @@ module Padrino
|
|
|
196
197
|
candidates = []
|
|
197
198
|
candidates << app_const.app_file if app_const.respond_to?(:app_file)
|
|
198
199
|
candidates << Padrino.first_caller if File.identical?(Padrino.first_caller.to_s, Padrino.called_from.to_s)
|
|
199
|
-
candidates << Padrino.mounted_root(name.downcase,
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
end
|
|
207
|
-
candidates << Padrino.root("app", "app.rb")
|
|
200
|
+
candidates << Padrino.mounted_root(name.downcase, 'app.rb')
|
|
201
|
+
|
|
202
|
+
simple_name = name.split('::').last.downcase
|
|
203
|
+
mod_name = name.split('::')[0..-2].join('::')
|
|
204
|
+
|
|
205
|
+
Padrino.modules.each { |mod| candidates << mod.root(simple_name, 'app.rb') if mod.name == mod_name }
|
|
206
|
+
candidates << Padrino.root('app', 'app.rb')
|
|
208
207
|
candidates.find { |candidate| File.exist?(candidate) }
|
|
209
208
|
end
|
|
210
209
|
|
|
@@ -212,7 +211,7 @@ module Padrino
|
|
|
212
211
|
# Raises an exception unless app_file is located properly.
|
|
213
212
|
#
|
|
214
213
|
def ensure_app_file!
|
|
215
|
-
message = "Unable to locate source file for app '#{app_class}', try with :
|
|
214
|
+
message = "Unable to locate source file for app '#{app_class}', try with app_file: '/path/app.rb'"
|
|
216
215
|
raise MounterException, message unless @app_file
|
|
217
216
|
end
|
|
218
217
|
|
|
@@ -220,7 +219,7 @@ module Padrino
|
|
|
220
219
|
# Raises an exception unless app_obj is defined properly.
|
|
221
220
|
#
|
|
222
221
|
def ensure_app_object!
|
|
223
|
-
message = "Unable to locate app for '#{app_class}', try with :
|
|
222
|
+
message = "Unable to locate app for '#{app_class}', try with app_class: 'MyAppClass'"
|
|
224
223
|
raise MounterException, message unless @app_obj
|
|
225
224
|
end
|
|
226
225
|
end
|
|
@@ -235,7 +234,7 @@ module Padrino
|
|
|
235
234
|
# the root to the mounted apps base directory.
|
|
236
235
|
#
|
|
237
236
|
def mounted_root(*args)
|
|
238
|
-
Padrino.root(@mounted_root ||=
|
|
237
|
+
Padrino.root(@mounted_root ||= '', *args)
|
|
239
238
|
end
|
|
240
239
|
|
|
241
240
|
##
|
|
@@ -263,7 +262,7 @@ module Padrino
|
|
|
263
262
|
# @example
|
|
264
263
|
# Padrino.mount("blog_app").to("/blog")
|
|
265
264
|
#
|
|
266
|
-
def mount(name, options={})
|
|
265
|
+
def mount(name, options = {})
|
|
267
266
|
Mounter.new(name, options)
|
|
268
267
|
end
|
|
269
268
|
end
|
|
@@ -12,7 +12,7 @@ module Padrino
|
|
|
12
12
|
def initialize(routes)
|
|
13
13
|
@routes = routes
|
|
14
14
|
end
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
##
|
|
17
17
|
# Compiles all routes into regexps.
|
|
18
18
|
#
|
|
@@ -37,7 +37,7 @@ module Padrino
|
|
|
37
37
|
#
|
|
38
38
|
def find_by(request_or_env)
|
|
39
39
|
request = request_or_env.is_a?(Hash) ? Sinatra::Request.new(request_or_env) : request_or_env
|
|
40
|
-
pattern
|
|
40
|
+
pattern = decode_pattern(request.path_info)
|
|
41
41
|
verb = request.request_method
|
|
42
42
|
rotation { |offset| match?(offset, pattern) }.select { |route| route.verb == verb }
|
|
43
43
|
end
|
|
@@ -47,8 +47,8 @@ module Padrino
|
|
|
47
47
|
#
|
|
48
48
|
def call_by_request(request)
|
|
49
49
|
rotation do |offset|
|
|
50
|
-
pattern
|
|
51
|
-
if route = match?(offset, pattern)
|
|
50
|
+
pattern = decode_pattern(request.path_info)
|
|
51
|
+
if (route = match?(offset, pattern))
|
|
52
52
|
params = route.params_for(pattern, request.params)
|
|
53
53
|
yield(route, params) if route.verb == request.request_method
|
|
54
54
|
route
|
|
@@ -63,15 +63,15 @@ module Padrino
|
|
|
63
63
|
pattern = decode_pattern(pattern)
|
|
64
64
|
rotation { |offset| match?(offset, pattern) }
|
|
65
65
|
end
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
private
|
|
68
68
|
|
|
69
69
|
##
|
|
70
70
|
# Returns a instance of PathRouter::Route if path is matched with current regexp
|
|
71
71
|
#
|
|
72
72
|
def match?(offset, path)
|
|
73
|
-
@routes[offset
|
|
74
|
-
route.regexp === path || (path.end_with?(
|
|
73
|
+
@routes[offset..].find do |route|
|
|
74
|
+
route.regexp === path || (path.end_with?('/') && route.regexp === path[0..-2])
|
|
75
75
|
end
|
|
76
76
|
end
|
|
77
77
|
|
|
@@ -81,7 +81,7 @@ module Padrino
|
|
|
81
81
|
def rotation(offset = 0)
|
|
82
82
|
compile! unless compiled?
|
|
83
83
|
loop.with_object([]) do |_, candidacies|
|
|
84
|
-
return candidacies unless route = yield(offset)
|
|
84
|
+
return candidacies unless (route = yield(offset))
|
|
85
85
|
candidacies << route
|
|
86
86
|
offset = route.index.next
|
|
87
87
|
end
|
|
@@ -4,13 +4,13 @@ module Padrino
|
|
|
4
4
|
module PathRouter
|
|
5
5
|
class Matcher
|
|
6
6
|
# To count group of regexp
|
|
7
|
-
GROUP_REGEXP =
|
|
7
|
+
GROUP_REGEXP = /\((?!\?:|\?!|\?<=|\?<!|\?=).+?\)/
|
|
8
8
|
|
|
9
9
|
##
|
|
10
10
|
# Constructs an instance of PathRouter::Matcher.
|
|
11
11
|
#
|
|
12
12
|
def initialize(path, options = {})
|
|
13
|
-
@path = path.is_a?(String) && path.empty? ?
|
|
13
|
+
@path = path.is_a?(String) && path.empty? ? '/' : path
|
|
14
14
|
@capture = options[:capture]
|
|
15
15
|
@default_values = options[:default_values]
|
|
16
16
|
end
|
|
@@ -19,9 +19,9 @@ module Padrino
|
|
|
19
19
|
# Matches a pattern with the route matcher.
|
|
20
20
|
#
|
|
21
21
|
def match(pattern)
|
|
22
|
-
if match_data = handler.match(pattern)
|
|
22
|
+
if (match_data = handler.match(pattern))
|
|
23
23
|
match_data
|
|
24
|
-
elsif pattern !=
|
|
24
|
+
elsif pattern != '/' && pattern.end_with?('/')
|
|
25
25
|
handler.match(pattern[0..-2])
|
|
26
26
|
end
|
|
27
27
|
end
|
|
@@ -42,7 +42,7 @@ module Padrino
|
|
|
42
42
|
parts[handler.names.include?(key.to_s) ? 0 : 1][key] = val
|
|
43
43
|
end
|
|
44
44
|
expanded_path = handler.expand(:append, params)
|
|
45
|
-
expanded_path +=
|
|
45
|
+
expanded_path += "?#{Padrino::Utils.build_uri_query(query)}" unless query.empty?
|
|
46
46
|
expanded_path
|
|
47
47
|
end
|
|
48
48
|
|
|
@@ -60,15 +60,15 @@ module Padrino
|
|
|
60
60
|
data = match(pattern)
|
|
61
61
|
params = indifferent_hash
|
|
62
62
|
if data.names.empty?
|
|
63
|
-
params.merge!(:
|
|
63
|
+
params.merge!(captures: data.captures) unless data.captures.empty?
|
|
64
64
|
else
|
|
65
65
|
if mustermann?
|
|
66
|
-
new_params = handler.params(pattern, :
|
|
66
|
+
new_params = handler.params(pattern, captures: data)
|
|
67
67
|
params.merge!(new_params) if new_params
|
|
68
68
|
elsif data
|
|
69
69
|
params.merge!(Hash[names.zip(data.captures)])
|
|
70
70
|
end
|
|
71
|
-
params.merge!(others){ |_, old, new| old || new }
|
|
71
|
+
params.merge!(others) { |_, old, new| old || new }
|
|
72
72
|
end
|
|
73
73
|
params
|
|
74
74
|
end
|
|
@@ -80,7 +80,7 @@ module Padrino
|
|
|
80
80
|
@handler ||=
|
|
81
81
|
case @path
|
|
82
82
|
when String
|
|
83
|
-
Mustermann.new(@path, :
|
|
83
|
+
Mustermann.new(@path, capture: @capture, uri_decode: false)
|
|
84
84
|
when Regexp
|
|
85
85
|
/^(?:#{@path})$/
|
|
86
86
|
else
|
|
@@ -108,7 +108,7 @@ module Padrino
|
|
|
108
108
|
#
|
|
109
109
|
def capture_length
|
|
110
110
|
if mustermann?
|
|
111
|
-
handler.named_captures.inject(0) { |count, (_, capture)| count
|
|
111
|
+
handler.named_captures.inject(0) { |count, (_, capture)| count + capture.length }
|
|
112
112
|
else
|
|
113
113
|
handler.inspect.scan(GROUP_REGEXP).length
|
|
114
114
|
end
|
|
@@ -120,7 +120,7 @@ module Padrino
|
|
|
120
120
|
# Creates a hash with indifferent access.
|
|
121
121
|
#
|
|
122
122
|
def indifferent_hash
|
|
123
|
-
Hash.new{ |hash, key| hash[key.to_s] if key.instance_of?(Symbol) }
|
|
123
|
+
Hash.new { |hash, key| hash[key.to_s] if key.instance_of?(Symbol) }
|
|
124
124
|
end
|
|
125
125
|
end
|
|
126
126
|
end
|