padrino-core 0.16.0.pre3 → 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 +28 -30
- 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 +87 -78
- 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 -17
- 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 +52 -53
- data/test/test_flash.rb +18 -18
- data/test/test_locale.rb +2 -2
- data/test/test_logger.rb +65 -65
- data/test/test_mounter.rb +133 -123
- data/test/test_params_protection.rb +40 -40
- data/test/test_reloader_complex.rb +24 -24
- 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 +897 -909
- metadata +7 -7
data/lib/padrino-core/loader.rb
CHANGED
|
@@ -142,24 +142,22 @@ module Padrino
|
|
|
142
142
|
# require_dependencies("#{Padrino.root}/lib/**/*.rb")
|
|
143
143
|
#
|
|
144
144
|
def require_dependencies(*paths)
|
|
145
|
-
options = { :
|
|
145
|
+
options = { cyclic: true }.update(paths.last.is_a?(Hash) ? paths.pop : {})
|
|
146
146
|
|
|
147
|
-
files = paths.flatten.flat_map{ |path| Dir.glob(path).sort_by{ |filename| filename.count('/') } }.uniq
|
|
147
|
+
files = paths.flatten.flat_map { |path| Dir.glob(path).sort_by { |filename| filename.count('/') } }.uniq
|
|
148
148
|
|
|
149
149
|
until files.empty?
|
|
150
150
|
error = fatal = loaded = nil
|
|
151
151
|
|
|
152
152
|
files.dup.each do |file|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
break
|
|
162
|
-
|
|
153
|
+
Reloader.safe_load(file, options)
|
|
154
|
+
files.delete(file)
|
|
155
|
+
loaded = true
|
|
156
|
+
rescue NameError, LoadError => error
|
|
157
|
+
raise if Reloader.exclude.any? { |path| file.start_with?(path) } || options[:cyclic] == false
|
|
158
|
+
logger.devel "Cyclic dependency reload for #{error.class}: #{error.message}"
|
|
159
|
+
rescue Exception => fatal
|
|
160
|
+
break
|
|
163
161
|
end
|
|
164
162
|
|
|
165
163
|
next unless fatal || !loaded
|
data/lib/padrino-core/logger.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'pathname'
|
|
2
|
+
require 'stringio'
|
|
2
3
|
|
|
3
4
|
# Defines the log level for a Padrino project.
|
|
4
5
|
PADRINO_LOG_LEVEL = ENV['PADRINO_LOG_LEVEL'] unless defined?(PADRINO_LOG_LEVEL)
|
|
@@ -62,14 +63,16 @@ module Padrino
|
|
|
62
63
|
# :debug:: low-level information for developers
|
|
63
64
|
# :devel:: Development-related information that is unnecessary in debug mode
|
|
64
65
|
#
|
|
65
|
-
Levels
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
|
73
76
|
|
|
74
77
|
module Extensions
|
|
75
78
|
##
|
|
@@ -78,22 +81,20 @@ module Padrino
|
|
|
78
81
|
Padrino::Logger::Levels.each_pair do |name, number|
|
|
79
82
|
define_method(name) do |*args|
|
|
80
83
|
return if number < level
|
|
84
|
+
|
|
81
85
|
if args.size > 1
|
|
82
86
|
bench(args[0], args[1], args[2], name)
|
|
83
87
|
else
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
end if enable_source_location?
|
|
88
|
+
location = resolve_source_location(caller(1).shift)
|
|
89
|
+
args.unshift(location) if location && enable_source_location?
|
|
87
90
|
push(args * '', name)
|
|
88
91
|
end
|
|
89
92
|
end
|
|
90
93
|
|
|
91
|
-
define_method(:"#{name}?")
|
|
92
|
-
number >= level
|
|
93
|
-
end
|
|
94
|
+
define_method(:"#{name}?") { number >= level }
|
|
94
95
|
end
|
|
95
96
|
|
|
96
|
-
SOURCE_LOCATION_REGEXP = /^(.*?):(\d+?)(?::in `.+?')
|
|
97
|
+
SOURCE_LOCATION_REGEXP = /^(.*?):(\d+?)(?::in `.+?')?$/
|
|
97
98
|
|
|
98
99
|
##
|
|
99
100
|
# Returns true if :source_location is set to true.
|
|
@@ -108,11 +109,12 @@ module Padrino
|
|
|
108
109
|
def resolve_source_location(message)
|
|
109
110
|
path, line = *message.scan(SOURCE_LOCATION_REGEXP).first
|
|
110
111
|
return unless path && line
|
|
112
|
+
|
|
111
113
|
root = Padrino.root
|
|
112
114
|
path = File.realpath(path) if Pathname.new(path).relative?
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
115
|
+
return unless path.start_with?(root) && !path.start_with?(Padrino.root('vendor'))
|
|
116
|
+
|
|
117
|
+
"[#{path.gsub("#{root}/", '')}:#{line}] "
|
|
116
118
|
end
|
|
117
119
|
|
|
118
120
|
##
|
|
@@ -131,13 +133,13 @@ module Padrino
|
|
|
131
133
|
# logger.bench 'GET', started_at, '/blog/categories'
|
|
132
134
|
# # => DEBUG - GET (0.0056s) - /blog/categories
|
|
133
135
|
#
|
|
134
|
-
def bench(action, began_at, message, level
|
|
136
|
+
def bench(action, began_at, message, level = :debug, color = :yellow)
|
|
135
137
|
@_pad ||= 8
|
|
136
138
|
@_pad = action.to_s.size if action.to_s.size > @_pad
|
|
137
139
|
duration = Time.now - began_at
|
|
138
140
|
color = :red if duration > 1
|
|
139
141
|
action = colorize(action.to_s.upcase.rjust(@_pad), color)
|
|
140
|
-
duration = colorize('%0.4fs'
|
|
142
|
+
duration = colorize(Kernel.format('%0.4fs', duration), color, :bold)
|
|
141
143
|
push "#{action} (#{duration}) #{message}", level
|
|
142
144
|
end
|
|
143
145
|
|
|
@@ -222,29 +224,34 @@ module Padrino
|
|
|
222
224
|
# Padrino.logger.exception e
|
|
223
225
|
# Padrino.logger.exception(e, :short)
|
|
224
226
|
def exception(boom, verbosity = :long, level = :error)
|
|
225
|
-
return unless Levels.
|
|
227
|
+
return unless Levels.key?(level)
|
|
228
|
+
|
|
226
229
|
text = ["#{boom.class} - #{boom.message}:"]
|
|
227
230
|
trace = boom.backtrace
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
text << trace.first
|
|
233
|
-
|
|
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
|
+
|
|
234
239
|
send level, text.join("\n ")
|
|
235
240
|
end
|
|
236
241
|
end
|
|
237
242
|
|
|
238
243
|
module Colorize
|
|
239
244
|
# Colors for levels
|
|
240
|
-
ColoredLevels
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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
|
|
248
255
|
|
|
249
256
|
##
|
|
250
257
|
# Colorize our level.
|
|
@@ -254,12 +261,12 @@ module Padrino
|
|
|
254
261
|
# @see Padrino::Logging::ColorizedLogger::ColoredLevels
|
|
255
262
|
#
|
|
256
263
|
def colorize(string, *colors)
|
|
257
|
-
string.colorize(:
|
|
264
|
+
string.colorize(color: colors[0], mode: colors[1])
|
|
258
265
|
end
|
|
259
266
|
|
|
260
267
|
def stylized_level(level)
|
|
261
|
-
|
|
262
|
-
[
|
|
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
|
|
263
270
|
end
|
|
264
271
|
end
|
|
265
272
|
|
|
@@ -288,7 +295,7 @@ module Padrino
|
|
|
288
295
|
# :colorize_logging:: Whether or not to colorize log messages. Defaults to: true
|
|
289
296
|
#
|
|
290
297
|
# @example
|
|
291
|
-
# Padrino::Logger::Config[:development] = { :
|
|
298
|
+
# Padrino::Logger::Config[:development] = { log_level: :debug, stream: :to_file }
|
|
292
299
|
# # or you can edit our defaults
|
|
293
300
|
# Padrino::Logger::Config[:development][:log_level] = :error
|
|
294
301
|
# # or change log file path
|
|
@@ -300,34 +307,37 @@ module Padrino
|
|
|
300
307
|
#
|
|
301
308
|
# Defaults are:
|
|
302
309
|
#
|
|
303
|
-
# :production => { :
|
|
304
|
-
# :development => { :
|
|
305
|
-
# :test => { :
|
|
310
|
+
# :production => { log_level: :warn, stream: :to_file }
|
|
311
|
+
# :development => { log_level: :debug, stream: :stdout }
|
|
312
|
+
# :test => { log_level: :fatal, stream: :null }
|
|
306
313
|
#
|
|
307
314
|
# In some cases, configuring the loggers before loading the framework is necessary.
|
|
308
315
|
# You can do so by setting PADRINO_LOGGER:
|
|
309
316
|
#
|
|
310
|
-
# PADRINO_LOGGER = { :
|
|
317
|
+
# PADRINO_LOGGER = { staging: { log_level: :debug, stream: :to_file }}
|
|
311
318
|
#
|
|
312
319
|
Config = {
|
|
313
|
-
:
|
|
314
|
-
:
|
|
315
|
-
:
|
|
320
|
+
production: { log_level: :warn, stream: :to_file },
|
|
321
|
+
development: { log_level: :debug, stream: :stdout, format_datetime: '' },
|
|
322
|
+
test: { log_level: :debug, stream: :null }
|
|
316
323
|
}
|
|
317
324
|
Config.merge!(PADRINO_LOGGER) if PADRINO_LOGGER
|
|
318
325
|
|
|
319
|
-
|
|
326
|
+
def self.mutex
|
|
327
|
+
@_mutex ||= Mutex.new
|
|
328
|
+
end
|
|
329
|
+
|
|
320
330
|
def self.logger
|
|
321
331
|
(@_logger ||= nil) || setup!
|
|
322
332
|
end
|
|
323
333
|
|
|
324
334
|
def self.logger=(logger)
|
|
325
335
|
unless logger.class.ancestors.include?(Padrino::Logger::Extensions)
|
|
326
|
-
warn
|
|
327
|
-
WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and other features.
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
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
|
|
331
341
|
end
|
|
332
342
|
@_logger = logger
|
|
333
343
|
end
|
|
@@ -347,9 +357,10 @@ WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and
|
|
|
347
357
|
config = Config[:production]
|
|
348
358
|
end
|
|
349
359
|
|
|
350
|
-
stream =
|
|
360
|
+
stream =
|
|
361
|
+
case config[:stream]
|
|
351
362
|
when :to_file
|
|
352
|
-
if filename = config[:log_path]
|
|
363
|
+
if (filename = config[:log_path])
|
|
353
364
|
filename = Padrino.root(filename) unless Pathname.new(filename).absolute?
|
|
354
365
|
if File.directory?(filename)
|
|
355
366
|
filename = File.join(filename, "#{Padrino.env}.log")
|
|
@@ -361,13 +372,13 @@ WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and
|
|
|
361
372
|
FileUtils.mkdir_p(Padrino.root('log')) unless File.exist?(Padrino.root('log'))
|
|
362
373
|
File.new(Padrino.root('log', "#{Padrino.env}.log"), 'a+')
|
|
363
374
|
end
|
|
364
|
-
when :null then StringIO.new
|
|
375
|
+
when :null then ::StringIO.new
|
|
365
376
|
when :stdout then $stdout
|
|
366
377
|
when :stderr then $stderr
|
|
367
378
|
else config[:stream] # return itself, probabilly is a custom stream.
|
|
368
|
-
|
|
379
|
+
end
|
|
369
380
|
|
|
370
|
-
new_logger = Padrino::Logger.new(config.merge(:
|
|
381
|
+
new_logger = Padrino::Logger.new(config.merge(stream: stream))
|
|
371
382
|
new_logger.extend(Padrino::Logger::Extensions)
|
|
372
383
|
self.logger = new_logger
|
|
373
384
|
end
|
|
@@ -405,16 +416,16 @@ WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and
|
|
|
405
416
|
# Can be an encoding, false or true.
|
|
406
417
|
# If it's true, logger sanitizes to Encoding.default_external.
|
|
407
418
|
#
|
|
408
|
-
def initialize(options={})
|
|
419
|
+
def initialize(options = {})
|
|
409
420
|
@buffer = []
|
|
410
|
-
@auto_flush = options.
|
|
421
|
+
@auto_flush = options.key?(:auto_flush) ? options[:auto_flush] : true
|
|
411
422
|
@level = options[:log_level] ? Padrino::Logger::Levels[options[:log_level]] : Padrino::Logger::Levels[:debug]
|
|
412
|
-
@log = options[:stream]
|
|
423
|
+
@log = options[:stream] || $stdout
|
|
413
424
|
@log.sync = true
|
|
414
|
-
@format_datetime = options[:format_datetime] ||
|
|
415
|
-
@format_message = options[:format_message] ||
|
|
416
|
-
@log_static = options.
|
|
417
|
-
@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
|
|
418
429
|
@source_location = options[:source_location]
|
|
419
430
|
@sanitize_encoding = options[:sanitize_encoding] || false
|
|
420
431
|
@sanitize_encoding = Encoding.default_external if @sanitize_encoding == true
|
|
@@ -429,10 +440,10 @@ WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and
|
|
|
429
440
|
# Flush the entire buffer to the log object.
|
|
430
441
|
#
|
|
431
442
|
def flush
|
|
432
|
-
return unless @buffer.size
|
|
433
|
-
|
|
443
|
+
return unless @buffer.size.positive?
|
|
444
|
+
self.class.mutex.synchronize do
|
|
434
445
|
@buffer.each do |line|
|
|
435
|
-
line.encode!(@sanitize_encoding, :
|
|
446
|
+
line.encode!(@sanitize_encoding, invalid: :replace, undef: :replace) if @sanitize_encoding
|
|
436
447
|
@log.write(line)
|
|
437
448
|
end
|
|
438
449
|
@buffer.clear
|
|
@@ -464,17 +475,15 @@ WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and
|
|
|
464
475
|
# The message
|
|
465
476
|
#
|
|
466
477
|
def <<(message = nil)
|
|
467
|
-
message << "\n" unless message[-1] ==
|
|
468
|
-
|
|
469
|
-
@buffer << message
|
|
470
|
-
}
|
|
478
|
+
message << "\n" unless message[-1] == "\n"
|
|
479
|
+
self.class.mutex.synchronize { @buffer << message }
|
|
471
480
|
flush if @auto_flush
|
|
472
481
|
message
|
|
473
482
|
end
|
|
474
|
-
alias
|
|
483
|
+
alias write <<
|
|
475
484
|
|
|
476
485
|
def format(message, level)
|
|
477
|
-
@format_message
|
|
486
|
+
Kernel.format(@format_message, stylized_level(level), colorize(Time.now.strftime(@format_datetime), :yellow), message.to_s.strip)
|
|
478
487
|
end
|
|
479
488
|
|
|
480
489
|
##
|
|
@@ -485,7 +494,7 @@ WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and
|
|
|
485
494
|
class Rack
|
|
486
495
|
def initialize(app, uri_root)
|
|
487
496
|
@app = app
|
|
488
|
-
@uri_root = uri_root.
|
|
497
|
+
@uri_root = uri_root.chomp('/')
|
|
489
498
|
end
|
|
490
499
|
|
|
491
500
|
def call(env)
|
|
@@ -501,17 +510,17 @@ WARNING! `Padrino.logger = new_logger` no longer extends it with #colorize! and
|
|
|
501
510
|
def log(env, status, header, began_at)
|
|
502
511
|
return if env['sinatra.static_file'] && (!logger.respond_to?(:log_static) || !logger.log_static)
|
|
503
512
|
logger.bench(
|
|
504
|
-
env[
|
|
513
|
+
env['REQUEST_METHOD'],
|
|
505
514
|
began_at,
|
|
506
515
|
[
|
|
507
516
|
@uri_root.to_s,
|
|
508
|
-
env[
|
|
509
|
-
env[
|
|
517
|
+
env['PATH_INFO'],
|
|
518
|
+
env['QUERY_STRING'].empty? ? '' : "?#{env['QUERY_STRING']}",
|
|
510
519
|
' - ',
|
|
511
520
|
logger.colorize(status.to_s[0..3], :default, :bold),
|
|
512
521
|
' ',
|
|
513
522
|
code_to_name(status)
|
|
514
|
-
]
|
|
523
|
+
].join,
|
|
515
524
|
:debug,
|
|
516
525
|
:magenta
|
|
517
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
|