padrino-core 0.10.7 → 0.11.0

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.
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