ramaze 2008.06 → 2008.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. data/README.markdown +6 -6
  2. data/Rakefile +33 -3
  3. data/bin/ramaze +18 -0
  4. data/doc/CHANGELOG +960 -0
  5. data/doc/LEGAL +5 -1
  6. data/doc/meta/announcement.txt +20 -36
  7. data/doc/tutorial/todolist.html +421 -313
  8. data/doc/tutorial/todolist.mkd +33 -16
  9. data/examples/app/blog/spec/blog.rb +3 -3
  10. data/examples/app/rapaste/controller/paste.rb +8 -1
  11. data/examples/app/rapaste/model/paste.rb +3 -0
  12. data/examples/app/rapaste/spec/rapaste.rb +3 -1
  13. data/examples/app/rapaste/start.rb +3 -2
  14. data/examples/app/sourceview/public/sourceview.js +2 -2
  15. data/examples/app/todolist/spec/todolist.rb +6 -6
  16. data/examples/app/todolist/template/index.xhtml +1 -1
  17. data/examples/app/whywiki/spec/whywiki.rb +2 -2
  18. data/examples/app/wikore/spec/wikore.rb +2 -2
  19. data/examples/app/wikore/src/model.rb +4 -3
  20. data/examples/app/wiktacular/spec/wiktacular.rb +7 -7
  21. data/examples/basic/simple.rb +2 -2
  22. data/examples/helpers/paginate.rb +71 -0
  23. data/examples/misc/simple_auth.rb +20 -8
  24. data/lib/proto/controller/init.rb +10 -0
  25. data/lib/proto/controller/main.rb +1 -3
  26. data/lib/proto/model/init.rb +4 -0
  27. data/lib/proto/public/dispatch.fcgi +1 -1
  28. data/lib/proto/spec/main.rb +2 -1
  29. data/lib/proto/start.rb +3 -3
  30. data/lib/proto/start.ru +1 -1
  31. data/lib/proto/view/error.xhtml +4 -4
  32. data/lib/ramaze.rb +8 -3
  33. data/lib/ramaze/action.rb +6 -6
  34. data/lib/ramaze/adapter.rb +1 -6
  35. data/lib/ramaze/adapter/base.rb +30 -27
  36. data/lib/ramaze/adapter/cgi.rb +1 -0
  37. data/lib/ramaze/cache.rb +1 -3
  38. data/lib/ramaze/cache/memcached.rb +3 -5
  39. data/lib/ramaze/contrib/auto_params.rb +2 -2
  40. data/lib/ramaze/contrib/auto_params/get_args.rb +2 -1
  41. data/lib/ramaze/contrib/gems.rb +17 -18
  42. data/lib/ramaze/contrib/gzip_filter.rb +22 -9
  43. data/lib/ramaze/contrib/maruku_uv.rb +59 -0
  44. data/lib/ramaze/contrib/profiling.rb +1 -1
  45. data/lib/ramaze/contrib/rest.rb +16 -13
  46. data/lib/ramaze/contrib/sequel/create_join.rb +25 -0
  47. data/lib/ramaze/contrib/sequel/form_field.rb +129 -0
  48. data/lib/ramaze/contrib/sequel/image.rb +198 -0
  49. data/lib/ramaze/contrib/sequel/relation.rb +82 -0
  50. data/lib/ramaze/controller.rb +33 -34
  51. data/lib/ramaze/controller/resolve.rb +29 -9
  52. data/lib/ramaze/current.rb +60 -20
  53. data/lib/ramaze/current/request.rb +8 -7
  54. data/lib/ramaze/current/response.rb +15 -3
  55. data/lib/ramaze/current/session/flash.rb +8 -0
  56. data/lib/ramaze/dispatcher.rb +17 -9
  57. data/lib/ramaze/dispatcher/action.rb +4 -5
  58. data/lib/ramaze/dispatcher/directory.rb +1 -1
  59. data/lib/ramaze/dispatcher/error.rb +4 -4
  60. data/lib/ramaze/dispatcher/file.rb +4 -4
  61. data/lib/ramaze/gestalt.rb +15 -20
  62. data/lib/ramaze/helper/cgi.rb +7 -15
  63. data/lib/ramaze/helper/formatting.rb +41 -1
  64. data/lib/ramaze/helper/httpdigest.rb +20 -7
  65. data/lib/ramaze/helper/link.rb +4 -6
  66. data/lib/ramaze/helper/paginate.rb +233 -0
  67. data/lib/ramaze/helper/redirect.rb +1 -1
  68. data/lib/ramaze/helper/rest.rb +1 -1
  69. data/lib/ramaze/helper/thread.rb +17 -0
  70. data/lib/ramaze/helper/ultraviolet.rb +44 -0
  71. data/lib/ramaze/helper/user.rb +4 -9
  72. data/lib/ramaze/log.rb +2 -2
  73. data/lib/ramaze/log/analogger.rb +21 -23
  74. data/lib/ramaze/log/growl.rb +21 -23
  75. data/lib/ramaze/log/hub.rb +1 -1
  76. data/lib/ramaze/log/informer.rb +97 -99
  77. data/lib/ramaze/log/knotify.rb +14 -16
  78. data/lib/ramaze/log/logger.rb +11 -13
  79. data/lib/ramaze/log/logging.rb +61 -63
  80. data/lib/ramaze/log/rotatinginformer.rb +168 -0
  81. data/lib/ramaze/log/syslog.rb +41 -31
  82. data/lib/ramaze/log/xosd.rb +70 -72
  83. data/lib/ramaze/option.rb +9 -6
  84. data/lib/ramaze/option/holder.rb +5 -27
  85. data/lib/ramaze/reloader.rb +186 -0
  86. data/lib/ramaze/setup.rb +1 -1
  87. data/lib/ramaze/snippets.rb +13 -0
  88. data/lib/ramaze/snippets/array/put_within.rb +31 -24
  89. data/lib/ramaze/snippets/binding/locals.rb +23 -11
  90. data/lib/ramaze/snippets/dictionary.rb +2 -2
  91. data/lib/ramaze/snippets/fiber.rb +63 -0
  92. data/lib/ramaze/snippets/kernel/constant.rb +36 -21
  93. data/lib/ramaze/snippets/kernel/pretty_inspect.rb +12 -6
  94. data/lib/ramaze/snippets/numeric/filesize_format.rb +24 -17
  95. data/lib/ramaze/snippets/numeric/time.rb +63 -0
  96. data/lib/ramaze/snippets/object/__dir__.rb +29 -0
  97. data/lib/ramaze/snippets/object/acquire.rb +40 -0
  98. data/lib/ramaze/snippets/object/instance_variable_defined.rb +16 -5
  99. data/lib/ramaze/snippets/object/pretty.rb +14 -4
  100. data/lib/ramaze/snippets/object/scope.rb +14 -7
  101. data/lib/ramaze/snippets/ordered_set.rb +25 -14
  102. data/lib/ramaze/snippets/proc/locals.rb +17 -9
  103. data/lib/ramaze/snippets/ramaze/deprecated.rb +13 -0
  104. data/lib/ramaze/snippets/ramaze/fiber.rb +24 -0
  105. data/lib/ramaze/snippets/ramaze/state.rb +86 -0
  106. data/lib/ramaze/snippets/ramaze/struct.rb +45 -0
  107. data/lib/ramaze/snippets/string/camel_case.rb +13 -8
  108. data/lib/ramaze/snippets/string/color.rb +24 -20
  109. data/lib/ramaze/snippets/string/each.rb +14 -3
  110. data/lib/ramaze/snippets/string/end_with.rb +20 -0
  111. data/lib/ramaze/snippets/string/esc.rb +26 -21
  112. data/lib/ramaze/snippets/string/ord.rb +12 -6
  113. data/lib/ramaze/snippets/string/snake_case.rb +13 -7
  114. data/lib/ramaze/snippets/string/start_with.rb +16 -5
  115. data/lib/ramaze/snippets/string/unindent.rb +23 -15
  116. data/lib/ramaze/snippets/thread/into.rb +3 -3
  117. data/lib/ramaze/spec/helper/bacon.rb +5 -5
  118. data/lib/ramaze/spec/helper/mock_http.rb +1 -1
  119. data/lib/ramaze/spec/helper/pretty_output.rb +2 -2
  120. data/lib/ramaze/spec/helper/snippets.rb +8 -0
  121. data/lib/ramaze/template.rb +4 -1
  122. data/lib/ramaze/template/ezamar/textpow.syntax +34 -0
  123. data/lib/ramaze/template/maruku.rb +34 -0
  124. data/lib/ramaze/template/tagz.rb +2 -2
  125. data/lib/ramaze/template/xslt.rb +2 -2
  126. data/lib/ramaze/tool/create.rb +27 -53
  127. data/lib/ramaze/tool/localize.rb +8 -4
  128. data/lib/ramaze/tool/mime.rb +11 -1
  129. data/lib/ramaze/tool/project_creator.rb +110 -0
  130. data/lib/ramaze/trinity.rb +4 -1
  131. data/lib/ramaze/version.rb +1 -1
  132. data/lib/vendor/bacon.rb +323 -0
  133. data/rake_tasks/gem.rake +10 -1
  134. data/rake_tasks/maintenance.rake +40 -2
  135. data/rake_tasks/metric.rake +24 -0
  136. data/rake_tasks/release.rake +17 -4
  137. data/rake_tasks/spec.rake +1 -2
  138. data/ramaze.gemspec +549 -495
  139. data/spec/contrib/auto_params.rb +3 -3
  140. data/spec/contrib/profiling.rb +2 -2
  141. data/spec/examples/simple_auth.rb +2 -2
  142. data/spec/examples/templates/template_haml.rb +0 -2
  143. data/spec/ramaze/action/file_cache.rb +22 -0
  144. data/spec/ramaze/adapter.rb +2 -2
  145. data/spec/ramaze/controller/actionless_templates.rb +1 -1
  146. data/spec/ramaze/controller/subclass.rb +15 -0
  147. data/spec/ramaze/controller/template_resolving.rb +1 -1
  148. data/spec/ramaze/controller/view/bar.xhtml +1 -0
  149. data/spec/ramaze/controller/view/base/another.xhtml +1 -0
  150. data/spec/ramaze/current/session.rb +1 -1
  151. data/spec/ramaze/dispatcher/file.rb +2 -2
  152. data/spec/ramaze/helper/aspect.rb +26 -17
  153. data/spec/ramaze/helper/formatting.rb +13 -0
  154. data/spec/ramaze/log/informer.rb +10 -10
  155. data/spec/ramaze/log/syslog.rb +67 -4
  156. data/spec/ramaze/rewrite.rb +1 -1
  157. data/spec/ramaze/route.rb +1 -1
  158. data/spec/ramaze/struct.rb +47 -0
  159. data/spec/ramaze/template/markaby.rb +1 -1
  160. data/spec/ramaze/template/tagz.rb +1 -1
  161. data/spec/snippets/binding/locals.rb +9 -0
  162. data/spec/snippets/numeric/time.rb +12 -0
  163. data/spec/snippets/{kernel → object}/__dir__.rb +0 -0
  164. data/spec/snippets/{kernel → object}/acquire.rb +0 -0
  165. metadata +90 -81
  166. data/cache.yaml +0 -7
  167. data/examples/app/rammit/spec/rammit.rb +0 -31
  168. data/examples/app/rammit/src/controller/main.rb +0 -3
  169. data/examples/app/rammit/src/controller/page.rb +0 -16
  170. data/examples/app/rammit/src/model.rb +0 -33
  171. data/examples/app/rammit/start.rb +0 -8
  172. data/examples/app/rammit/template/index.xhtml +0 -14
  173. data/examples/app/rammit/template/page/view.xhtml +0 -4
  174. data/lib/ramaze/snippets/kernel/__dir__.rb +0 -23
  175. data/lib/ramaze/snippets/kernel/acquire.rb +0 -34
  176. data/lib/ramaze/snippets/object/thread_accessor.rb +0 -5
  177. data/lib/ramaze/snippets/ramaze/thread_accessor.rb +0 -58
  178. data/lib/ramaze/snippets/struct/fill.rb +0 -23
  179. data/lib/ramaze/snippets/struct/values_at.rb +0 -39
  180. data/lib/ramaze/snippets/symbol/to_proc.rb +0 -24
  181. data/lib/ramaze/sourcereload.rb +0 -176
  182. data/spec/snippets/struct/fill.rb +0 -26
  183. data/spec/snippets/struct/values_at.rb +0 -52
  184. data/spec/snippets/symbol/to_proc.rb +0 -13
