padrino-core 0.9.28 → 0.9.29
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/padrino-core.rb +3 -14
- data/lib/padrino-core/application.rb +45 -38
- data/lib/padrino-core/application/rendering.rb +16 -9
- data/lib/padrino-core/application/routing.rb +41 -57
- data/lib/padrino-core/cli/adapter.rb +9 -32
- data/lib/padrino-core/cli/base.rb +13 -14
- data/lib/padrino-core/cli/rake.rb +14 -69
- data/lib/padrino-core/cli/rake_tasks.rb +59 -0
- data/lib/padrino-core/loader.rb +50 -41
- data/lib/padrino-core/logger.rb +17 -7
- data/lib/padrino-core/mounter.rb +1 -0
- data/lib/padrino-core/reloader.rb +170 -210
- data/lib/padrino-core/server.rb +41 -45
- data/lib/padrino-core/support_lite.rb +24 -76
- data/lib/padrino-core/version.rb +1 -1
- data/padrino-core.gemspec +6 -2
- data/test/fixtures/apps/simple.rb +1 -1
- data/test/test_application.rb +1 -1
- data/test/test_core.rb +18 -4
- data/test/test_mounter.rb +1 -1
- data/test/test_reloader_complex.rb +2 -2
- data/test/test_reloader_simple.rb +2 -2
- data/test/test_rendering.rb +30 -0
- data/test/test_router.rb +4 -2
- data/test/test_routing.rb +9 -0
- metadata +5 -58
- data/test/test_server.rb +0 -37
data/lib/padrino-core/server.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Padrino
|
2
|
-
|
3
2
|
##
|
4
3
|
# Run the Padrino apps as a self-hosted server using:
|
5
4
|
# thin, mongrel, webrick in that order.
|
@@ -11,64 +10,61 @@ module Padrino
|
|
11
10
|
#
|
12
11
|
def self.run!(options={})
|
13
12
|
Padrino.load!
|
14
|
-
Server.
|
13
|
+
Server.start(Padrino.application, options)
|
15
14
|
end
|
16
15
|
|
17
16
|
##
|
18
17
|
# This module build a Padrino server
|
19
18
|
#
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
Handlers = %w[thin mongrel webrick] unless const_defined?(:Handlers)
|
19
|
+
class Server < Rack::Server
|
20
|
+
# Server Handlers
|
21
|
+
Handlers = [:thin, :mongrel, :webrick]
|
25
22
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
23
|
+
def self.start(app, opts={})
|
24
|
+
options = {}.merge(opts) # We use a standard hash instead of Thor::CoreExt::HashWithIndifferentAccess
|
25
|
+
options.symbolize_keys!
|
26
|
+
options[:Host] = options.delete(:host)
|
27
|
+
options[:Port] = options.delete(:port)
|
28
|
+
options[:AccessLog] = []
|
29
|
+
if options[:daemonize]
|
30
|
+
options[:pid] = options[:pid].blank? ? File.expand_path('tmp/pids/server.pid') : opts[:pid]
|
31
|
+
FileUtils.mkdir_p(File.dirname(options[:pid]))
|
32
|
+
end
|
33
|
+
options[:server] = detect_rack_handler if options[:server].blank?
|
34
|
+
new(options, app).start
|
35
|
+
end
|
31
36
|
|
32
|
-
|
37
|
+
def initialize(options, app)
|
38
|
+
@options, @app = options, app
|
39
|
+
end
|
33
40
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
41
|
+
def start
|
42
|
+
puts "=> Padrino/#{Padrino.version} has taken the stage #{Padrino.env} at http://#{options[:Host]}:#{options[:Port]}"
|
43
|
+
[:INT, :TERM].each { |sig| trap(sig) { exit } }
|
44
|
+
super
|
45
|
+
ensure
|
46
|
+
puts "<= Padrino has ended his set (crowd applauds)" unless options[:daemonize]
|
47
|
+
end
|
40
48
|
|
41
|
-
|
49
|
+
def app
|
50
|
+
@app
|
51
|
+
end
|
52
|
+
alias :wrapped_app :app
|
42
53
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
server.respond_to?(:stop!) ? server.stop! : server.stop
|
47
|
-
puts "<= Padrino has ended his set (crowd applauds)"
|
48
|
-
end
|
49
|
-
end
|
50
|
-
rescue RuntimeError => e
|
51
|
-
if e.message =~ /no acceptor/
|
52
|
-
if port < 1024 && RUBY_PLATFORM !~ /mswin|win|mingw/ && Process.uid != 0
|
53
|
-
puts "=> Only root may open a priviledged port #{port}!"
|
54
|
-
else
|
55
|
-
puts "=> Someone is already performing on port #{port}!"
|
56
|
-
end
|
57
|
-
else
|
58
|
-
raise e
|
59
|
-
end
|
60
|
-
rescue Errno::EADDRINUSE
|
61
|
-
puts "=> Someone is already performing on port #{port}!"
|
62
|
-
end
|
54
|
+
def options
|
55
|
+
@options
|
56
|
+
end
|
63
57
|
|
64
|
-
|
65
|
-
|
58
|
+
private
|
59
|
+
def self.detect_rack_handler
|
60
|
+
Handlers.each do |handler|
|
66
61
|
begin
|
67
|
-
return Rack::Handler.get(
|
68
|
-
rescue
|
62
|
+
return handler if Rack::Handler.get(handler.to_s.downcase)
|
63
|
+
rescue LoadError
|
64
|
+
rescue NameError
|
69
65
|
end
|
70
66
|
end
|
71
|
-
|
67
|
+
fail "Server handler (#{Handlers.join(', ')}) not found."
|
72
68
|
end
|
73
69
|
end # Server
|
74
70
|
end # Padrino
|
@@ -1,95 +1,41 @@
|
|
1
1
|
##
|
2
2
|
# This file loads certain extensions required by Padrino from ActiveSupport.
|
3
3
|
#
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
# 2) Loading custom method extensions or separate gems would conflict with AS when AR or MM has been loaded.
|
8
|
-
# 3) Datamapper 1.0 supports ActiveSupport 3.0 and no longer requires extlib.
|
9
|
-
#
|
10
|
-
|
11
|
-
# ActiveSupport Required Extensions
|
12
|
-
require 'active_support/core_ext/string/conversions' unless String.method_defined?(:to_date)
|
13
|
-
require 'active_support/core_ext/kernel' unless Kernel.method_defined?(:silence_warnings)
|
14
|
-
require 'active_support/core_ext/module' unless Module.method_defined?(:alias_method_chain)
|
4
|
+
require 'active_support/core_ext/string/conversions' unless String.method_defined?(:to_date)
|
5
|
+
require 'active_support/core_ext/kernel' unless Kernel.method_defined?(:silence_warnings)
|
6
|
+
require 'active_support/core_ext/module' unless Module.method_defined?(:alias_method_chain)
|
15
7
|
require 'active_support/core_ext/class/attribute_accessors' unless Class.method_defined?(:cattr_reader)
|
16
|
-
require 'active_support/core_ext/hash/keys'
|
17
|
-
require 'active_support/core_ext/hash/deep_merge'
|
18
|
-
require 'active_support/core_ext/hash/reverse_merge'
|
19
|
-
require 'active_support/core_ext/hash/slice'
|
20
|
-
require 'active_support/core_ext/object/blank'
|
21
|
-
require 'active_support/core_ext/array'
|
22
|
-
require 'active_support/ordered_hash'
|
23
|
-
require 'active_support/inflector'
|
24
|
-
require 'active_support/core_ext/float/rounding'
|
25
|
-
require 'active_support/option_merger'
|
26
|
-
|
27
|
-
# Loads symbol to proc extensions
|
28
|
-
begin
|
29
|
-
require 'active_support/core_ext/symbol'
|
30
|
-
rescue LoadError
|
31
|
-
# AS 3.0 has been removed it because is now available in Ruby > 1.8.7 but we want keep Ruby 1.8.6 support.
|
32
|
-
class Symbol
|
33
|
-
# Turns the symbol into a simple proc, which is especially useful for enumerations like: people.map(&:name)
|
34
|
-
def to_proc
|
35
|
-
Proc.new { |*args| args.shift.__send__(self, *args) }
|
36
|
-
end
|
37
|
-
end unless :to_proc.respond_to?(:to_proc)
|
38
|
-
end
|
39
|
-
|
40
|
-
# On ActiveSupport < 3.0.0 this is called misc
|
41
|
-
begin
|
42
|
-
require 'active_support/core_ext/object/with_options'
|
43
|
-
rescue LoadError
|
44
|
-
require 'active_support/core_ext/object/misc'
|
45
|
-
end unless Object.method_defined?(:with_options)
|
46
|
-
|
47
|
-
if defined?(ActiveSupport::CoreExtensions::Hash) && !Hash.method_defined?(:slice)
|
48
|
-
# This mean that we are using AS 2.3.x
|
49
|
-
class Hash
|
50
|
-
include ActiveSupport::CoreExtensions::Hash::Keys
|
51
|
-
include ActiveSupport::CoreExtensions::Hash::DeepMerge
|
52
|
-
include ActiveSupport::CoreExtensions::Hash::ReverseMerge
|
53
|
-
include ActiveSupport::CoreExtensions::Hash::Slice
|
54
|
-
|
55
|
-
def ordered_collect(&block)
|
56
|
-
keys = self.stringify_keys.keys.sort
|
57
|
-
keys.map { |key| block.call(key, self[key.to_sym]) }
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
8
|
+
require 'active_support/core_ext/hash/keys' unless Hash.method_defined?(:symbolize_keys!)
|
9
|
+
require 'active_support/core_ext/hash/deep_merge' unless Hash.method_defined?(:deep_merge)
|
10
|
+
require 'active_support/core_ext/hash/reverse_merge' unless Hash.method_defined?(:reverse_merge)
|
11
|
+
require 'active_support/core_ext/hash/slice' unless Hash.method_defined?(:slice)
|
12
|
+
require 'active_support/core_ext/object/blank' unless Object.method_defined?(:present?)
|
13
|
+
require 'active_support/core_ext/array' unless Array.method_defined?(:from)
|
14
|
+
require 'active_support/ordered_hash' unless defined?(ActiveSupport::OrderedHash)
|
15
|
+
require 'active_support/inflector' unless String.method_defined?(:humanize)
|
16
|
+
require 'active_support/core_ext/float/rounding' unless Float.method_defined?(:round)
|
17
|
+
require 'active_support/option_merger' unless defined?(ActiveSupport::OptionMerger)
|
18
|
+
require 'active_support/core_ext/object/with_options' unless Object.method_defined?(:with_options)
|
61
19
|
|
62
20
|
##
|
63
21
|
# Used to know if this file has already been required
|
64
22
|
#
|
65
|
-
module SupportLite; end
|
23
|
+
module SupportLite; end
|
66
24
|
|
67
25
|
module ObjectSpace
|
68
26
|
class << self
|
69
27
|
# Returns all the classes in the object space.
|
70
28
|
def classes
|
71
|
-
|
72
|
-
|
73
|
-
|
29
|
+
ObjectSpace.each_object(Module).select do |klass|
|
30
|
+
Class.class_eval { klass } rescue false
|
31
|
+
end
|
74
32
|
end
|
75
33
|
end
|
76
|
-
end
|
77
|
-
|
78
|
-
class Object
|
79
|
-
def full_const_get(name)
|
80
|
-
list = name.split("::")
|
81
|
-
list.shift if list.first.blank?
|
82
|
-
obj = self
|
83
|
-
list.each do |x|
|
84
|
-
# This is required because const_get tries to look for constants in the
|
85
|
-
# ancestor chain, but we only want constants that are HERE
|
86
|
-
obj = obj.const_defined?(x) ? obj.const_get(x) : obj.const_missing(x)
|
87
|
-
end
|
88
|
-
obj
|
89
|
-
end
|
90
|
-
end unless Object.method_defined?(:full_const_get)
|
34
|
+
end
|
91
35
|
|
36
|
+
##
|
92
37
|
# FileSet helper method for iterating and interacting with files inside a directory
|
38
|
+
#
|
93
39
|
class FileSet
|
94
40
|
# Iterates over every file in the glob pattern and yields to a block
|
95
41
|
# Returns the list of files matching the glob pattern
|
@@ -106,10 +52,12 @@ class FileSet
|
|
106
52
|
def self.glob_require(glob_pattern, file_path=nil)
|
107
53
|
self.glob(glob_pattern, file_path) { |f| require f }
|
108
54
|
end
|
109
|
-
end
|
55
|
+
end
|
110
56
|
|
57
|
+
##
|
111
58
|
# YAML Engine Parsing Fix
|
112
59
|
# https://github.com/padrino/padrino-framework/issues/424
|
60
|
+
#
|
113
61
|
require 'yaml' unless defined?(YAML)
|
114
62
|
YAML::ENGINE.yamler = "syck" if defined?(YAML::ENGINE)
|
115
63
|
|
data/lib/padrino-core/version.rb
CHANGED
data/padrino-core.gemspec
CHANGED
@@ -20,10 +20,14 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
s.rdoc_options = ["--charset=UTF-8"]
|
22
22
|
|
23
|
+
|
24
|
+
# TODO remove after a couple versions
|
25
|
+
s.post_install_message = "\e[32m When upgrading, please 'enable :sessions' for each application"
|
26
|
+
s.post_install_message << " as shown here:\e[0m http://bit.ly/kODKMx"
|
27
|
+
|
23
28
|
s.add_dependency("tilt", "~> 1.3.0")
|
24
29
|
s.add_dependency("sinatra", "~> 1.2.6")
|
25
|
-
s.add_dependency("http_router", "~> 0.7.
|
30
|
+
s.add_dependency("http_router", "~> 0.7.8")
|
26
31
|
s.add_dependency("thor", ">=0.14.3")
|
27
32
|
s.add_dependency("activesupport", ">= 3.0.0")
|
28
|
-
s.add_dependency("tzinfo")
|
29
33
|
end
|
data/test/test_application.rb
CHANGED
data/test/test_core.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/helper')
|
2
2
|
|
3
3
|
class TestCore < Test::Unit::TestCase
|
4
|
-
def
|
5
|
-
Padrino.
|
4
|
+
def setup
|
5
|
+
Padrino.clear!
|
6
6
|
end
|
7
7
|
|
8
8
|
context 'for core functionality' do
|
@@ -31,6 +31,9 @@ class TestCore < Test::Unit::TestCase
|
|
31
31
|
Padrino.set_encoding
|
32
32
|
if RUBY_VERSION <'1.9'
|
33
33
|
assert_equal 'UTF8', $KCODE
|
34
|
+
else
|
35
|
+
assert_equal Encoding.default_external, Encoding::UTF_8
|
36
|
+
assert_equal Encoding.default_internal, Encoding::UTF_8
|
34
37
|
end
|
35
38
|
end
|
36
39
|
|
@@ -39,10 +42,18 @@ class TestCore < Test::Unit::TestCase
|
|
39
42
|
end
|
40
43
|
|
41
44
|
should 'raise application error if I instantiate a new padrino application without mounted apps' do
|
42
|
-
Padrino.mounted_apps.clear
|
43
45
|
assert_raise(Padrino::ApplicationLoadError) { Padrino.application.new }
|
44
46
|
end
|
45
47
|
|
48
|
+
should "check before/after padrino load hooks" do
|
49
|
+
Padrino.before_load { @_foo = 1 }
|
50
|
+
Padrino.after_load { @_foo += 1 }
|
51
|
+
Padrino.load!
|
52
|
+
assert_equal 1, Padrino.before_load.size
|
53
|
+
assert_equal 1, Padrino.after_load.size
|
54
|
+
assert_equal 2, @_foo
|
55
|
+
end
|
56
|
+
|
46
57
|
should "add middlewares in front if specified" do
|
47
58
|
test = Class.new {
|
48
59
|
def initialize(app)
|
@@ -56,10 +67,13 @@ class TestCore < Test::Unit::TestCase
|
|
56
67
|
end
|
57
68
|
}
|
58
69
|
|
70
|
+
class Foo < Padrino::Application; end
|
71
|
+
|
59
72
|
Padrino.use(test)
|
73
|
+
Padrino.mount(Foo).to("/")
|
60
74
|
|
61
75
|
res = Rack::MockRequest.new(Padrino.application).get("/")
|
62
76
|
assert_equal "yes", res["Middleware-Called"]
|
63
77
|
end
|
64
78
|
end
|
65
|
-
end
|
79
|
+
end
|
data/test/test_mounter.rb
CHANGED
@@ -6,7 +6,7 @@ class TestComplexReloader < Test::Unit::TestCase
|
|
6
6
|
context 'for complex reload functionality' do
|
7
7
|
|
8
8
|
should 'correctly instantiate Complex(1-2)Demo fixture' do
|
9
|
-
Padrino.
|
9
|
+
Padrino.clear!
|
10
10
|
Padrino.mount("complex_1_demo").to("/complex_1_demo")
|
11
11
|
Padrino.mount("complex_2_demo").to("/complex_2_demo")
|
12
12
|
assert_equal ["/complex_1_demo", "/complex_2_demo"], Padrino.mounted_apps.map(&:uri_root)
|
@@ -36,7 +36,7 @@ class TestComplexReloader < Test::Unit::TestCase
|
|
36
36
|
get "/complex_2_demo/old"
|
37
37
|
assert_equal 200, status
|
38
38
|
|
39
|
-
new_phrase = "The magick number is: #{rand(
|
39
|
+
new_phrase = "The magick number is: #{rand(2**255)}!"
|
40
40
|
buffer = File.read(Complex1Demo.app_file)
|
41
41
|
new_buffer = buffer.gsub(/The magick number is: \d+!/, new_phrase)
|
42
42
|
begin
|
@@ -45,7 +45,7 @@ class TestSimpleReloader < Test::Unit::TestCase
|
|
45
45
|
context 'for simple reload functionality' do
|
46
46
|
|
47
47
|
should 'correctly instantiate SimpleDemo fixture' do
|
48
|
-
Padrino.
|
48
|
+
Padrino.clear!
|
49
49
|
Padrino.mount("simple_demo").to("/")
|
50
50
|
assert_equal ["simple_demo"], Padrino.mounted_apps.map(&:name)
|
51
51
|
assert SimpleDemo.reload?
|
@@ -56,7 +56,7 @@ class TestSimpleReloader < Test::Unit::TestCase
|
|
56
56
|
@app = SimpleDemo
|
57
57
|
get "/"
|
58
58
|
assert ok?
|
59
|
-
new_phrase = "The magick number is: #{rand(
|
59
|
+
new_phrase = "The magick number is: #{rand(2**255)}!"
|
60
60
|
buffer = File.read(SimpleDemo.app_file)
|
61
61
|
new_buffer = buffer.gsub(/The magick number is: \d+!/, new_phrase)
|
62
62
|
File.open(SimpleDemo.app_file, "w") { |f| f.write(new_buffer) }
|
data/test/test_rendering.rb
CHANGED
@@ -204,6 +204,36 @@ class TestRendering < Test::Unit::TestCase
|
|
204
204
|
assert_equal "3", body
|
205
205
|
end
|
206
206
|
|
207
|
+
should "support passing locals into render" do
|
208
|
+
create_layout :application, "layout <%= yield %>"
|
209
|
+
create_view :index, "<%= foo %>"
|
210
|
+
mock_app do
|
211
|
+
get("/") { render "index", { :layout => true }, { :foo => "bar" } }
|
212
|
+
end
|
213
|
+
get "/"
|
214
|
+
assert_equal "layout bar", body
|
215
|
+
end
|
216
|
+
|
217
|
+
should "support passing locals into sinatra render" do
|
218
|
+
create_layout :application, "layout <%= yield %>"
|
219
|
+
create_view :index, "<%= foo %>"
|
220
|
+
mock_app do
|
221
|
+
get("/") { render :erb, :index, { :layout => true }, { :foo => "bar" } }
|
222
|
+
end
|
223
|
+
get "/"
|
224
|
+
assert_equal "layout bar", body
|
225
|
+
end
|
226
|
+
|
227
|
+
should "support passing locals into special nil engine render" do
|
228
|
+
create_layout :application, "layout <%= yield %>"
|
229
|
+
create_view :index, "<%= foo %>"
|
230
|
+
mock_app do
|
231
|
+
get("/") { render nil, :index, { :layout => true }, { :foo => "bar" } }
|
232
|
+
end
|
233
|
+
get "/"
|
234
|
+
assert_equal "layout bar", body
|
235
|
+
end
|
236
|
+
|
207
237
|
should 'be compatible with sinatra views' do
|
208
238
|
with_view :index, "<%= 1+2 %>" do
|
209
239
|
mock_app do
|
data/test/test_router.rb
CHANGED
@@ -3,6 +3,10 @@ require File.expand_path(File.dirname(__FILE__) + '/fixtures/apps/simple')
|
|
3
3
|
|
4
4
|
class TestRouter < Test::Unit::TestCase
|
5
5
|
|
6
|
+
def setup
|
7
|
+
Padrino.clear!
|
8
|
+
end
|
9
|
+
|
6
10
|
should "dispatch paths correctly" do
|
7
11
|
app = lambda { |env|
|
8
12
|
[200, {
|
@@ -104,7 +108,6 @@ class TestRouter < Test::Unit::TestCase
|
|
104
108
|
end
|
105
109
|
|
106
110
|
should "works with padrino core applications" do
|
107
|
-
Padrino.mounted_apps.clear
|
108
111
|
Padrino.mount("simple_demo").host("padrino.org")
|
109
112
|
assert_equal ["simple_demo"], Padrino.mounted_apps.map(&:name)
|
110
113
|
assert_equal ["padrino.org"], Padrino.mounted_apps.map(&:app_host)
|
@@ -120,7 +123,6 @@ class TestRouter < Test::Unit::TestCase
|
|
120
123
|
end
|
121
124
|
|
122
125
|
should "works with padrino applications" do
|
123
|
-
Padrino.mounted_apps.clear
|
124
126
|
Padrino.mount("simple_demo").to("/foo").host(/.*\.padrino.org/)
|
125
127
|
|
126
128
|
res = Rack::MockRequest.new(Padrino.application).get("/")
|