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/lib/padrino-core/caller.rb
CHANGED
@@ -19,16 +19,22 @@ module Padrino
|
|
19
19
|
%r{/thor}, # thor require hacks
|
20
20
|
] unless defined?(PADRINO_IGNORE_CALLERS)
|
21
21
|
|
22
|
-
|
22
|
+
##
|
23
|
+
# Add rubinius (and hopefully other VM impls) ignore patterns ...
|
24
|
+
#
|
23
25
|
PADRINO_IGNORE_CALLERS.concat(RUBY_IGNORE_CALLERS) if defined?(RUBY_IGNORE_CALLERS)
|
24
26
|
|
27
|
+
##
|
25
28
|
# Returns the filename for the file that is the direct caller (first caller)
|
29
|
+
#
|
26
30
|
def self.first_caller
|
27
31
|
caller_files.first
|
28
32
|
end
|
29
33
|
|
34
|
+
##
|
30
35
|
# Like Kernel#caller but excluding certain magic entries and without
|
31
36
|
# line / method information; the resulting array contains filenames only.
|
37
|
+
#
|
32
38
|
def self.caller_files
|
33
39
|
caller_locations.map { |file,line| file }
|
34
40
|
end
|
@@ -38,4 +44,4 @@ module Padrino
|
|
38
44
|
map { |line| line.split(/:(?=\d|in )/)[0,2] }.
|
39
45
|
reject { |file,line| PADRINO_IGNORE_CALLERS.any? { |pattern| file =~ pattern } }
|
40
46
|
end
|
41
|
-
end
|
47
|
+
end # Padrino
|
data/lib/padrino-core/cli.rb
CHANGED
@@ -41,6 +41,7 @@ module Padrino
|
|
41
41
|
method_option :environment, :type => :string, :aliases => "-e", :required => true, :default => :development
|
42
42
|
method_option :task_list, :type => :string, :aliases => "-T" # Only for accept rake
|
43
43
|
def rake(task="")
|
44
|
+
ENV['PADRINO_LOG_LEVEL'] ||= "test"
|
44
45
|
boot = check_boot
|
45
46
|
return unless boot
|
46
47
|
require 'rake'
|
@@ -95,6 +96,6 @@ module Padrino
|
|
95
96
|
"cannot be accessed by the current user!"
|
96
97
|
end
|
97
98
|
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
99
|
+
end # Base
|
100
|
+
end # Cli
|
101
|
+
end # Padrino
|
data/lib/padrino-core/loader.rb
CHANGED
@@ -1,54 +1,97 @@
|
|
1
1
|
module Padrino
|
2
2
|
class << self
|
3
|
+
##
|
3
4
|
# Requires necessary dependencies as well as application files from root lib and models
|
5
|
+
#
|
4
6
|
def load!
|
5
7
|
return false if loaded?
|
6
8
|
@_called_from = first_caller
|
7
|
-
|
8
|
-
|
9
|
+
set_encoding
|
10
|
+
set_load_paths(*load_paths) # we set the padrino load paths
|
11
|
+
require_dependencies("#{root}/lib/**/*.rb", "#{root}/shared/lib/**/*.rb") # load root libs
|
12
|
+
require_dependencies("#{root}/models/**/*.rb", "#{root}/shared/models/**/*.rb") # load root models
|
9
13
|
require_dependencies("#{root}/config/database.rb", "#{root}/config/apps.rb") # load configuration
|
10
14
|
Stat.reload! # We need to fill our Stat::CACHE but we do that only for development
|
11
15
|
Thread.current[:padrino_loaded] = true
|
12
16
|
end
|
13
17
|
|
18
|
+
##
|
14
19
|
# Method for reloading required applications and their files
|
20
|
+
#
|
15
21
|
def reload!
|
16
22
|
return unless Stat.changed?
|
17
23
|
Stat.reload! # detects the modified files
|
18
24
|
Padrino.mounted_apps.each { |m| m.app_object.reload! } # finally we reload all files for each app
|
19
25
|
end
|
20
26
|
|
27
|
+
##
|
21
28
|
# This adds the ablity to instantiate Padrino.load! after Padrino::Application definition.
|
29
|
+
#
|
22
30
|
def called_from
|
23
31
|
@_called_from || first_caller
|
24
32
|
end
|
25
33
|
|
34
|
+
##
|
26
35
|
# Return true if Padrino was loaded with Padrino.load!
|
36
|
+
#
|
27
37
|
def loaded?
|
28
38
|
Thread.current[:padrino_loaded]
|
29
39
|
end
|
30
40
|
|
41
|
+
##
|
31
42
|
# Attempts to require all dependency libs that we need.
|
32
43
|
# If you use this method we can perform correctly a Padrino.reload!
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
44
|
+
# Another good thing that this method are dependency check, for example:
|
45
|
+
#
|
46
|
+
# models
|
47
|
+
# \-- a.rb => require something of b.rb
|
48
|
+
# \-- b.rb
|
49
|
+
#
|
50
|
+
# In the example above if we do:
|
51
|
+
#
|
52
|
+
# Dir["/models/*.rb"].each { |r| require r }
|
53
|
+
#
|
54
|
+
# we get an error, because we try to require first a.rb that need +something+ of b.rb.
|
55
|
+
#
|
56
|
+
# With +require_dependencies+ we don't have this problem.
|
57
|
+
#
|
37
58
|
# Example:
|
38
59
|
# # For require all our app libs we need to do:
|
39
60
|
# require_dependencies("#{Padrino.root}/lib/**/*.rb")
|
61
|
+
#
|
40
62
|
def require_dependencies(*paths)
|
41
|
-
|
42
|
-
|
63
|
+
# Extract all files to load
|
64
|
+
files = paths.map { |path| Dir[path] }.flatten
|
65
|
+
|
66
|
+
while files.present?
|
67
|
+
# We need a size to make sure things are loading
|
68
|
+
size_at_start = files.size
|
69
|
+
|
70
|
+
# List of errors and failed files
|
71
|
+
errors, failed = [], []
|
72
|
+
|
73
|
+
# Now we try to require our dependencies
|
74
|
+
files.each do |file|
|
75
|
+
begin
|
76
|
+
require file
|
77
|
+
files.delete(file)
|
78
|
+
rescue Exception => e
|
79
|
+
errors << e
|
80
|
+
failed << files
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Stop processing if nothing loads or if everything has loaded
|
85
|
+
raise errors.last if files.size == size_at_start && files.present?
|
86
|
+
break if files.empty?
|
43
87
|
end
|
44
88
|
end
|
45
89
|
alias :require_dependency :require_dependencies
|
46
90
|
|
91
|
+
##
|
47
92
|
# Attempts to load all dependency libs that we need.
|
48
93
|
# If you use this method we can perform correctly a Padrino.reload!
|
49
94
|
#
|
50
|
-
# ==== Parameters
|
51
|
-
# paths:: Path where is necessary to load a dependency
|
52
95
|
def load_dependencies(*paths)
|
53
96
|
paths.each do |path|
|
54
97
|
Dir[path].each { |file| load(file) }
|
@@ -56,5 +99,12 @@ module Padrino
|
|
56
99
|
end
|
57
100
|
alias :load_dependency :load_dependencies
|
58
101
|
|
59
|
-
|
60
|
-
|
102
|
+
##
|
103
|
+
# Concat to $LOAD_PATH the given paths
|
104
|
+
#
|
105
|
+
def set_load_paths(*paths)
|
106
|
+
$:.concat(paths)
|
107
|
+
$:.uniq!
|
108
|
+
end
|
109
|
+
end # self
|
110
|
+
end # Padrino
|
data/lib/padrino-core/logger.rb
CHANGED
@@ -1,13 +1,20 @@
|
|
1
|
+
# Defines our PADRINO_LOG_LEVEL
|
2
|
+
PADRINO_LOG_LEVEL = ENV['PADRINO_LOG_LEVEL'] unless defined?(PADRINO_LOG_LEVEL)
|
3
|
+
|
1
4
|
module Padrino
|
2
5
|
|
6
|
+
##
|
7
|
+
# Returns the padrino logger
|
8
|
+
#
|
9
|
+
# Examples:
|
10
|
+
#
|
11
|
+
# logger.debug "foo"
|
12
|
+
# logger.warn "bar"
|
13
|
+
#
|
3
14
|
def self.logger
|
4
15
|
Thread.current[:padrino_logger] ||= Padrino::Logger.setup!
|
5
16
|
end
|
6
17
|
|
7
|
-
def self.logger_env=(env)
|
8
|
-
Thread.current[:padrino_logger] ||= Padrino::Logger.setup!(env)
|
9
|
-
end
|
10
|
-
|
11
18
|
class Logger
|
12
19
|
|
13
20
|
attr_accessor :level
|
@@ -16,7 +23,7 @@ module Padrino
|
|
16
23
|
attr_reader :log
|
17
24
|
attr_reader :init_args
|
18
25
|
|
19
|
-
|
26
|
+
##
|
20
27
|
# Ruby (standard) logger levels:
|
21
28
|
#
|
22
29
|
# :fatal:: An unhandleable error that results in a program crash
|
@@ -34,7 +41,7 @@ module Padrino
|
|
34
41
|
|
35
42
|
@@mutex = {}
|
36
43
|
|
37
|
-
|
44
|
+
##
|
38
45
|
# Configuration for a given environment, possible options are:
|
39
46
|
#
|
40
47
|
# :log_level:: Once of [:fatal, :error, :warn, :info, :debug]
|
@@ -61,16 +68,19 @@ module Padrino
|
|
61
68
|
# :production => { :log_level => :warn, :stream => :to_file }
|
62
69
|
# :development => { :log_level => :debug, :stream => :stdout }
|
63
70
|
# :test => { :log_level => :fatal, :stream => :null }
|
71
|
+
#
|
64
72
|
Config = {
|
65
|
-
:production => { :log_level => :warn,
|
73
|
+
:production => { :log_level => :warn, :stream => :to_file },
|
66
74
|
:development => { :log_level => :debug, :stream => :stdout },
|
67
75
|
:test => { :log_level => :debug, :stream => :null }
|
68
76
|
} unless const_defined?(:Config)
|
69
77
|
|
70
|
-
|
78
|
+
##
|
71
79
|
# Setup a new logger
|
72
|
-
|
73
|
-
|
80
|
+
#
|
81
|
+
def self.setup!
|
82
|
+
config_level = (PADRINO_LOG_LEVEL || Padrino.env || :test).to_sym # need this for PADRINO_LOG_LEVEL
|
83
|
+
config = Config[config_level]
|
74
84
|
stream = case config[:stream]
|
75
85
|
when :to_file
|
76
86
|
FileUtils.mkdir_p(Padrino.root("log")) unless File.exists?(Padrino.root("log"))
|
@@ -85,6 +95,7 @@ module Padrino
|
|
85
95
|
|
86
96
|
public
|
87
97
|
|
98
|
+
##
|
88
99
|
# To initialize the logger you create a new object, proxies to set_log.
|
89
100
|
#
|
90
101
|
# ==== Options can be:
|
@@ -109,7 +120,9 @@ module Padrino
|
|
109
120
|
@format_message = options[:format_message] || "%-5s - [%s] \"%s\""
|
110
121
|
end
|
111
122
|
|
123
|
+
##
|
112
124
|
# Flush the entire buffer to the log object.
|
125
|
+
#
|
113
126
|
def flush
|
114
127
|
return unless @buffer.size > 0
|
115
128
|
@mutex.synchronize do
|
@@ -117,21 +130,19 @@ module Padrino
|
|
117
130
|
end
|
118
131
|
end
|
119
132
|
|
133
|
+
##
|
120
134
|
# Close and remove the current log object.
|
135
|
+
#
|
121
136
|
def close
|
122
137
|
flush
|
123
138
|
@log.close if @log.respond_to?(:close) && !@log.tty?
|
124
139
|
@log = nil
|
125
140
|
end
|
126
141
|
|
142
|
+
##
|
127
143
|
# Appends a message to the log. The methods yield to an optional block and
|
128
144
|
# the output of this block will be appended to the message.
|
129
145
|
#
|
130
|
-
# ==== Parameters
|
131
|
-
# message:: The message to be logged. Defaults to nil.
|
132
|
-
#
|
133
|
-
# ==== Returns
|
134
|
-
# message:: The resulting message added to the log file.
|
135
146
|
def push(message = nil, level = nil)
|
136
147
|
self << @format_message % [level.to_s.upcase, Time.now.strftime(@format_datetime), message.to_s]
|
137
148
|
end
|
@@ -143,7 +154,9 @@ module Padrino
|
|
143
154
|
message
|
144
155
|
end
|
145
156
|
|
157
|
+
##
|
146
158
|
# Generate the logging methods for Padrino.logger for each log level.
|
159
|
+
#
|
147
160
|
Levels.each_pair do |name, number|
|
148
161
|
class_eval <<-LEVELMETHODS, __FILE__, __LINE__
|
149
162
|
|
@@ -191,13 +204,17 @@ module Padrino
|
|
191
204
|
|
192
205
|
end
|
193
206
|
|
207
|
+
##
|
194
208
|
# RackLogger forwards every request to an +app+ given, and
|
195
209
|
# logs a line in the Apache common log format to the +logger+, or
|
196
210
|
# rack.errors by default.
|
211
|
+
#
|
197
212
|
class RackLogger
|
213
|
+
##
|
198
214
|
# Common Log Format: http://httpd.apache.org/docs/1.3/logs.html#common
|
199
215
|
# "lilith.local - - GET / HTTP/1.1 500 -"
|
200
216
|
# %{%s - %s %s %s%s %s - %d %s %0.4f}
|
217
|
+
#
|
201
218
|
FORMAT = %{%s - %s %s %s%s %s - %d %s %0.4f}
|
202
219
|
|
203
220
|
def initialize(app)
|
@@ -237,13 +254,15 @@ module Padrino
|
|
237
254
|
end
|
238
255
|
'-'
|
239
256
|
end
|
240
|
-
end
|
241
|
-
end
|
257
|
+
end # Logger
|
258
|
+
end # Padrino
|
242
259
|
|
243
260
|
module Kernel
|
244
261
|
|
262
|
+
##
|
245
263
|
# Define a logger available every where in our app
|
264
|
+
#
|
246
265
|
def logger
|
247
266
|
Padrino.logger
|
248
267
|
end
|
249
|
-
end
|
268
|
+
end # Kernel
|
data/lib/padrino-core/mounter.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
module Padrino
|
2
|
+
##
|
2
3
|
# Represents a particular mounted padrino application
|
3
4
|
# Stores the name of the application (app folder name) and url mount path
|
4
|
-
#
|
5
|
-
#
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
#
|
8
|
+
# Mounter.new("blog_app", :app_class => "Blog").to("/blog")
|
9
|
+
# Mounter.new("blog_app", :app_file => "/path/to/blog/app.rb").to("/blog")
|
10
|
+
#
|
6
11
|
class Mounter
|
7
12
|
attr_accessor :name, :uri_root, :app_file, :app_class, :app_root, :app_obj
|
8
13
|
|
@@ -14,17 +19,24 @@ module Padrino
|
|
14
19
|
@app_obj = self.app_object
|
15
20
|
end
|
16
21
|
|
22
|
+
##
|
17
23
|
# Registers the mounted application onto Padrino
|
18
|
-
#
|
24
|
+
#
|
25
|
+
# Example:
|
26
|
+
# Mounter.new("blog_app").to("/blog")
|
27
|
+
#
|
19
28
|
def to(mount_url)
|
20
29
|
@uri_root = mount_url
|
21
30
|
Padrino.insert_mounted_app(self)
|
22
31
|
self
|
23
32
|
end
|
24
33
|
|
34
|
+
##
|
25
35
|
# Maps Padrino application onto a Rack::Builder
|
26
36
|
# For use in constructing a Rack application
|
27
|
-
#
|
37
|
+
#
|
38
|
+
# @app.map_onto(@builder)
|
39
|
+
#
|
28
40
|
def map_onto(builder)
|
29
41
|
app_data, app_obj = self, @app_obj
|
30
42
|
builder.map self.uri_root do
|
@@ -38,19 +50,25 @@ module Padrino
|
|
38
50
|
end
|
39
51
|
end
|
40
52
|
|
53
|
+
##
|
41
54
|
# Return the class for the app
|
55
|
+
#
|
42
56
|
def app_object
|
43
57
|
app_class.constantize rescue Padrino.require_dependency(app_file)
|
44
58
|
app_class.constantize
|
45
59
|
end
|
46
60
|
|
61
|
+
##
|
47
62
|
# Returns the determined location of the mounted application main file
|
63
|
+
#
|
48
64
|
def locate_app_file
|
49
65
|
callers_are_identical = File.identical?(Padrino.first_caller.to_s, Padrino.called_from.to_s)
|
50
66
|
callers_are_identical ? Padrino.first_caller : Padrino.mounted_root(name, "app.rb")
|
51
67
|
end
|
52
68
|
|
69
|
+
##
|
53
70
|
# Makes two Mounters equal if they have the same name and uri_root
|
71
|
+
#
|
54
72
|
def ==(other)
|
55
73
|
other.is_a?(Mounter) && self.name == other.name && self.uri_root == other.uri_root
|
56
74
|
end
|
@@ -59,25 +77,36 @@ module Padrino
|
|
59
77
|
class << self
|
60
78
|
attr_writer :mounted_root # Set root directory where padrino searches mounted apps
|
61
79
|
|
80
|
+
##
|
62
81
|
# Returns the root to the mounted apps base directory
|
82
|
+
#
|
63
83
|
def mounted_root(*args)
|
64
84
|
Padrino.root(@mounted_root ||= "", *args)
|
65
85
|
end
|
66
86
|
|
87
|
+
##
|
67
88
|
# Returns the mounted padrino applications (MountedApp objects)
|
89
|
+
#
|
68
90
|
def mounted_apps
|
69
91
|
@mounted_apps ||= []
|
70
92
|
end
|
71
93
|
|
94
|
+
##
|
72
95
|
# Inserts a Mounter object into the mounted applications (avoids duplicates)
|
96
|
+
#
|
73
97
|
def insert_mounted_app(mounter)
|
74
98
|
return false if Padrino.mounted_apps.include?(mounter)
|
75
99
|
Padrino.mounted_apps << mounter
|
76
100
|
end
|
77
101
|
|
102
|
+
##
|
78
103
|
# Mounts the core application onto Padrino project with given app settings (file, class, root)
|
79
|
-
#
|
80
|
-
#
|
104
|
+
#
|
105
|
+
# Examples:
|
106
|
+
#
|
107
|
+
# Padrino.mount_core("Blog")
|
108
|
+
# Padrino.mount_core(:app_file => "/path/to/file", :app_class => "Blog")
|
109
|
+
#
|
81
110
|
def mount_core(*args)
|
82
111
|
options = args.extract_options!
|
83
112
|
app_class = args.size > 0 ? args.first.to_s.camelize : nil
|
@@ -85,10 +114,13 @@ module Padrino
|
|
85
114
|
mount("core", options).to("/")
|
86
115
|
end
|
87
116
|
|
117
|
+
##
|
88
118
|
# Mounts a new sub-application onto Padrino project
|
89
|
-
#
|
119
|
+
#
|
120
|
+
# Padrino.mount("blog_app").to("/blog")
|
121
|
+
#
|
90
122
|
def mount(name, options={})
|
91
123
|
Mounter.new(name, options)
|
92
124
|
end
|
93
|
-
end
|
94
|
-
end
|
125
|
+
end # Mounter
|
126
|
+
end # Padrino
|