padrino-core 0.10.7 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/lib/padrino-core.rb +58 -4
  3. data/lib/padrino-core/application.rb +38 -16
  4. data/lib/padrino-core/application/flash.rb +229 -0
  5. data/lib/padrino-core/application/rendering.rb +39 -11
  6. data/lib/padrino-core/application/rendering/extensions/erubis.rb +55 -0
  7. data/lib/padrino-core/application/rendering/extensions/haml.rb +26 -0
  8. data/lib/padrino-core/application/rendering/extensions/slim.rb +14 -0
  9. data/lib/padrino-core/application/routing.rb +106 -35
  10. data/lib/padrino-core/cli/base.rb +41 -38
  11. data/lib/padrino-core/cli/rake.rb +30 -9
  12. data/lib/padrino-core/cli/rake_tasks.rb +9 -14
  13. data/lib/padrino-core/loader.rb +23 -9
  14. data/lib/padrino-core/locale/fr.yml +1 -1
  15. data/lib/padrino-core/locale/ru.yml +1 -1
  16. data/lib/padrino-core/logger.rb +48 -32
  17. data/lib/padrino-core/module.rb +58 -0
  18. data/lib/padrino-core/mounter.rb +15 -5
  19. data/lib/padrino-core/reloader.rb +14 -12
  20. data/lib/padrino-core/server.rb +4 -4
  21. data/lib/padrino-core/support_lite.rb +43 -6
  22. data/lib/padrino-core/version.rb +1 -1
  23. data/padrino-core.gemspec +9 -4
  24. data/test/fixtures/app_gem/Gemfile +4 -0
  25. data/test/fixtures/app_gem/app/app.rb +3 -0
  26. data/test/fixtures/app_gem/app_gem.gemspec +17 -0
  27. data/test/fixtures/app_gem/lib/app_gem.rb +7 -0
  28. data/test/fixtures/app_gem/lib/app_gem/version.rb +3 -0
  29. data/test/mini_shoulda.rb +1 -1
  30. data/test/test_application.rb +38 -21
  31. data/test/test_csrf_protection.rb +80 -0
  32. data/test/test_filters.rb +70 -0
  33. data/test/test_flash.rb +168 -0
  34. data/test/test_logger.rb +27 -0
  35. data/test/test_mounter.rb +24 -2
  36. data/test/test_reloader_simple.rb +4 -4
  37. data/test/test_rendering.rb +75 -4
  38. data/test/test_routing.rb +164 -35
  39. data/test/test_support_lite.rb +56 -0
  40. metadata +52 -29
@@ -3,20 +3,41 @@ require 'rake'
3
3
  require 'rake/dsl_definition'
4
4
  require 'thor'
5
5
  require 'securerandom' unless defined?(SecureRandom)
6
+ require 'padrino-gen'
6
7
 
7
8
  module PadrinoTasks
8
9
  def self.init(init=false)
9
10
  Padrino::Tasks.files.flatten.uniq.each { |rakefile| Rake.application.add_import(rakefile) rescue puts "<= Failed load #{ext}" }