data/cache.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- bar:foobar:
3
- :value: bar
4
- :expires:
5
- foo:foobar:
6
- :value: foo
7
- :expires:
@@ -1,31 +0,0 @@
1
- require 'ramaze'
2
- require 'ramaze/spec/helper'
3
-
4
- $LOAD_PATH.unshift base = __DIR__/'..'
5
- spec_require 'hpricot', 'sequel'
6
-
7
- require 'start'
8
-
9
- describe 'Rammit' do
10
- behaves_like 'http'
11
- base = File.expand_path(__DIR__/'..')
12
- ramaze :view_root => base/'template',
13
- :public_root => base/'public'
14
-
15
- it 'should have intro page' do
16
- got = get('/')
17
- doc = Hpricot(got.body)
18
- form = doc.at(:form)
19
- form.at('textarea[@name=text]').should.not == nil
20
- form.at('input[@type=submit @value="Create a site"]').should.not == nil
21
- end
22
-
23
- it 'should create page from intro page' do
24
- got = post('/page/create', 'text' => 'Some text')
25
- refer = got.headers['Location']
26
- refer.should.not == nil
27
- got = get(refer)
28
- doc = Hpricot(got.body)
29
- doc.at('div#text').inner_html.should =~ /Some text/
30
- end
31
- end
@@ -1,3 +0,0 @@
1
- class MainController < Ramaze::Controller
2
- map '/'
3
- end
@@ -1,16 +0,0 @@
1
- class PageController < Ramaze::Controller
2
- map '/page'
3
-
4
- def create
5
- redirect_referrer unless request.post?
6
- if text = request[:text]
7
- page = Page.create :text => text
8
- redirect page.url
9
- end
10
- end
11
-
12
- def view(oid)
13
- page = Page[oid]
14
- @text = page.text
15
- end
16
- end
@@ -1,33 +0,0 @@
1
- require 'sequel'
2
-
3
- DB = Sequel.sqlite
4
-
5
- class User < Sequel::Model(:user)
6
- set_schema do
7
- primary_key :id
8
-
9
- text :nick
10
- text :password
11
- text :email
12
- time :created
13
- end
14
- end
15
-
16
- class Page < Sequel::Model(:page)
17
- include Ramaze::Helper::Link
18
-
19
- set_schema do
20
- primary_key :id
21
-
22
- text :text
23
- end
24
-
25
- def url
26
- R(PageController, :view, id)
27
- end
28
-
29
- end
30
-
31
- [ User, Page ].each do |model|
32
- model.create_table! unless model.table_exists?
33
- end
@@ -1,8 +0,0 @@
1
- require 'rubygems'
2
- require 'ramaze'
3
-
4
- require 'src/model'
5
- require 'src/controller/main'
6
- require 'src/controller/page'
7
-
8
- Ramaze.start
@@ -1,14 +0,0 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
4
- <head>
5
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
- <title>Rammit</title>
7
- </head>
8
- <body>
9
- <form method="POST" action="#{R PageController, :create}">
10
- <textarea name="text"></textarea>
11
- <input type="submit" value="Create a site" />
12
- </form>
13
- </body>
14
- </html>
@@ -1,4 +0,0 @@
1
- <div id="text">
2
- #@text
3
- </div>
4
-
@@ -1,23 +0,0 @@
1
- # Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
2
- # All files in this distribution are subject to the terms of the Ruby license.
3
-
4
- # Extensions for Kernel
5
-
6
- module Kernel
7
- unless defined?__DIR__
8
-
9
- # This is similar to +__FILE__+ and +__LINE__+, and returns a String
10
- # representing the directory of the current file is.
11
- # Unlike +__FILE__+ the path returned is absolute.
12
- #
13
- # This method is convenience for the
14
- # File.expand_path(File.dirname(__FILE__))
15
- # idiom.
16
- #
17
-
18
- def __DIR__()
19
- filename = caller[0][/^(.*):/, 1]
20
- File.expand_path(File.dirname(filename))
21
- end
22
- end
23
- end
@@ -1,34 +0,0 @@
1
- # Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
2
- # All files in this distribution are subject to the terms of the Ruby license.
3
-
4
- # Extensions for Kernel
5
-
6
- module Kernel
7
-
8
- # Require all .rb and .so files on the given globs, utilizes Dir::[].
9
- #
10
- # Examples:
11
- # # Given following directory structure:
12
- # # src/foo.rb
13
- # # src/bar.so
14
- # # src/foo.yaml
15
- # # src/foobar/baz.rb
16
- # # src/foobar/README
17
- #
18
- # # requires all files in 'src':
19
- # acquire 'src/*'
20
- #
21
- # # requires all files in 'src' recursive:
22
- # acquire 'src/**/*'
23
- #
24
- # # require 'src/foo.rb' and 'src/bar.so' and 'src/foobar/baz.rb'
25
- # acquire 'src/*', 'src/foobar/*'
26
-
27
- def acquire *globs
28
- globs.flatten.each do |glob|
29
- Dir[glob].each do |file|
30
- require file if file =~ /\.(rb|so)$/
31
- end
32
- end
33
- end
34
- end
@@ -1,5 +0,0 @@
1
- require(File.expand_path(File.join(File.dirname(__FILE__), '../ramaze/thread_accessor')))
2
-
3
- class Object
4
- include Ramaze::ThreadAccessor
5
- end
@@ -1,58 +0,0 @@
1
- module Ramaze
2
-
3
- # A alike of attr_accessor and friends, but for thread variables in
4
- # Thread::current
5
- module ThreadAccessor
6
-
7
- # Iterate over the names and yield accordingly.
8
- # names are either objects responding to #to_sym or hashes.
9
- #
10
- # It's only used within this module for abstractin-purposes.
11
- # Usage below.
12
- def self.each(*names)
13
- names.each do |name|
14
- if name.respond_to?(:to_hash)
15
- name.to_hash.each do |key, meth|
16
- key, meth = key.to_sym, meth.to_sym
17
- yield key, meth
18
- end
19
- else
20
- key = meth = name.to_sym
21
- yield key, meth
22
- end
23
- end
24
- end
25
-
26
- # thread_writer and thread_reader, initializer is a block that may be given
27
- # and its result will be the new value in case the reader was never called
28
- # before or the value wasn't set before.
29
- def thread_accessor(*names, &initializer)
30
- thread_writer(*names)
31
- thread_reader(*names, &initializer)
32
- end
33
-
34
- # Simple writer accessor to Thread::current[key]=
35
- def thread_writer(*names)
36
- ThreadAccessor.each(*names) do |key, meth|
37
- define_method("#{meth}="){|obj| Thread.current[key] = obj }
38
- end
39
- end
40
-
41
- # Reader accessor for Thread::current[key]
42
- def thread_reader(*names, &initializer)
43
- ThreadAccessor.each(*names) do |key, meth|
44
- if initializer
45
- define_method(meth) do
46
- unless Thread.current.key?(key)
47
- Thread.current[key] = instance_eval(&initializer)
48
- else
49
- Thread.current[key]
50
- end
51
- end
52
- else
53
- define_method(meth){ Thread.current[key] }
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,23 +0,0 @@
1
- # Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
2
- # All files in this distribution are subject to the terms of the Ruby license.
3
-
4
- # Extensions for Struct
5
-
6
- class Struct
7
-
8
- # Action = Struct.new('Action', :template, :method, :params)
9
- #
10
- # a = Action.fill(:template => nil, :method => :meth, :params => [1])
11
- # # => #<struct Struct::Action template=nil, method=:meth, params=[1]>
12
-
13
- def self.fill(hash = {})
14
- instance = new
15
- to_s = members.first.respond_to?(:to_str)
16
- hash.each do |key, value|
17
- key = to_s ? key.to_s : key.to_sym
18
- next unless members.include?(key)
19
- instance.send("#{key}=", value)
20
- end
21
- instance
22
- end
23
- end
@@ -1,39 +0,0 @@
1
- # Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
2
- # All files in this distribution are subject to the terms of the Ruby license.
3
-
4
- # Extensions for Struct
5
-
6
- class Struct
7
- undef values_at
8
-
9
- # Example:
10
- # Point = Struct.new(:x, :y)
11
- # point = Point.new(15, 10)
12
- # point.values_at(:y, :x)
13
- # # => [10, 15]
14
- # point.values_at(0, 1)
15
- # # => [15, 10]
16
- # point.values_at(0..1)
17
- # # => [15, 10]
18
-
19
- def values_at(*keys)
20
- if keys.all?{|key| key.respond_to?(:to_int) and not key.is_a?(Symbol) }
21
- keys.map{|key| values[key.to_int] }
22
- else
23
- out = []
24
-
25
- keys.each do |key|
26
- case key
27
- when Range
28
- key.each do |r|
29
- out << self[r]
30
- end
31
- else
32
- out << self[key]
33
- end
34
- end
35
-
36
- out
37
- end
38
- end
39
- end
@@ -1,24 +0,0 @@
1
- # Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
2
- # All files in this distribution are subject to the terms of the Ruby license.
3
-
4
- # Extensions for Symbol
5
-
6
- class Symbol
7
- unless method_defined?(:to_proc)
8
-
9
- # Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:
10
- #
11
- # # The same as people.collect { |p| p.name }
12
- # people.collect(&:name)
13
- #
14
- # # The same as people.select { |p| p.manager? }.collect { |p| p.salary }
15
- # people.select(&:manager?).collect(&:salary)
16
- #
17
- # [1, 2, 3].map(&:to_s) # => ['1', '2', '3']
18
- # %w[a b c].map(&:to_sym) # => [:a, :b, :c]
19
-
20
- def to_proc
21
- Proc.new{|*args| args.shift.__send__(self, *args) }
22
- end
23
- end
24
- end
@@ -1,176 +0,0 @@
1
- # Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
2
- # All files in this distribution are subject to the terms of the Ruby license.
3
-
4
- module Ramaze
5
-
6
- # SourceReload provides a way to reload changed files automatically during
7
- # runtime. Its default behaviour in Ramaze is to check periodically for
8
- # files with newer mtime and then attempts to load them in a controlled
9
- # manner.
10
-
11
- class SourceReload
12
-
13
- # Called from Ramaze::startup, just assigns a new instance to
14
- # Global.sourcreloader
15
- def self.startup(options = {})
16
- Thread.main[:sourcereload] = new
17
- end
18
-
19
- def self.restart
20
- Log.dev("Restart SourceReload")
21
- shutdown
22
- startup
23
- end
24
-
25
- # Maybe make this better?
26
- def self.shutdown
27
- new(false)
28
- end
29
-
30
- attr_reader :thread
31
- attr_accessor :interval
32
-
33
- # Setup the @mtimes hash. any new file will be assigned it's last modified
34
- # time (mtime) so we don't reload a file when we see it the first time.
35
- #
36
- # The thread only runs if Global.sourcereload is set.
37
- def initialize(interval = Global.sourcereload)
38
- if sr = Thread.main[:sourcereload]
39
- sr.interval = interval
40
- else
41
- @interval = interval
42
- startup
43
- end
44
- end
45
-
46
- def startup
47
- return unless @interval
48
- Log.dev("Startup SourceReload")
49
-
50
- @mtimes = Hash.new{|h,k| h[k] = mtime(k) }
51
-
52
- @thread = Thread.new{
53
- current = Thread.current
54
- current.priority = -1
55
-
56
- while iv = @interval
57
- rotate
58
- sleep iv
59
- end
60
- }
61
- end
62
-
63
- # One iteration of rotate will look for files that changed since the last
64
- # iteration and will try to #safe_load it.
65
- # This method is quite handy if you want direct control over when your
66
- # code is reloaded.
67
- #
68
- # Usage example:
69
- #
70
- # trap :HUP do
71
- # Ramaze::Log.info "reloading source"
72
- # Thread.main[:sourcereload].rotate
73
- # end
74
- #
75
-
76
- def rotate
77
- before_rotation
78
-
79
- rotation do |file|
80
- mtime = mtime(file)
81
-
82
- if mtime > @mtimes[file]
83
- safe_load(file)
84
- end
85
- end
86
-
87
- after_rotation
88
- end
89
-
90
- # Iterates over the $LOADED_FEATURES ($") and $LOAD_PATH ($:) and tries to
91
- # find either absolute paths or tries to find one by combining paths and files.
92
- # Every found file is yielded to the rotate method.
93
-
94
- def rotation
95
- files = Array[$0, *$LOADED_FEATURES].uniq
96
- paths = Array['./', *$LOAD_PATH].uniq
97
-
98
- files.each do |file|
99
- if Pathname.new(file).absolute?
100
- yield(file) if File.file?(file)
101
- else
102
- paths.each do |path|
103
- full = File.join(path, file)
104
- if File.file?(full)
105
- break yield(full)
106
- end
107
- end
108
- end
109
- end
110
- end
111
-
112
- # Safe mtime
113
- def mtime(file)
114
- File.mtime(file)
115
- rescue Errno::ENOENT
116
- false
117
- end
118
-
119
- # A safe Kernel::load, issuing the hooks depending on the results
120
- def safe_load(file)
121
- before_safe_load(file)
122
- load(file)
123
- after_safe_load_succeed(file)
124
- rescue Object => ex
125
- after_safe_load_failed(file, ex)
126
- ensure
127
- @mtimes[file] = mtime(file)
128
- end
129
- end
130
-
131
- # Holds hooks that are called before and after #reload and #safe_load
132
-
133
- module SourceReloadHooks
134
- # Overwrite to add actions before the reload rotation is started.
135
-
136
- def before_rotation
137
- end
138
-
139
- # Overwrite to add actions after the reload rotation has ended.
140
-
141
- def after_rotation
142
- end
143
-
144
- # Overwrite to add actions before a file is Kernel::load-ed
145
-
146
- def before_safe_load(file)
147
- Log.debug("reload #{file}")
148
- end
149
-
150
- # Overwrite to add actions after a file is Kernel::load-ed successfully,
151
- # by default we clean the Cache for compiled templates and resolved actions.
152
-
153
- def after_safe_load_succeed(file)
154
- Cache.compiled.clear
155
- Cache.resolved.clear
156
- Cache.action_methods.clear
157
- after_safe_load(file)
158
- end
159
-
160
- # Overwrite to add custom hook in addition to default Cache cleaning
161
-
162
- def after_safe_load(file)
163
- end
164
-
165
- # Overwrite to add actions after a file is Kernel::load-ed unsuccessfully,
166
- # by default we output an error-message with the exception.
167
-
168
- def after_safe_load_failed(file, error)
169
- Log.error(error)
170
- end
171
- end
172
-
173
- class SourceReload
174
- include SourceReloadHooks
175
- end
176
- end