padrino-core 0.6.3 → 0.6.7
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.
- data/VERSION +1 -1
- data/bin/padrino +1 -1
- data/lib/padrino-core.rb +72 -38
- data/lib/padrino-core/application.rb +114 -58
- data/lib/padrino-core/caller.rb +8 -2
- data/lib/padrino-core/cli.rb +4 -3
- data/lib/padrino-core/cli/rake.rb +0 -1
- data/lib/padrino-core/loader.rb +62 -12
- data/lib/padrino-core/logger.rb +37 -18
- data/lib/padrino-core/mounter.rb +41 -9
- data/lib/padrino-core/reloader.rb +4 -2
- data/lib/padrino-core/server.rb +14 -2
- data/lib/padrino-core/stat.rb +10 -4
- data/lib/padrino-core/support_lite.rb +23 -21
- data/lib/padrino-core/tasks.rb +6 -3
- data/lib/padrino-core/version.rb +8 -2
- data/padrino-core.gemspec +6 -3
- data/test/fixtures/apps/simple.rb +7 -1
- data/test/fixtures/dependencies/a.rb +4 -0
- data/test/fixtures/dependencies/b.rb +4 -0
- data/test/fixtures/dependencies/c.rb +1 -0
- data/test/helper.rb +8 -0
- data/test/test_core.rb +18 -2
- data/test/test_dependencies.rb +27 -0
- metadata +6 -3
- data/lib/padrino-core/routing.rb +0 -0
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.7
|
data/bin/padrino
CHANGED
data/lib/padrino-core.rb
CHANGED
@@ -6,49 +6,83 @@ PADRINO_ENV = ENV["PADRINO_ENV"] ||= ENV["RACK_ENV"] ||= "development" unless de
|
|
6
6
|
|
7
7
|
module Padrino
|
8
8
|
class ApplicationLoadError < RuntimeError; end
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
9
|
+
|
10
|
+
class << self
|
11
|
+
##
|
12
|
+
# Helper method for file references.
|
13
|
+
#
|
14
|
+
# Example:
|
15
|
+
# # Referencing a file in config called settings.yml
|
16
|
+
# Padrino.root("config", "settings.yml")
|
17
|
+
# # returns PADRINO_ROOT + "/config/setting.yml"
|
18
|
+
#
|
19
|
+
def root(*args)
|
20
|
+
File.expand_path(File.join(PADRINO_ROOT, *args))
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Helper method that return PADRINO_ENV
|
25
|
+
#
|
26
|
+
def env
|
27
|
+
PADRINO_ENV.to_s.downcase.to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Returns the resulting rack builder mapping each 'mounted' application
|
32
|
+
#
|
33
|
+
def application
|
34
|
+
raise ApplicationLoadError.new("At least one app must be mounted!") unless self.mounted_apps && self.mounted_apps.any?
|
35
|
+
builder = Rack::Builder.new
|
36
|
+
self.mounted_apps.each { |app| app.map_onto(builder) }
|
37
|
+
builder
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Default encoding to UTF8 if it has not already been set to something else.
|
42
|
+
#
|
43
|
+
def set_encoding
|
44
|
+
unless RUBY_VERSION >= '1.9'
|
45
|
+
$KCODE = 'UTF8' if $KCODE == 'NONE' || $KCODE.blank?
|
46
|
+
end
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Returns the used $LOAD_PATHS from padrino
|
52
|
+
#
|
53
|
+
def load_paths
|
54
|
+
%w(
|
55
|
+
lib
|
56
|
+
models
|
57
|
+
shared
|
58
|
+
).map { |dir| root(dir) }
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# Method used for require dependencies and correct support_lite
|
63
|
+
#
|
64
|
+
def require_dependencies!
|
65
|
+
require root('vendor', 'gems', 'environment')
|
66
|
+
Bundler.require_env(Padrino.env)
|
45
67
|
Dir[File.dirname(__FILE__) + '/padrino-core/*.rb'].each {|file| require file }
|
68
|
+
puts "=> Loaded bundled gems for #{Padrino.env} with #{Padrino.support.to_s.humanize}"
|
69
|
+
rescue LoadError
|
70
|
+
require 'bundler'
|
71
|
+
if File.exist?(root("Gemfile"))
|
72
|
+
Bundler::Bundle.load(root("Gemfile")).environment.require_env(Padrino.env)
|
73
|
+
Dir[File.dirname(__FILE__) + '/padrino-core/*.rb'].each {|file| require file }
|
74
|
+
puts "=> Located Gemfile for #{Padrino.env} with #{Padrino.support.to_s.humanize}"
|
75
|
+
else
|
76
|
+
Dir[File.dirname(__FILE__) + '/padrino-core/*.rb'].each {|file| require file }
|
77
|
+
end
|
46
78
|
end
|
47
|
-
end
|
48
|
-
end
|
79
|
+
end # self
|
80
|
+
end # Padrino
|
49
81
|
|
82
|
+
##
|
50
83
|
# When we require this file is necessary check if we have a gemfile o bundled gems,
|
51
84
|
# this because we load ExtLib or ActiveSupport if some of our dependencies
|
52
85
|
# just require them. This prevent for example to load ActiveSupport
|
53
86
|
# when we require only 'dm-core'.
|
87
|
+
#
|
54
88
|
Padrino.require_dependencies!
|
@@ -1,61 +1,34 @@
|
|
1
1
|
module Padrino
|
2
2
|
class ApplicationSetupError < RuntimeError; end
|
3
|
+
##
|
3
4
|
# Subclasses of this become independent Padrino applications (stemming from Sinatra::Application)
|
4
5
|
# These subclassed applications can be easily mounted into other Padrino applications as well.
|
6
|
+
#
|
5
7
|
class Application < Sinatra::Application
|
6
8
|
|
7
|
-
# Return the request format, this is useful when we need to respond to a given content_type like:
|
8
|
-
#
|
9
|
-
# get :index, :respond_to => :any do
|
10
|
-
# case content_type
|
11
|
-
# when :js then ...
|
12
|
-
# when :json then ...
|
13
|
-
# when :html then ...
|
14
|
-
# end
|
15
|
-
# end
|
16
|
-
def content_type(type=nil, params={})
|
17
|
-
type.nil? ? @_content_type : super(type, params)
|
18
|
-
end
|
19
|
-
|
20
|
-
|
21
|
-
# Instance method for url generation like:
|
22
|
-
#
|
23
|
-
# url(:show, :id => 1)
|
24
|
-
# url(:show, :name => :test)
|
25
|
-
# url("/show/:id/:name", :id => 1, :name => foo)
|
26
|
-
#
|
27
|
-
def url(name, *params)
|
28
|
-
self.class.url(name, *params)
|
29
|
-
end
|
30
|
-
alias :url_for :url
|
31
|
-
|
32
|
-
# This is mostly just a helper so request.path_info isn't changed when
|
33
|
-
# serving files from the public directory
|
34
|
-
def static_file?(path)
|
35
|
-
public_dir = File.expand_path(options.public)
|
36
|
-
path = File.expand_path(File.join(public_dir, unescape(path)))
|
37
|
-
path[0, public_dir.length] == public_dir && File.file?(path)
|
38
|
-
end
|
39
|
-
|
40
9
|
class << self
|
41
10
|
def inherited(subclass)
|
42
11
|
CALLERS_TO_IGNORE.concat(PADRINO_IGNORE_CALLERS)
|
43
12
|
subclass.default_configuration!
|
44
|
-
Padrino.
|
13
|
+
Padrino.set_load_paths File.join(subclass.root, "/models")
|
14
|
+
Padrino.require_dependencies File.join(subclass.root, "/models/**/*.rb")
|
45
15
|
super # Loading the subclass
|
46
16
|
subclass.default_filters!
|
47
17
|
subclass.default_routes!
|
48
18
|
end
|
49
19
|
|
20
|
+
##
|
50
21
|
# Hooks into when a new instance of the application is created
|
51
22
|
# This is used because putting the configuration into inherited doesn't
|
52
23
|
# take into account overwritten app settings inside subclassed definitions
|
53
|
-
# Only performs the setup first time application is initialized
|
24
|
+
# Only performs the setup first time application is initialized.
|
25
|
+
#
|
54
26
|
def new(*args, &bk)
|
55
27
|
setup_application!
|
56
28
|
super
|
57
29
|
end
|
58
30
|
|
31
|
+
##
|
59
32
|
# Method for organize in a better way our routes like:
|
60
33
|
#
|
61
34
|
# controller :admin do
|
@@ -79,7 +52,7 @@ module Padrino
|
|
79
52
|
#
|
80
53
|
# # => "/admin"
|
81
54
|
# # => "/admin/show/1"
|
82
|
-
#
|
55
|
+
#
|
83
56
|
def controller(*extensions, &block)
|
84
57
|
if block_given?
|
85
58
|
@_controller, original = extensions, @_controller
|
@@ -91,7 +64,9 @@ module Padrino
|
|
91
64
|
end
|
92
65
|
alias :controllers :controller
|
93
66
|
|
94
|
-
|
67
|
+
##
|
68
|
+
# Usher router, for fatures and configurations see: http://github.com/joshbuddy/usher
|
69
|
+
#
|
95
70
|
def router
|
96
71
|
@router ||= Usher.new(:request_methods => [:request_method, :host, :port, :scheme],
|
97
72
|
:ignore_trailing_delimiters => true,
|
@@ -100,6 +75,7 @@ module Padrino
|
|
100
75
|
end
|
101
76
|
alias :urls :router
|
102
77
|
|
78
|
+
##
|
103
79
|
# Instance method for url generation like:
|
104
80
|
#
|
105
81
|
# url(:show, :id => 1)
|
@@ -118,6 +94,7 @@ module Padrino
|
|
118
94
|
end
|
119
95
|
alias :url_for :url
|
120
96
|
|
97
|
+
##
|
121
98
|
# With this method we can use layout like rails do or if a block given like sinatra
|
122
99
|
# By default we look in your/app/views/layouts/application.(haml|erb|etc)
|
123
100
|
#
|
@@ -126,26 +103,33 @@ module Padrino
|
|
126
103
|
# layout :custom
|
127
104
|
#
|
128
105
|
# Padrino look for your/app/views/layouts/custom.(haml|erb|etc)
|
106
|
+
#
|
129
107
|
def layout(name=:layout, &block)
|
130
108
|
return super if block_given?
|
131
109
|
@_layout = name
|
132
110
|
end
|
133
111
|
|
112
|
+
##
|
134
113
|
# Reloads the application files from all defined load paths
|
114
|
+
#
|
135
115
|
def reload!
|
136
116
|
reset_routes! # remove all existing user-defined application routes
|
137
117
|
Padrino.load_dependency(self.app_file) # reload the app file
|
138
118
|
load_paths.each { |path| Padrino.load_dependencies(File.join(self.root, path)) } # reload dependencies
|
139
119
|
end
|
140
120
|
|
121
|
+
##
|
141
122
|
# Resets application routes to only routes not defined by the user
|
123
|
+
#
|
142
124
|
def reset_routes!
|
143
125
|
router.reset!
|
144
126
|
default_routes!
|
145
127
|
end
|
146
128
|
|
129
|
+
##
|
147
130
|
# Setup the application by registering initializers, load paths and logger
|
148
131
|
# Invoked automatically when an application is first instantiated
|
132
|
+
#
|
149
133
|
def setup_application!
|
150
134
|
return if @_configured
|
151
135
|
self.register_framework_extensions
|
@@ -159,7 +143,9 @@ module Padrino
|
|
159
143
|
end
|
160
144
|
|
161
145
|
protected
|
146
|
+
##
|
162
147
|
# Defines default settings for Padrino application
|
148
|
+
#
|
163
149
|
def default_configuration!
|
164
150
|
# Overwriting Sinatra defaults
|
165
151
|
set :app_file, caller_files.first || $0 # Assume app file is first caller
|
@@ -183,6 +169,9 @@ module Padrino
|
|
183
169
|
set :padrino_helpers, defined?(Padrino::Helpers)
|
184
170
|
end
|
185
171
|
|
172
|
+
##
|
173
|
+
# We need to add almost __sinatra__ images.
|
174
|
+
#
|
186
175
|
def default_routes!
|
187
176
|
# images resources
|
188
177
|
get "/__sinatra__/:image.png" do
|
@@ -191,7 +180,9 @@ module Padrino
|
|
191
180
|
end
|
192
181
|
end
|
193
182
|
|
183
|
+
##
|
194
184
|
# This filter it's used for know the format of the request, and automatically set the content type.
|
185
|
+
#
|
195
186
|
def default_filters!
|
196
187
|
before do
|
197
188
|
unless options.static? && options.public? && (request.get? || request.head?) && static_file?(request.path_info)
|
@@ -202,49 +193,62 @@ module Padrino
|
|
202
193
|
end
|
203
194
|
end
|
204
195
|
|
196
|
+
##
|
205
197
|
# Calculates any required paths after app_file and root have been properly configured
|
206
198
|
# Executes as part of the setup_application! method
|
199
|
+
#
|
207
200
|
def calculate_paths
|
208
201
|
raise ApplicationSetupError.new("Please define 'app_file' option for #{self.name} app!") unless self.app_file
|
209
202
|
set :views, find_view_path if find_view_path
|
210
203
|
set :images_path, File.join(self.public, "/images") unless self.respond_to?(:images_path)
|
211
204
|
end
|
212
205
|
|
206
|
+
##
|
213
207
|
# Requires the middleware and initializer modules to configure components
|
208
|
+
#
|
214
209
|
def register_initializers
|
215
210
|
use Padrino::RackLogger
|
216
211
|
use Padrino::Reloader if reload?
|
217
212
|
use Rack::Flash if flash?
|
218
|
-
register DatabaseSetup if defined?(DatabaseSetup)
|
219
213
|
@initializer_path ||= Padrino.root + '/config/initializers/*.rb'
|
220
214
|
Dir[@initializer_path].each { |file| register_initializer(file) }
|
221
215
|
end
|
222
216
|
|
217
|
+
##
|
223
218
|
# Registers all desired padrino extension helpers
|
219
|
+
#
|
224
220
|
def register_framework_extensions
|
225
221
|
register Padrino::Mailer if padrino_mailer?
|
226
222
|
register Padrino::Helpers if padrino_helpers?
|
227
223
|
register Padrino::AccessControl if authentication?
|
228
224
|
end
|
229
225
|
|
226
|
+
##
|
230
227
|
# Returns the load_paths for the application (relative to the application root)
|
228
|
+
#
|
231
229
|
def load_paths
|
232
230
|
@load_paths ||= ["urls.rb", "config/urls.rb", "mailers/*.rb", "controllers/**/*.rb", "helpers/*.rb"]
|
233
231
|
end
|
234
232
|
|
233
|
+
##
|
235
234
|
# Requires all files within the application load paths
|
235
|
+
#
|
236
236
|
def require_load_paths
|
237
237
|
load_paths.each { |path| Padrino.require_dependencies(File.join(self.root, path)) }
|
238
238
|
end
|
239
239
|
|
240
|
+
##
|
240
241
|
# Returns the path to the views directory from root by returning the first that is found
|
242
|
+
#
|
241
243
|
def find_view_path
|
242
244
|
@view_paths = ["views"].collect { |path| File.join(self.root, path) }
|
243
245
|
@view_paths.find { |path| Dir[File.join(path, '/**/*')].any? }
|
244
246
|
end
|
245
247
|
|
248
|
+
##
|
246
249
|
# Registers an initializer with the application
|
247
250
|
# register_initializer('/path/to/initializer')
|
251
|
+
#
|
248
252
|
def register_initializer(file_path)
|
249
253
|
Padrino.require_dependencies(file_path)
|
250
254
|
file_class = File.basename(file_path, '.rb').camelize
|
@@ -255,6 +259,7 @@ module Padrino
|
|
255
259
|
end
|
256
260
|
|
257
261
|
private
|
262
|
+
##
|
258
263
|
# Rewrite default because now routes can be:
|
259
264
|
#
|
260
265
|
# get :index # => "/"
|
@@ -337,8 +342,8 @@ module Padrino
|
|
337
342
|
host_name(options.delete(:host)) if options.key?(:host)
|
338
343
|
|
339
344
|
# Sinatra defaults
|
340
|
-
define_method "
|
341
|
-
unbound_method = instance_method("
|
345
|
+
define_method "#{verb} #{path}", &block
|
346
|
+
unbound_method = instance_method("#{verb} #{path}")
|
342
347
|
block =
|
343
348
|
if block.arity != 0
|
344
349
|
lambda { unbound_method.bind(self).call(*@block_params) }
|
@@ -352,24 +357,67 @@ module Padrino
|
|
352
357
|
route.name(name) if name
|
353
358
|
route
|
354
359
|
end
|
360
|
+
end # self
|
355
361
|
|
362
|
+
##
|
363
|
+
# Return the request format, this is useful when we need to respond to a given content_type like:
|
364
|
+
#
|
365
|
+
# get :index, :respond_to => :any do
|
366
|
+
# case content_type
|
367
|
+
# when :js then ...
|
368
|
+
# when :json then ...
|
369
|
+
# when :html then ...
|
370
|
+
# end
|
371
|
+
# end
|
372
|
+
#
|
373
|
+
def content_type(type=nil, params={})
|
374
|
+
type.nil? ? @_content_type : super(type, params)
|
356
375
|
end
|
357
376
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
377
|
+
##
|
378
|
+
# Instance method for url generation like:
|
379
|
+
#
|
380
|
+
# url(:show, :id => 1)
|
381
|
+
# url(:show, :name => :test)
|
382
|
+
# url("/show/:id/:name", :id => 1, :name => foo)
|
383
|
+
#
|
384
|
+
def url(name, *params)
|
385
|
+
self.class.url(name, *params)
|
386
|
+
end
|
387
|
+
alias :url_for :url
|
364
388
|
|
365
|
-
|
366
|
-
|
367
|
-
|
389
|
+
##
|
390
|
+
# This is mostly just a helper so request.path_info isn't changed when
|
391
|
+
# serving files from the public directory
|
392
|
+
#
|
393
|
+
def static_file?(path_info)
|
394
|
+
[options.public, Padrino.root("shared/public")].find do |folder|
|
395
|
+
next if folder.nil?
|
396
|
+
public_dir = File.expand_path(folder)
|
397
|
+
|
398
|
+
path = File.expand_path(public_dir + unescape(path_info))
|
399
|
+
next if path[0, public_dir.length] != public_dir
|
400
|
+
next unless File.file?(path)
|
401
|
+
return path
|
402
|
+
end
|
403
|
+
end
|
368
404
|
|
369
|
-
|
405
|
+
private
|
406
|
+
|
407
|
+
##
|
408
|
+
# Method for deliver static files, Sinatra 0.10.x or 1.0.x have this method
|
409
|
+
# but for now we use this (because we need a compatibility with 0.9.x) and also
|
410
|
+
# because we just have +static_file?+ method.
|
411
|
+
#
|
412
|
+
def static!
|
413
|
+
if path = static_file?(request.path_info)
|
414
|
+
send_file(path, :disposition => nil)
|
415
|
+
end
|
370
416
|
end
|
371
417
|
|
418
|
+
##
|
372
419
|
# Compatibility with usher
|
420
|
+
#
|
373
421
|
def route!(base=self.class, pass_block=nil)
|
374
422
|
# TODO: remove this when sinatra 1.0 will be released
|
375
423
|
if Sinatra::VERSION =~ /^0\.9/
|
@@ -399,10 +447,13 @@ module Padrino
|
|
399
447
|
end
|
400
448
|
end
|
401
449
|
|
402
|
-
|
450
|
+
##
|
451
|
+
# When we set :auto_locale, true then if we use param locale like:
|
452
|
+
#
|
453
|
+
# get "/:locale/some/foo" do; ...; end
|
454
|
+
#
|
455
|
+
# we automatically set the I18n locale to params[:locale]
|
403
456
|
#
|
404
|
-
# * if we pass "/:locale/some/foo" we automatically set teh I18n locale to params[:locale]
|
405
|
-
# * if params[:locale] is empty we use the first HTTP_ACCEPT_LANGUAGE
|
406
457
|
def route_eval(&block)
|
407
458
|
if options.auto_locale
|
408
459
|
if params[:locale]
|
@@ -412,14 +463,18 @@ module Padrino
|
|
412
463
|
super
|
413
464
|
end
|
414
465
|
|
415
|
-
|
466
|
+
##
|
467
|
+
# Hijacking the sinatra render for do three thing:
|
416
468
|
#
|
417
469
|
# * Use layout like rails do
|
418
|
-
# * Use render 'path/to/my/template'
|
470
|
+
# * Use render 'path/to/my/template' (without symbols)
|
471
|
+
# * Use render 'path/to/my/template' (with auto enegine lookup)
|
419
472
|
#
|
420
473
|
def render(engine, data=nil, options={}, locals={}, &block)
|
421
474
|
# TODO: remove these @template_cache.respond_to?(:clear) when sinatra 1.0 will be released
|
422
475
|
@template_cache.clear if Padrino.env != :production && @template_cache && @template_cache.respond_to?(:clear)
|
476
|
+
# If engine is an hash we convert to json
|
477
|
+
return engine.to_json if engine.is_a?(Hash)
|
423
478
|
# If an engine is a string probably is a path so we try to resolve them
|
424
479
|
if data.nil?
|
425
480
|
data = engine.to_sym
|
@@ -436,14 +491,15 @@ module Padrino
|
|
436
491
|
super
|
437
492
|
end
|
438
493
|
|
494
|
+
##
|
439
495
|
# Returns the template engine (i.e haml) to use for a given template_path
|
440
496
|
# resolve_template_engine('users/new') => :haml
|
497
|
+
#
|
441
498
|
def resolve_template_engine(template_path)
|
442
499
|
resolved_template_path = File.join(self.options.views, template_path.to_s + ".*")
|
443
500
|
template_file = Dir[resolved_template_path].first
|
444
501
|
raise "Template path '#{template_path}' could not be located in views!" unless template_file
|
445
502
|
template_engine = File.extname(template_file)[1..-1].to_sym
|
446
503
|
end
|
447
|
-
end
|
448
|
-
|
449
|
-
end
|
504
|
+
end # Application
|
505
|
+
end # Padrino
|