10
- if init
11
- Rake.application.init
12
- Rake.application.instance_variable_set(:@rakefile, __FILE__)
13
- load(File.expand_path('../rake_tasks.rb', __FILE__))
14
- Rake.application.load_imports
15
- Rake.application.top_level
16
- else
17
- load(File.expand_path('../rake_tasks.rb', __FILE__))
18
- Rake.application.load_imports
11
+ load(File.expand_path('../rake_tasks.rb', __FILE__))
12
+ Rake.application.load_imports
13
+ end
14
+
15
+ def self.use(task)
16
+ tasks << task
17
+ end
18
+
19
+ def self.tasks
20
+ @tasks ||= []
21
+ end
22
+
23
+ def self.load?(task, constant_present)
24
+ if constant_present && !PadrinoTasks.tasks.include?(task)
25
+ warn <<-WARNING.undent
26
+ Loading #{task} tasks automatically.
27
+ This functionality will be disabled in future versions. Please put
28
+
29
+ PadrinoTasks.use(#{task.inspect})
30
+ PadrinoTasks.init
31
+
32
+ and remove
33
+
34
+ require File.expand_path('../config/boot.rb', __FILE__)
35
+
36
+ in you Rakefile instead.
37
+ WARNING
19
38
  end
39
+
40
+ constant_present || PadrinoTasks.tasks.include?(task)
20
41
  end
21
42
  end
22
43
 
@@ -1,11 +1,17 @@
1
1
  # Load rake tasks from common rake task definition locations
2
- Dir["lib/tasks/**/*.rake"].
3
- concat(Dir["tasks/**/*.rake"]).
4
- concat(Dir["{test,spec}/*.rake"]).each { |rake| load(rake) }
2
+ Dir["{lib/tasks/**,tasks/**,test,spec}/*.rake"].each do |file|
3
+ begin
4
+ load(file)
5
+ rescue LoadError => e
6
+ warn "#{file}: #{e.message}"
7
+ end
8
+ end
5
9
 
6
10
  # Loads the Padrino applications mounted within the project
7
11
  # setting up the required environment for Padrino
8
12
  task :environment do
13
+ require File.expand_path('config/boot.rb', Rake.application.original_dir)
14
+
9
15
  Padrino.mounted_apps.each do |app|
10
16
  app.app_obj.setup_application!
11
17
  end
@@ -46,14 +52,3 @@ namespace :routes do
46
52
  list_app_routes(app, args) if app
47
53
  end
48
54
  end
49
-
50
- desc "Generate the Rakefile"
51
- task :gen do
52
- File.open(Padrino.root("Rakefile"), "w") do |file|
53
- file.puts <<-RUBY.gsub(/^ {6}/, '')
54
- require File.expand_path('../config/boot.rb', __FILE__)
55
- require 'padrino-core/cli/rake'
56
- PadrinoTasks.init
57
- RUBY
58
- end
59
- end
@@ -60,6 +60,8 @@ module Padrino
60
60
  #
61
61
  def load!
62
62
  return false if loaded?
63
+ t = Time.now
64
+
63
65
  @_called_from = first_caller
64
66
  Padrino.set_encoding
65
67
  Padrino.set_load_paths(*load_paths) # We set the padrino load paths
@@ -71,6 +73,8 @@ module Padrino
71
73
  Padrino.after_load.each(&:call) # Run after hooks
72
74
  Padrino::Reloader.run!
73
75
  Thread.current[:padrino_loaded] = true
76
+
77
+ Padrino.logger.devel "Loaded Padrino in #{Time.now - t} seconds"
74
78
  end
75
79
 
76
80
  ##
@@ -162,10 +166,8 @@ module Padrino
162
166
  begin
163
167
  Padrino::Reloader.safe_load(file, options.dup)
164
168
  files.delete(file)
165
- rescue LoadError => e
166
- errors << e
167
- failed << file
168
- rescue NameError => e
169
+ rescue NameError, LoadError => e
170
+ Padrino.logger.devel "Problem while loading #{file}: #{e.to_s}"
169
171
  errors << e
170
172
  failed << file
171
173
  rescue Exception => e
@@ -190,11 +192,7 @@ module Padrino
190
192
  # Padrino.dependency_paths << "#{Padrino.root}/uploaders/*.rb"
191
193
  #
192
194
  def dependency_paths
193
- @_dependency_paths_was = [
194
- "#{root}/config/database.rb", "#{root}/lib/**/*.rb", "#{root}/shared/lib/**/*.rb",
195
- "#{root}/models/**/*.rb", "#{root}/shared/models/**/*.rb", "#{root}/config/apps.rb"
196
- ]
197
- @_dependency_paths ||= @_dependency_paths_was
195
+ @_dependency_paths ||= (dependency_paths_was + Array(module_paths))
198
196
  end
199
197
 
200
198
  ##
@@ -207,5 +205,21 @@ module Padrino
207
205
  $:.concat(paths); load_paths.concat(paths)
208
206
  $:.uniq!; load_paths.uniq!
209
207
  end
208
+
209
+ private
210
+ def module_paths
211
+ Padrino.modules.map(&:dependency_paths).flatten!
212
+ end
213
+
214
+ def dependency_paths_was
215
+ [
216
+ "#{root}/config/database.rb",
217
+ "#{root}/lib/**/*.rb",
218
+ "#{root}/shared/lib/**/*.rb",
219
+ "#{root}/models/**/*.rb",
220
+ "#{root}/shared/models/**/*.rb",
221
+ "#{root}/config/apps.rb"
222
+ ]
223
+ end
210
224
  end # self
211
225
  end # Padrino
@@ -12,7 +12,7 @@ fr:
12
12
  day_names: [Dimanche, Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi]
13
13
  abbr_day_names: [Lun, Mar, Mer, Jeu, Ven, Sam, Dim]
14
14
  month_names: [~, Janvier, Février, Mars, Avril, Mai, Juin, Juillet, Août, Septembre, Octobre, Novembre, Décembre]
15
- abbr_month_names: [~, Jan, Fev, Mar, Avr, Mai, Jui, Jui, Aou, Sep, Oct, Nov, Dec]
15
+ abbr_month_names: [~, Jan, Fev, Mar, Avr, Mai, Jun, Jul, Aou, Sep, Oct, Nov, Dec]
16
16
  order:
17
17
  - day
18
18
  - month
@@ -12,7 +12,7 @@ ru:
12
12
  day_names: [Воскресенье, Понедельник, Вторник, Среда, Четверг, Пятница, Суббота]
13
13
  abbr_day_names: [Вс, Пн, Вт, Ср, Чт, Пт, Сб]
14
14
  month_names: [~, Январь, Февраль, Март, Апрель, Май, Июнь, Июль, Август, Сентябрь, Октябрь, Ноябрь, Декабрь]
15
- abbr_month_names: [~, Янв, Феб, Мар, Апр, Май, Июн, Июл, Авг, Сен, Окт, Ноя, Дек]
15
+ abbr_month_names: [~, Янв, Фев, Мар, Апр, Май, Июн, Июл, Авг, Сен, Окт, Ноя, Дек]
16
16
  order:
17
17
  - year
18
18
  - month
@@ -13,8 +13,7 @@ module Padrino
13
13
  # logger.warn "bar"
14
14
  #
15
15
  def self.logger
16
- Padrino::Logger.setup! if Thread.current[:padrino_logger].nil?
17
- Thread.current[:padrino_logger]
16
+ Padrino::Logger.logger
18
17
  end
19
18
 
20
19
  ##
@@ -35,8 +34,7 @@ module Padrino
35
34
  # Padrino.logger = Buffered.new(STDOUT)
36
35
  #
37
36
  def self.logger=(value)
38
- value.extend(Padrino::Logger::Extensions) unless (Padrino::Logger::Extensions === value)
39
- Thread.current[:padrino_logger] = value
37
+ Padrino::Logger.logger = value
40
38
  end
41
39
 
42
40
  ##
@@ -95,7 +93,7 @@ module Padrino
95
93
  #
96
94
  # @example
97
95
  # logger.bench 'GET', started_at, '/blog/categories'
98
- # # => DEBUG - GET (0.056ms) - /blog/categories
96
+ # # => DEBUG - GET (0.0056s) - /blog/categories
99
97
  #
100
98
  def bench(action, began_at, message, level=:debug, color=:yellow)
101
99
  @_pad ||= 8
@@ -103,7 +101,7 @@ module Padrino
103
101
  duration = Time.now - began_at
104
102
  color = :red if duration > 1
105
103
  action = colorize(action.to_s.upcase.rjust(@_pad), color)
106
- duration = colorize('%0.4fms' % duration, :bold, color)
104
+ duration = colorize('%0.4fs' % duration, :bold, color)
107
105
  push "#{action} (#{duration}) #{message}", level
108
106
  end
109
107
 
@@ -208,7 +206,6 @@ module Padrino
208
206
  end
209
207
 
210
208
  include Extensions
211
- include Colorize
212
209
 
213
210
  attr_accessor :level
214
211
  attr_accessor :auto_flush
@@ -216,8 +213,7 @@ module Padrino
216
213
  attr_reader :log
217
214
  attr_reader :init_args
218
215
  attr_accessor :log_static
219
-
220
- @@mutex = {}
216
+ attr_reader :colorize_logging
221
217
 
222
218
  ##
223
219
  # Configuration for a given environment, possible options are:
@@ -233,6 +229,7 @@ module Padrino
233
229
  # :format_datetime:: Format of datetime. Defaults to: "%d/%b/%Y %H:%M:%S"
234
230
  # :format_message:: Format of message. Defaults to: ""%s - - [%s] \"%s\"""
235
231
  # :log_static:: Whether or not to show log messages for static files. Defaults to: false
232
+ # :colorize_logging:: Whether or not to colorize log messages. Defaults to: true
236
233
  #
237
234
  # @example
238
235
  # Padrino::Logger::Config[:development] = { :log_level => :debug, :stream => :to_file }
@@ -254,11 +251,22 @@ module Padrino
254
251
  #
255
252
  Config = {
256
253
  :production => { :log_level => :warn, :stream => :to_file },
257
- :development => { :log_level => :debug, :stream => :stdout, :format_datetime => ' ' },
254
+ :development => { :log_level => :debug, :stream => :stdout, :format_datetime => '' },
258
255
  :test => { :log_level => :debug, :stream => :null }
259
256
  }
260
257
  Config.merge!(PADRINO_LOGGER) if PADRINO_LOGGER
261
258
 
259
+ @@mutex = Mutex.new
260
+ def self.logger
261
+ @_logger || setup!
262
+ end
263
+
264
+ def self.logger=(logger)
265
+ logger.extend(Padrino::Logger::Extensions)
266
+
267
+ @_logger = logger
268
+ end
269
+
262
270
  ##
263
271
  # Setup a new logger
264
272
  #
@@ -266,25 +274,27 @@ module Padrino
266
274
  # A {Padrino::Logger} instance
267
275
  #
268
276
  def self.setup!
269
- config_level = (PADRINO_LOG_LEVEL || Padrino.env || :test).to_sym # need this for PADRINO_LOG_LEVEL
270
- config = Config[config_level]
277
+ self.logger = begin
278
+ config_level = (PADRINO_LOG_LEVEL || Padrino.env || :test).to_sym # need this for PADRINO_LOG_LEVEL
279
+ config = Config[config_level]
271
280
 
272
- unless config
273
- warn("No logging configuration for :#{config_level} found, falling back to :production")
274
- config = Config[:production]
275
- end
281
+ unless config
282
+ warn("No logging configuration for :#{config_level} found, falling back to :production")
283
+ config = Config[:production]
284
+ end
276
285
 
277
- stream = case config[:stream]
278
- when :to_file
279
- FileUtils.mkdir_p(Padrino.root('log')) unless File.exists?(Padrino.root('log'))
280
- File.new(Padrino.root('log', "#{Padrino.env}.log"), 'a+')
281
- when :null then StringIO.new
282
- when :stdout then $stdout
283
- when :stderr then $stderr
284
- else config[:stream] # return itself, probabilly is a custom stream.
285
- end
286
+ stream = case config[:stream]
287
+ when :to_file
288
+ FileUtils.mkdir_p(Padrino.root('log')) unless File.exists?(Padrino.root('log'))
289
+ File.new(Padrino.root('log', "#{Padrino.env}.log"), 'a+')
290
+ when :null then StringIO.new
291
+ when :stdout then $stdout
292
+ when :stderr then $stderr
293
+ else config[:stream] # return itself, probabilly is a custom stream.
294
+ end
286
295
 
287
- Thread.current[:padrino_logger] = Padrino::Logger.new(config.merge(:stream => stream))
296
+ Padrino::Logger.new(config.merge(:stream => stream))
297
+ end
288
298
  end
289
299
 
290
300
  ##
@@ -311,16 +321,20 @@ module Padrino
311
321
  # @option options [Symbol] :log_static (false)
312
322
  # Whether or not to show log messages for static files.
313
323
  #
324
+ # @option options [Symbol] :colorize_logging (true)
325
+ # Whether or not to colorize log messages. Defaults to: true
326
+ #
314
327
  def initialize(options={})
315
328
  @buffer = []
316
329
  @auto_flush = options.has_key?(:auto_flush) ? options[:auto_flush] : true
317
330
  @level = options[:log_level] ? Padrino::Logger::Levels[options[:log_level]] : Padrino::Logger::Levels[:debug]
318
331
  @log = options[:stream] || $stdout
319
332
  @log.sync = true
320
- @mutex = @@mutex[@log] ||= Mutex.new
321
333
  @format_datetime = options[:format_datetime] || "%d/%b/%Y %H:%M:%S"
322
- @format_message = options[:format_message] || "%s -%s%s"
334
+ @format_message = options[:format_message] || "%s - %s %s"
323
335
  @log_static = options.has_key?(:log_static) ? options[:log_static] : false
336
+ @colorize_logging = options.has_key?(:colorize_logging) ? options[:colorize_logging] : true
337
+ colorize! if @colorize_logging
324
338
  end
325
339
 
326
340
  ##
@@ -328,8 +342,9 @@ module Padrino
328
342
  #
329
343
  def flush
330
344
  return unless @buffer.size > 0
331
- @mutex.synchronize do
332
- @log.write(@buffer.slice!(0..-1).join(''))
345
+ @@mutex.synchronize do
346
+ @log.write(@buffer.join(''))
347
+ @buffer.clear
333
348
  end
334
349
  end
335
350
 
@@ -360,7 +375,9 @@ module Padrino
360
375
  #
361
376
  def <<(message = nil)
362
377
  message << "\n" unless message[-1] == ?\n
363
- @buffer << message
378
+ @@mutex.synchronize {
379
+ @buffer << message
380
+ }
364
381
  flush if @auto_flush
365
382
  message
366
383
  end
@@ -425,4 +442,3 @@ module Kernel # @private
425
442
  Padrino.logger
426
443
  end
427
444
  end # Kernel
428
-
@@ -0,0 +1,58 @@
1
+ module Padrino
2
+ module Module
3
+ attr_accessor :root
4
+
5
+ ##
6
+ # Register this module as being loaded from a gem. This automatically
7
+ # sets the root and therefore the dependency paths correctly.
8
+ #
9
+ # @param [String] name
10
+ # The name of the gem. Has to be the name as stated in the gemspec.
11
+ #
12
+ # @returns the gems root.
13
+ def gem!(name)
14
+ self.root = Padrino.gem(name, self)
15
+ end
16
+
17
+ ##
18
+ # Helper method for file references within a Padrino module.
19
+ #
20
+ # @param [Array<String>] args
21
+ # The directories to join to {Module.root}.
22
+ #
23
+ # @return [String]
24
+ # The absolute path.
25
+ #
26
+ # @example
27
+ # module MyModule
28
+ # extend Padrino::Module
29
+ # gem! 'my_gem'
30
+ # end
31
+ # Module.root!
32
+ def root(*args)
33
+ File.expand_path(File.join(@root, *args))
34
+ end
35
+
36
+ ##
37
+ # Returns the list of path globs to load as dependencies
38
+ # Appends custom dependency patterns to the be loaded for Padrino.
39
+ #
40
+ # @return [Array<String>]
41
+ # The dependency paths.
42
+ #
43
+ # @example
44
+ # module MyModule
45
+ # extend Padrino::Module
46
+ # gem! 'my_gem'
47
+ # end
48
+ #
49
+ # Module.dependency_paths << "#{MyModule.root}/uploaders/*.rb"
50
+ #
51
+ def dependency_paths
52
+ [
53
+ "#{root}/lib/**/*.rb", "#{root}/shared/lib/**/*.rb",
54
+ "#{root}/models/**/*.rb", "#{root}/shared/models/**/*.rb"
55
+ ]
56
+ end
57
+ end
58
+ end
@@ -22,10 +22,12 @@ module Padrino
22
22
  # @option options [Symbol] :app_file (Automatically detected)
23
23
  # @option options [Symbol] :app_obj (Detected)
24
24
  # @option options [Symbol] :app_root (Directory of :app_file)
25
+ # @option options [Symbol] :gem The gem to load the app from (Detected from name)
25
26
  #
26
27
  def initialize(name, options={})
27
28
  @name = name.to_s
28
29
  @app_class = options[:app_class] || @name.camelize
30
+ @gem = options[:gem] || @app_class.split("::").first.underscore
29
31
  @app_file = options[:app_file] || locate_app_file
30
32
  @app_obj = options[:app_obj] || app_constant || locate_app_object
31
33
  ensure_app_file! || ensure_app_object!
@@ -104,11 +106,12 @@ module Padrino
104
106
  #
105
107
  def named_routes
106
108
  app_obj.routes.map { |route|
107
- name_array = "(#{route.named.to_s.split("_").map { |piece| %Q[:#{piece}] }.join(", ")})"
108
- request_method = route.conditions[:request_method][0]
109
- full_path = File.join(uri_root, route.original_path)
110
- next if route.named.blank? || request_method == 'HEAD'
111
- OpenStruct.new(:verb => request_method, :identifier => route.named, :name => name_array, :path => full_path)
109
+ name_array = "(#{route.name.to_s.split("_").map { |piece| %Q[:#{piece}] }.join(", ")})"
110
+ request_method = route.request_methods.first
111
+ next if route.name.blank? || request_method == 'HEAD'
112
+ original_path = route.original_path.is_a?(Regexp) ? route.original_path.inspect : route.original_path
113
+ full_path = File.join(uri_root, original_path)
114
+ OpenStruct.new(:verb => request_method, :identifier => route.name, :name => name_array, :path => full_path)
112
115
  }.compact
113
116
  end
114
117
 
@@ -158,6 +161,13 @@ module Padrino
158
161
  candidates << app_constant.app_file if app_constant.respond_to?(:app_file) && File.exist?(app_constant.app_file.to_s)
159
162
  candidates << Padrino.first_caller if File.identical?(Padrino.first_caller.to_s, Padrino.called_from.to_s)
160
163
  candidates << Padrino.mounted_root(name.downcase, "app.rb")
164
+ simple_name = name.split("::").last.downcase
165
+ mod_name = name.split("::")[0..-2].join("::")
166
+ Padrino.modules.each do |mod|
167
+ if mod.name == mod_name
168
+ candidates << mod.root(simple_name, "app.rb")
169
+ end
170
+ end
161
171
  candidates << Padrino.root("app", "app.rb")
162
172
  candidates.find { |candidate| File.exist?(candidate) }
163
173
  end