ramaze 2008.06 → 2008.11
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.
- data/README.markdown +6 -6
- data/Rakefile +33 -3
- data/bin/ramaze +18 -0
- data/doc/CHANGELOG +960 -0
- data/doc/LEGAL +5 -1
- data/doc/meta/announcement.txt +20 -36
- data/doc/tutorial/todolist.html +421 -313
- data/doc/tutorial/todolist.mkd +33 -16
- data/examples/app/blog/spec/blog.rb +3 -3
- data/examples/app/rapaste/controller/paste.rb +8 -1
- data/examples/app/rapaste/model/paste.rb +3 -0
- data/examples/app/rapaste/spec/rapaste.rb +3 -1
- data/examples/app/rapaste/start.rb +3 -2
- data/examples/app/sourceview/public/sourceview.js +2 -2
- data/examples/app/todolist/spec/todolist.rb +6 -6
- data/examples/app/todolist/template/index.xhtml +1 -1
- data/examples/app/whywiki/spec/whywiki.rb +2 -2
- data/examples/app/wikore/spec/wikore.rb +2 -2
- data/examples/app/wikore/src/model.rb +4 -3
- data/examples/app/wiktacular/spec/wiktacular.rb +7 -7
- data/examples/basic/simple.rb +2 -2
- data/examples/helpers/paginate.rb +71 -0
- data/examples/misc/simple_auth.rb +20 -8
- data/lib/proto/controller/init.rb +10 -0
- data/lib/proto/controller/main.rb +1 -3
- data/lib/proto/model/init.rb +4 -0
- data/lib/proto/public/dispatch.fcgi +1 -1
- data/lib/proto/spec/main.rb +2 -1
- data/lib/proto/start.rb +3 -3
- data/lib/proto/start.ru +1 -1
- data/lib/proto/view/error.xhtml +4 -4
- data/lib/ramaze.rb +8 -3
- data/lib/ramaze/action.rb +6 -6
- data/lib/ramaze/adapter.rb +1 -6
- data/lib/ramaze/adapter/base.rb +30 -27
- data/lib/ramaze/adapter/cgi.rb +1 -0
- data/lib/ramaze/cache.rb +1 -3
- data/lib/ramaze/cache/memcached.rb +3 -5
- data/lib/ramaze/contrib/auto_params.rb +2 -2
- data/lib/ramaze/contrib/auto_params/get_args.rb +2 -1
- data/lib/ramaze/contrib/gems.rb +17 -18
- data/lib/ramaze/contrib/gzip_filter.rb +22 -9
- data/lib/ramaze/contrib/maruku_uv.rb +59 -0
- data/lib/ramaze/contrib/profiling.rb +1 -1
- data/lib/ramaze/contrib/rest.rb +16 -13
- data/lib/ramaze/contrib/sequel/create_join.rb +25 -0
- data/lib/ramaze/contrib/sequel/form_field.rb +129 -0
- data/lib/ramaze/contrib/sequel/image.rb +198 -0
- data/lib/ramaze/contrib/sequel/relation.rb +82 -0
- data/lib/ramaze/controller.rb +33 -34
- data/lib/ramaze/controller/resolve.rb +29 -9
- data/lib/ramaze/current.rb +60 -20
- data/lib/ramaze/current/request.rb +8 -7
- data/lib/ramaze/current/response.rb +15 -3
- data/lib/ramaze/current/session/flash.rb +8 -0
- data/lib/ramaze/dispatcher.rb +17 -9
- data/lib/ramaze/dispatcher/action.rb +4 -5
- data/lib/ramaze/dispatcher/directory.rb +1 -1
- data/lib/ramaze/dispatcher/error.rb +4 -4
- data/lib/ramaze/dispatcher/file.rb +4 -4
- data/lib/ramaze/gestalt.rb +15 -20
- data/lib/ramaze/helper/cgi.rb +7 -15
- data/lib/ramaze/helper/formatting.rb +41 -1
- data/lib/ramaze/helper/httpdigest.rb +20 -7
- data/lib/ramaze/helper/link.rb +4 -6
- data/lib/ramaze/helper/paginate.rb +233 -0
- data/lib/ramaze/helper/redirect.rb +1 -1
- data/lib/ramaze/helper/rest.rb +1 -1
- data/lib/ramaze/helper/thread.rb +17 -0
- data/lib/ramaze/helper/ultraviolet.rb +44 -0
- data/lib/ramaze/helper/user.rb +4 -9
- data/lib/ramaze/log.rb +2 -2
- data/lib/ramaze/log/analogger.rb +21 -23
- data/lib/ramaze/log/growl.rb +21 -23
- data/lib/ramaze/log/hub.rb +1 -1
- data/lib/ramaze/log/informer.rb +97 -99
- data/lib/ramaze/log/knotify.rb +14 -16
- data/lib/ramaze/log/logger.rb +11 -13
- data/lib/ramaze/log/logging.rb +61 -63
- data/lib/ramaze/log/rotatinginformer.rb +168 -0
- data/lib/ramaze/log/syslog.rb +41 -31
- data/lib/ramaze/log/xosd.rb +70 -72
- data/lib/ramaze/option.rb +9 -6
- data/lib/ramaze/option/holder.rb +5 -27
- data/lib/ramaze/reloader.rb +186 -0
- data/lib/ramaze/setup.rb +1 -1
- data/lib/ramaze/snippets.rb +13 -0
- data/lib/ramaze/snippets/array/put_within.rb +31 -24
- data/lib/ramaze/snippets/binding/locals.rb +23 -11
- data/lib/ramaze/snippets/dictionary.rb +2 -2
- data/lib/ramaze/snippets/fiber.rb +63 -0
- data/lib/ramaze/snippets/kernel/constant.rb +36 -21
- data/lib/ramaze/snippets/kernel/pretty_inspect.rb +12 -6
- data/lib/ramaze/snippets/numeric/filesize_format.rb +24 -17
- data/lib/ramaze/snippets/numeric/time.rb +63 -0
- data/lib/ramaze/snippets/object/__dir__.rb +29 -0
- data/lib/ramaze/snippets/object/acquire.rb +40 -0
- data/lib/ramaze/snippets/object/instance_variable_defined.rb +16 -5
- data/lib/ramaze/snippets/object/pretty.rb +14 -4
- data/lib/ramaze/snippets/object/scope.rb +14 -7
- data/lib/ramaze/snippets/ordered_set.rb +25 -14
- data/lib/ramaze/snippets/proc/locals.rb +17 -9
- data/lib/ramaze/snippets/ramaze/deprecated.rb +13 -0
- data/lib/ramaze/snippets/ramaze/fiber.rb +24 -0
- data/lib/ramaze/snippets/ramaze/state.rb +86 -0
- data/lib/ramaze/snippets/ramaze/struct.rb +45 -0
- data/lib/ramaze/snippets/string/camel_case.rb +13 -8
- data/lib/ramaze/snippets/string/color.rb +24 -20
- data/lib/ramaze/snippets/string/each.rb +14 -3
- data/lib/ramaze/snippets/string/end_with.rb +20 -0
- data/lib/ramaze/snippets/string/esc.rb +26 -21
- data/lib/ramaze/snippets/string/ord.rb +12 -6
- data/lib/ramaze/snippets/string/snake_case.rb +13 -7
- data/lib/ramaze/snippets/string/start_with.rb +16 -5
- data/lib/ramaze/snippets/string/unindent.rb +23 -15
- data/lib/ramaze/snippets/thread/into.rb +3 -3
- data/lib/ramaze/spec/helper/bacon.rb +5 -5
- data/lib/ramaze/spec/helper/mock_http.rb +1 -1
- data/lib/ramaze/spec/helper/pretty_output.rb +2 -2
- data/lib/ramaze/spec/helper/snippets.rb +8 -0
- data/lib/ramaze/template.rb +4 -1
- data/lib/ramaze/template/ezamar/textpow.syntax +34 -0
- data/lib/ramaze/template/maruku.rb +34 -0
- data/lib/ramaze/template/tagz.rb +2 -2
- data/lib/ramaze/template/xslt.rb +2 -2
- data/lib/ramaze/tool/create.rb +27 -53
- data/lib/ramaze/tool/localize.rb +8 -4
- data/lib/ramaze/tool/mime.rb +11 -1
- data/lib/ramaze/tool/project_creator.rb +110 -0
- data/lib/ramaze/trinity.rb +4 -1
- data/lib/ramaze/version.rb +1 -1
- data/lib/vendor/bacon.rb +323 -0
- data/rake_tasks/gem.rake +10 -1
- data/rake_tasks/maintenance.rake +40 -2
- data/rake_tasks/metric.rake +24 -0
- data/rake_tasks/release.rake +17 -4
- data/rake_tasks/spec.rake +1 -2
- data/ramaze.gemspec +549 -495
- data/spec/contrib/auto_params.rb +3 -3
- data/spec/contrib/profiling.rb +2 -2
- data/spec/examples/simple_auth.rb +2 -2
- data/spec/examples/templates/template_haml.rb +0 -2
- data/spec/ramaze/action/file_cache.rb +22 -0
- data/spec/ramaze/adapter.rb +2 -2
- data/spec/ramaze/controller/actionless_templates.rb +1 -1
- data/spec/ramaze/controller/subclass.rb +15 -0
- data/spec/ramaze/controller/template_resolving.rb +1 -1
- data/spec/ramaze/controller/view/bar.xhtml +1 -0
- data/spec/ramaze/controller/view/base/another.xhtml +1 -0
- data/spec/ramaze/current/session.rb +1 -1
- data/spec/ramaze/dispatcher/file.rb +2 -2
- data/spec/ramaze/helper/aspect.rb +26 -17
- data/spec/ramaze/helper/formatting.rb +13 -0
- data/spec/ramaze/log/informer.rb +10 -10
- data/spec/ramaze/log/syslog.rb +67 -4
- data/spec/ramaze/rewrite.rb +1 -1
- data/spec/ramaze/route.rb +1 -1
- data/spec/ramaze/struct.rb +47 -0
- data/spec/ramaze/template/markaby.rb +1 -1
- data/spec/ramaze/template/tagz.rb +1 -1
- data/spec/snippets/binding/locals.rb +9 -0
- data/spec/snippets/numeric/time.rb +12 -0
- data/spec/snippets/{kernel → object}/__dir__.rb +0 -0
- data/spec/snippets/{kernel → object}/acquire.rb +0 -0
- metadata +90 -81
- data/cache.yaml +0 -7
- data/examples/app/rammit/spec/rammit.rb +0 -31
- data/examples/app/rammit/src/controller/main.rb +0 -3
- data/examples/app/rammit/src/controller/page.rb +0 -16
- data/examples/app/rammit/src/model.rb +0 -33
- data/examples/app/rammit/start.rb +0 -8
- data/examples/app/rammit/template/index.xhtml +0 -14
- data/examples/app/rammit/template/page/view.xhtml +0 -4
- data/lib/ramaze/snippets/kernel/__dir__.rb +0 -23
- data/lib/ramaze/snippets/kernel/acquire.rb +0 -34
- data/lib/ramaze/snippets/object/thread_accessor.rb +0 -5
- data/lib/ramaze/snippets/ramaze/thread_accessor.rb +0 -58
- data/lib/ramaze/snippets/struct/fill.rb +0 -23
- data/lib/ramaze/snippets/struct/values_at.rb +0 -39
- data/lib/ramaze/snippets/symbol/to_proc.rb +0 -24
- data/lib/ramaze/sourcereload.rb +0 -176
- data/spec/snippets/struct/fill.rb +0 -26
- data/spec/snippets/struct/values_at.rb +0 -52
- data/spec/snippets/symbol/to_proc.rb +0 -13
data/cache.yaml
DELETED
@@ -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,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,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,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,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
|
data/lib/ramaze/sourcereload.rb
DELETED
@@ -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
|