padrino-core 0.12.9 → 0.13.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/bin/padrino +1 -2
- data/lib/padrino-core/application/application_setup.rb +10 -6
- data/lib/padrino-core/application/params_protection.rb +7 -1
- data/lib/padrino-core/application/routing.rb +88 -50
- data/lib/padrino-core/application/show_exceptions.rb +29 -0
- data/lib/padrino-core/application.rb +0 -19
- data/lib/padrino-core/caller.rb +1 -2
- data/lib/padrino-core/cli/base.rb +7 -11
- data/lib/padrino-core/cli/rake_tasks.rb +8 -21
- data/lib/padrino-core/loader.rb +13 -12
- data/lib/padrino-core/logger.rb +4 -32
- data/lib/padrino-core/mounter.rb +62 -21
- data/lib/padrino-core/path_router/compiler.rb +110 -0
- data/lib/padrino-core/path_router/error_handler.rb +8 -0
- data/lib/padrino-core/path_router/matcher.rb +123 -0
- data/lib/padrino-core/path_router/route.rb +169 -0
- data/lib/padrino-core/path_router.rb +119 -0
- data/lib/padrino-core/reloader/rack.rb +1 -4
- data/lib/padrino-core/reloader/storage.rb +3 -31
- data/lib/padrino-core/reloader.rb +12 -17
- data/lib/padrino-core/version.rb +1 -1
- data/lib/padrino-core.rb +0 -2
- data/padrino-core.gemspec +8 -2
- data/test/fixtures/apps/helpers/support.rb +1 -0
- data/test/fixtures/apps/{rack_apps.rb → mountable_apps/rack_apps.rb} +0 -4
- data/test/fixtures/apps/{static.html → mountable_apps/static.html} +0 -0
- data/test/fixtures/apps/precompiled_app.rb +19 -0
- data/test/fixtures/apps/system.rb +0 -2
- data/test/helper.rb +1 -1
- data/test/test_application.rb +18 -6
- data/test/test_csrf_protection.rb +6 -7
- data/test/test_filters.rb +18 -1
- data/test/test_logger.rb +1 -49
- data/test/test_mounter.rb +2 -4
- data/test/test_params_protection.rb +15 -15
- data/test/test_reloader_simple.rb +2 -2
- data/test/test_reloader_system.rb +0 -30
- data/test/test_restful_routing.rb +4 -4
- data/test/test_routing.rb +176 -54
- metadata +109 -49
- data/lib/padrino-core/cli/binstub.rb +0 -27
- data/lib/padrino-core/configuration.rb +0 -40
- data/lib/padrino-core/ext/http_router.rb +0 -201
- data/lib/padrino-core/mounter/application_extension.rb +0 -55
- data/test/fixtures/apps/custom_dependencies/custom_dependencies.rb +0 -11
- data/test/fixtures/apps/custom_dependencies/my_dependencies/my_dependency.rb +0 -0
- data/test/fixtures/apps/stealthy/app.rb +0 -7
- data/test/fixtures/apps/stealthy/helpers/stealthy_class_helpers.rb +0 -13
- data/test/test_configuration.rb +0 -29
- data/test/test_reloader_storage.rb +0 -51
@@ -1,27 +0,0 @@
|
|
1
|
-
module Padrino
|
2
|
-
##
|
3
|
-
# Replaces the current process with it's binstub.
|
4
|
-
#
|
5
|
-
def self.replace_with_binstub(executable)
|
6
|
-
begin
|
7
|
-
return if Bundler.definition.missing_specs.empty?
|
8
|
-
rescue NameError, NoMethodError, Bundler::GemfileNotFound
|
9
|
-
end
|
10
|
-
|
11
|
-
project_root = Dir.pwd
|
12
|
-
until project_root.empty?
|
13
|
-
break if File.file?(File.join(project_root, 'Gemfile'))
|
14
|
-
project_root = project_root.rpartition('/').first
|
15
|
-
end
|
16
|
-
|
17
|
-
if %w(Gemfile .components).all? { |file| File.file?(File.join(project_root, file)) }
|
18
|
-
binstub = File.join(project_root, 'bin', executable)
|
19
|
-
if File.file?(binstub)
|
20
|
-
exec Gem.ruby, binstub, *ARGV
|
21
|
-
else
|
22
|
-
puts 'Please run `bundler install --binstubs` from your project root to generate bundle-specific executables'
|
23
|
-
exit!
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'ostruct'
|
2
|
-
|
3
|
-
module Padrino
|
4
|
-
##
|
5
|
-
# Padrino simple configuration module
|
6
|
-
#
|
7
|
-
module Configuration
|
8
|
-
##
|
9
|
-
# Returns the configuration structure allowing to get and set it's values.
|
10
|
-
# Padrino.config is a simple Ruby OpenStruct object with no additional magic.
|
11
|
-
#
|
12
|
-
# Example:
|
13
|
-
#
|
14
|
-
# Padrino.config.value1 = 42
|
15
|
-
# exit if Padrino.config.exiting
|
16
|
-
#
|
17
|
-
def config
|
18
|
-
@config ||= OpenStruct.new
|
19
|
-
end
|
20
|
-
|
21
|
-
##
|
22
|
-
# Allows to configure different environments differently. Requires a block.
|
23
|
-
#
|
24
|
-
# Example:
|
25
|
-
#
|
26
|
-
# Padrino.configure :development do |config|
|
27
|
-
# config.value2 = 'only development'
|
28
|
-
# end
|
29
|
-
# Padrino.configure :development, :production do |config|
|
30
|
-
# config.value2 = 'both development and production'
|
31
|
-
# end
|
32
|
-
# Padrino.configure do |config|
|
33
|
-
# config.value2 = 'any environment'
|
34
|
-
# end
|
35
|
-
#
|
36
|
-
def configure(*environments)
|
37
|
-
yield(config) if environments.empty? || environments.include?(Padrino.env)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,201 +0,0 @@
|
|
1
|
-
require 'http_router' unless defined?(HttpRouter)
|
2
|
-
|
3
|
-
class HttpRouter
|
4
|
-
def rewrite_partial_path_info(env, request); end
|
5
|
-
def rewrite_path_info(env, request); end
|
6
|
-
|
7
|
-
def process_destination_path(path, env)
|
8
|
-
Thread.current['padrino.instance'].instance_eval do
|
9
|
-
request.route_obj = path.route
|
10
|
-
@_response_buffer = nil
|
11
|
-
@route = path.route
|
12
|
-
@params ||= {}
|
13
|
-
@params.update(env['router.params'])
|
14
|
-
@block_params = if match_data = env['router.request'].extra_env['router.regex_match']
|
15
|
-
params_list = match_data.to_a
|
16
|
-
params_list.shift
|
17
|
-
@params[:captures] = params_list
|
18
|
-
params_list
|
19
|
-
else
|
20
|
-
env['router.request'].params
|
21
|
-
end
|
22
|
-
# Provide access to the current controller to the request
|
23
|
-
# Now we can eval route, but because we have "throw halt" we need to be
|
24
|
-
# (en)sure to reset old layout and run controller after filters.
|
25
|
-
original_params = @params
|
26
|
-
parent_layout = @layout
|
27
|
-
successful = false
|
28
|
-
begin
|
29
|
-
filter! :before
|
30
|
-
(@route.before_filters - settings.filters[:before]).each { |block| instance_eval(&block) }
|
31
|
-
@layout = path.route.use_layout if path.route.use_layout
|
32
|
-
@route.custom_conditions.each { |block| pass if block.bind(self).call == false }
|
33
|
-
halt_response = catch(:halt) { route_eval { @route.dest[self, @block_params] } }
|
34
|
-
@_response_buffer = halt_response.is_a?(Array) ? halt_response.last : halt_response
|
35
|
-
successful = true
|
36
|
-
halt halt_response
|
37
|
-
ensure
|
38
|
-
(@route.after_filters - settings.filters[:after]).each { |block| instance_eval(&block) } if successful
|
39
|
-
@layout = parent_layout
|
40
|
-
@params = original_params
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class Route
|
46
|
-
VALID_HTTP_VERBS.replace %w[GET POST PUT PATCH DELETE HEAD OPTIONS LINK UNLINK]
|
47
|
-
|
48
|
-
attr_accessor :use_layout, :controller, :action, :cache, :cache_key, :cache_expires, :parent
|
49
|
-
|
50
|
-
def before_filters(&block)
|
51
|
-
@_before_filters ||= []
|
52
|
-
@_before_filters << block if block_given?
|
53
|
-
|
54
|
-
@_before_filters
|
55
|
-
end
|
56
|
-
|
57
|
-
def after_filters(&block)
|
58
|
-
@_after_filters ||= []
|
59
|
-
@_after_filters << block if block_given?
|
60
|
-
|
61
|
-
@_after_filters
|
62
|
-
end
|
63
|
-
|
64
|
-
def custom_conditions(&block)
|
65
|
-
@_custom_conditions ||= []
|
66
|
-
@_custom_conditions << block if block_given?
|
67
|
-
|
68
|
-
@_custom_conditions
|
69
|
-
end
|
70
|
-
|
71
|
-
def significant_variable_names
|
72
|
-
@significant_variable_names ||= if @original_path.is_a?(String)
|
73
|
-
@original_path.scan(/(^|[^\\])[:\*]([a-zA-Z0-9_]+)/).map{|p| p.last.to_sym}
|
74
|
-
elsif @original_path.is_a?(Regexp) and @original_path.respond_to?(:named_captures)
|
75
|
-
@original_path.named_captures.keys.map(&:to_sym)
|
76
|
-
else
|
77
|
-
[]
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def to(dest = nil, &dest_block)
|
82
|
-
@dest = dest || dest_block || raise("you didn't specify a destination")
|
83
|
-
|
84
|
-
@router.current_order ||= 0
|
85
|
-
@order = @router.current_order
|
86
|
-
@router.current_order += 1
|
87
|
-
|
88
|
-
if @dest.respond_to?(:url_mount=)
|
89
|
-
urlmount = UrlMount.new(@path_for_generation, @default_values || {}) # TODO url mount should accept nil here.
|
90
|
-
urlmount.url_mount = @router.url_mount if @router.url_mount
|
91
|
-
@dest.url_mount = urlmount
|
92
|
-
end
|
93
|
-
self
|
94
|
-
end
|
95
|
-
|
96
|
-
attr_accessor :order
|
97
|
-
|
98
|
-
end
|
99
|
-
|
100
|
-
attr_accessor :current_order
|
101
|
-
|
102
|
-
def sort!
|
103
|
-
@routes.sort!{ |a, b| a.order <=> b.order }
|
104
|
-
end
|
105
|
-
|
106
|
-
class Node::Glob
|
107
|
-
def to_code
|
108
|
-
id = root.next_counter
|
109
|
-
"request.params << (globbed_params#{id} = [])
|
110
|
-
until request.path.empty?
|
111
|
-
globbed_params#{id} << request.path.shift
|
112
|
-
#{super}
|
113
|
-
end
|
114
|
-
request.path[0,0] = globbed_params#{id}
|
115
|
-
request.params.pop"
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
class Node::SpanningRegex
|
120
|
-
def to_code
|
121
|
-
params_count = @ordered_indicies.size
|
122
|
-
whole_path_var = "whole_path#{root.next_counter}"
|
123
|
-
"#{whole_path_var} = request.joined_path
|
124
|
-
if match = #{@matcher.inspect}.match(#{whole_path_var}) and match.begin(0).zero?
|
125
|
-
_#{whole_path_var} = request.path.dup
|
126
|
-
" << param_capturing_code << "
|
127
|
-
remaining_path = #{whole_path_var}[match[0].size + (#{whole_path_var}[match[0].size] == ?/ ? 1 : 0), #{whole_path_var}.size]
|
128
|
-
request.path = remaining_path.split('/')
|
129
|
-
#{node_to_code}
|
130
|
-
request.path = _#{whole_path_var}
|
131
|
-
request.params.slice!(#{-params_count}, #{params_count})
|
132
|
-
end
|
133
|
-
"
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
# Monkey patching the Request class. Using Rack::Utils.unescape rather than
|
138
|
-
# URI.unescape which can't handle utf-8 chars
|
139
|
-
class Request
|
140
|
-
def initialize(path, rack_request)
|
141
|
-
@rack_request = rack_request
|
142
|
-
@path = path.split(/\//).map{|part| Rack::Utils.unescape(part) }
|
143
|
-
@path.shift if @path.first == ''
|
144
|
-
@path.push('') if path[-1] == ?/
|
145
|
-
@extra_env = {}
|
146
|
-
@params = []
|
147
|
-
@acceptable_methods = Set.new
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
class Node::Path
|
152
|
-
def to_code
|
153
|
-
path_ivar = inject_root_ivar(self)
|
154
|
-
"#{"if !callback && request.path.size == 1 && request.path.first == '' && (request.rack_request.head? || request.rack_request.get?) && request.rack_request.path_info[-1] == ?/
|
155
|
-
catch(:pass) do
|
156
|
-
response = ::Rack::Response.new
|
157
|
-
response.redirect(request.rack_request.path_info[0, request.rack_request.path_info.size - 1], 302)
|
158
|
-
return response.finish
|
159
|
-
end
|
160
|
-
end" if router.redirect_trailing_slash?}
|
161
|
-
|
162
|
-
#{"if request.#{router.ignore_trailing_slash? ? 'path_finished?' : 'path.empty?'}" unless route.match_partially}
|
163
|
-
catch(:pass) do
|
164
|
-
if callback
|
165
|
-
request.called = true
|
166
|
-
callback.call(Response.new(request, #{path_ivar}))
|
167
|
-
else
|
168
|
-
env = request.rack_request.dup.env
|
169
|
-
env['router.request'] = request
|
170
|
-
env['router.params'] ||= {}
|
171
|
-
#{"env['router.params'].merge!(Hash[#{param_names.inspect}.zip(request.params)])" if dynamic?}
|
172
|
-
env['router.params'] = env['router.params'].with_indifferent_access
|
173
|
-
@router.rewrite#{"_partial" if route.match_partially}_path_info(env, request)
|
174
|
-
response = @router.process_destination_path(#{path_ivar}, env)
|
175
|
-
return response unless router.pass_on_response(response)
|
176
|
-
end
|
177
|
-
end
|
178
|
-
#{"end" unless route.match_partially}"
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
class Node::FreeRegex
|
183
|
-
def to_code
|
184
|
-
id = root.next_counter
|
185
|
-
"whole_path#{id} = \"/\#{request.joined_path}\"
|
186
|
-
if match = #{matcher.inspect}.match(whole_path#{id}) and match[0].size == whole_path#{id}.size
|
187
|
-
request.extra_env['router.regex_match'] = match
|
188
|
-
old_path = request.path
|
189
|
-
request.path = ['']
|
190
|
-
" << (use_named_captures? ?
|
191
|
-
"match.names.size.times{|i| request.params << match[i + 1]} if match.respond_to?(:names) && match.names" : "") << "
|
192
|
-
#{super}
|
193
|
-
request.path = old_path
|
194
|
-
request.extra_env.delete('router.regex_match')
|
195
|
-
" << (use_named_captures? ?
|
196
|
-
"request.params.slice!(-match.names.size, match.names.size)" : ""
|
197
|
-
) << "
|
198
|
-
end"
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
module Padrino
|
2
|
-
class Mounter
|
3
|
-
module ApplicationExtension
|
4
|
-
attr_accessor :uri_root, :mounter_options
|
5
|
-
attr_writer :public_folder
|
6
|
-
|
7
|
-
def dependencies
|
8
|
-
@__dependencies ||= Dir.glob("#{root}/**/*.rb").delete_if { |path| path == app_file }
|
9
|
-
end
|
10
|
-
|
11
|
-
def prerequisites
|
12
|
-
@__prerequisites ||= []
|
13
|
-
end
|
14
|
-
|
15
|
-
def app_file
|
16
|
-
@__app_file ||= trace_method(:app_file) { mounter_options[:app_file] }
|
17
|
-
end
|
18
|
-
|
19
|
-
def root
|
20
|
-
@__root ||= trace_method(:root) { File.expand_path("#{app_file}/../") }
|
21
|
-
end
|
22
|
-
|
23
|
-
def public_folder
|
24
|
-
@public_folder ||= trace_method(:public_folder) { "" }
|
25
|
-
end
|
26
|
-
|
27
|
-
def app_name
|
28
|
-
@__app_name ||= mounter_options[:app_name] || self.to_s.underscore.to_sym
|
29
|
-
end
|
30
|
-
|
31
|
-
def setup_application!
|
32
|
-
@configured ||= trace_method(:setup_application!) do
|
33
|
-
$LOAD_PATH.concat(prerequisites)
|
34
|
-
require_dependencies if root.start_with?(Padrino.root)
|
35
|
-
true
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def require_dependencies
|
42
|
-
Padrino.require_dependencies(dependencies, :force => true)
|
43
|
-
end
|
44
|
-
|
45
|
-
def trace_method(method_name)
|
46
|
-
value = baseclass.send(method_name) if baseclass != self && baseclass.respond_to?(method_name)
|
47
|
-
value || yield
|
48
|
-
end
|
49
|
-
|
50
|
-
def baseclass
|
51
|
-
@__baseclass ||= respond_to?(:superclass) ? superclass : self
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
File without changes
|
data/test/test_configuration.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/helper')
|
2
|
-
|
3
|
-
describe "PadrinoConfiguration" do
|
4
|
-
it 'should be able to store values' do
|
5
|
-
Padrino.config.val1 = 12345
|
6
|
-
assert_equal 12345, Padrino.config.val1
|
7
|
-
end
|
8
|
-
|
9
|
-
it 'should be able to configure with block' do
|
10
|
-
Padrino.configure do |config|
|
11
|
-
config.val2 = 54321
|
12
|
-
end
|
13
|
-
assert_equal 54321, Padrino.config.val2
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'should be able to configure with block' do
|
17
|
-
Padrino.configure :test do |config|
|
18
|
-
config.test1 = 54321
|
19
|
-
end
|
20
|
-
Padrino.configure :development do |config|
|
21
|
-
config.test1 = 12345
|
22
|
-
end
|
23
|
-
Padrino.configure :test, :development do |config|
|
24
|
-
config.both1 = 54321
|
25
|
-
end
|
26
|
-
assert_equal 54321, Padrino.config.test1
|
27
|
-
assert_equal 54321, Padrino.config.both1
|
28
|
-
end
|
29
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/helper')
|
2
|
-
|
3
|
-
describe "Padrino::Reloader::Storage" do
|
4
|
-
describe "#classes" do
|
5
|
-
it 'should take an snapshot of the current loaded classes' do
|
6
|
-
snapshot = Padrino::Reloader::Storage.send(:object_classes)
|
7
|
-
assert_equal snapshot.include?(Padrino::Logger), true
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'should return a Set object' do
|
11
|
-
snapshot = Padrino::Reloader::Storage.send(:object_classes)
|
12
|
-
assert_equal snapshot.kind_of?(Set), true
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'should be able to process a the class name given a block' do
|
16
|
-
klasses = Padrino::Reloader::Storage.send(:object_classes) do |klass|
|
17
|
-
next unless klass.respond_to?(:name) # fix JRuby < 1.7.22
|
18
|
-
if klass.name =~ /^Padrino::/
|
19
|
-
klass
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
assert_equal (klasses.size > 1), true
|
24
|
-
klasses.each do |klass|
|
25
|
-
assert_match /^Padrino::/, klass.to_s
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
describe "#new_classes" do
|
31
|
-
before do
|
32
|
-
@snapshot = Padrino::Reloader::Storage.send(:object_classes)
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'should return list of new classes' do
|
36
|
-
class OSTest; end
|
37
|
-
module OSTestModule; class B; end; end
|
38
|
-
|
39
|
-
new_classes = Padrino::Reloader::Storage.send(:new_classes, @snapshot)
|
40
|
-
|
41
|
-
assert_equal new_classes.size, 2
|
42
|
-
assert_equal new_classes.include?(OSTest), true
|
43
|
-
assert_equal new_classes.include?(OSTestModule::B), true
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'should return a Set object' do
|
47
|
-
new_classes = Padrino::Reloader::Storage.send(:new_classes, @snapshot)
|
48
|
-
assert_equal new_classes.kind_of?(Set), true
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|