autoreload 0.0.1 → 0.2.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.
- data/HISTORY +14 -0
- data/{License.txt → LICENSE} +0 -0
- data/PROFILE +20 -0
- data/README.rdoc +42 -0
- data/VERSION +5 -0
- data/lib/autoreload.rb +8 -99
- data/lib/autoreload/lookup.rb +90 -0
- data/lib/autoreload/reloader.rb +140 -0
- data/test/test_autoreload.rb +21 -21
- metadata +63 -60
- data/Changes.txt +0 -48
- data/History.txt +0 -4
- data/Manifest.txt +0 -21
- data/README.txt +0 -5
- data/Rakefile +0 -80
- data/default_task.rb +0 -129
- data/examples/foo.rb +0 -6
- data/examples/sample1.rb +0 -13
- data/scripts/lib-txt2html.rb +0 -133
- data/scripts/makemanifest.rb +0 -20
- data/scripts/txt2html +0 -10
- data/setup.rb +0 -1585
- data/website/index.html +0 -113
- data/website/index.txt +0 -54
- data/website/javascripts/rounded_corners_lite.inc.js +0 -285
- data/website/stylesheets/screen.css +0 -138
- data/website/template.rhtml +0 -48
data/HISTORY
ADDED
data/{License.txt → LICENSE}
RENAMED
File without changes
|
data/PROFILE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
---
|
2
|
+
title : Autoreload
|
3
|
+
summary: Automatically reload library files
|
4
|
+
license: MIT
|
5
|
+
contact: rubyworks-mailinglist@googlegroups.com
|
6
|
+
suite : rubyworks
|
7
|
+
created: 2007-07-01
|
8
|
+
|
9
|
+
authors:
|
10
|
+
- Kouichirou Eto
|
11
|
+
- Thomas Sawyer
|
12
|
+
|
13
|
+
description:
|
14
|
+
Autoreload automatically reloads library files when they have been
|
15
|
+
updated. It is especailly useful when testing stateless services
|
16
|
+
such as web applications.
|
17
|
+
|
18
|
+
resources:
|
19
|
+
homepage : http://rubyworks.github.com/autoreload
|
20
|
+
repository: http://github.com/rubyworks/autoreload
|
data/README.rdoc
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
= Autoreload
|
2
|
+
|
3
|
+
* home: http://rubyworks.github.com/autoreload
|
4
|
+
* work: http://github.com/rubyworks/autoreload
|
5
|
+
|
6
|
+
|
7
|
+
== DESCRIPTION
|
8
|
+
|
9
|
+
Autoreload automatically reloads library files when they have been
|
10
|
+
updated. It is especailly useful when testing stateless services
|
11
|
+
such as web applications.
|
12
|
+
|
13
|
+
|
14
|
+
== HOW TO USE
|
15
|
+
|
16
|
+
Say we have a library <tt>foo.rb</tt> in our load path:
|
17
|
+
|
18
|
+
def foo
|
19
|
+
1
|
20
|
+
end
|
21
|
+
|
22
|
+
We can then run the following script, <tt>example.rb</tt>:
|
23
|
+
|
24
|
+
require 'autoreload'
|
25
|
+
require 'foo'
|
26
|
+
|
27
|
+
autoreload('foo.rb', :interval=>2, :verbose=>true)
|
28
|
+
|
29
|
+
loop {
|
30
|
+
puts foo
|
31
|
+
sleep 2
|
32
|
+
}
|
33
|
+
|
34
|
+
With that running we can change <tt>foo.rb</tt> and the change will take
|
35
|
+
effect in <tt>example.rb</tt> within two seconds of being made.
|
36
|
+
|
37
|
+
|
38
|
+
== COPYRIGHT
|
39
|
+
|
40
|
+
Copyright (c) 2007 Kouichirou Eto
|
41
|
+
|
42
|
+
Copyright (c) 2010 Thomas Sawyer
|
data/VERSION
ADDED
data/lib/autoreload.rb
CHANGED
@@ -1,100 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
MINOR = 0
|
10
|
-
TINY = 1
|
11
|
-
STRING = [MAJOR, MINOR, TINY].join('.')
|
12
|
-
end
|
13
|
-
|
14
|
-
class Reloader
|
15
|
-
def self.start(*a)
|
16
|
-
self.new(*a).start
|
17
|
-
end
|
18
|
-
|
19
|
-
DEFAULT_INTERVAL = 1
|
20
|
-
|
21
|
-
def initialize(interval = DEFAULT_INTERVAL,
|
22
|
-
verbose = false, name = nil) #:nodoc:
|
23
|
-
@interval = interval
|
24
|
-
@verbose = verbose
|
25
|
-
@name = name
|
26
|
-
@status = {}
|
27
|
-
@thread = nil
|
28
|
-
end
|
29
|
-
|
30
|
-
def start #:nodoc:
|
31
|
-
@thread = Thread.new {
|
32
|
-
loop {
|
33
|
-
begin
|
34
|
-
update
|
35
|
-
rescue Exception
|
36
|
-
warn 'update failed: ' + $!
|
37
|
-
end
|
38
|
-
sleep @interval
|
39
|
-
}
|
40
|
-
}
|
41
|
-
@thread.abort_on_exception = true
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def warn(msg, out = $stderr)
|
47
|
-
msg = "#{@name}: #{msg}" if @name
|
48
|
-
out << msg + "\n"
|
49
|
-
# $stderr.puts()
|
50
|
-
end
|
51
|
-
|
52
|
-
def update
|
53
|
-
libs = [$0] + $"
|
54
|
-
libs.each {|lib|
|
55
|
-
check_lib(lib)
|
56
|
-
}
|
57
|
-
end
|
58
|
-
|
59
|
-
def check_lib(lib)
|
60
|
-
if @status[lib]
|
61
|
-
file, mtime = @status[lib]
|
62
|
-
return if ! FileTest.exist?(file) # file is disappered.
|
63
|
-
curtime = File.mtime(file).to_i
|
64
|
-
if mtime < curtime
|
65
|
-
if @verbose
|
66
|
-
warn "reload: '#{file}'"
|
67
|
-
end
|
68
|
-
load file # Load it.
|
69
|
-
@status[lib] = [file, curtime]
|
70
|
-
end
|
71
|
-
return
|
72
|
-
end
|
73
|
-
|
74
|
-
check_path = [''] + $LOAD_PATH
|
75
|
-
#check_path = ['']
|
76
|
-
check_path.each {|path|
|
77
|
-
file = File.join(path, lib)
|
78
|
-
file = lib if path.empty? # Check if the lib is a filename.
|
79
|
-
if FileTest.exist?(file)
|
80
|
-
@status[lib] = [file, File.mtime(file).to_i]
|
81
|
-
return
|
82
|
-
end
|
83
|
-
}
|
84
|
-
|
85
|
-
#raise "The library '#{lib}' is not found."
|
86
|
-
# $stdout.puts(message("The library '#{lib}' is not found.")) if @verbose
|
87
|
-
end
|
88
|
-
|
89
|
-
def get_status(file)
|
90
|
-
if FileTest.exist?(file)
|
91
|
-
return [file, File.mtime(file).to_i]
|
92
|
-
end
|
93
|
-
return nil
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def autoreload(*a)
|
99
|
-
AutoReload::Reloader.start(*a)
|
1
|
+
require 'autoreload/reloader'
|
2
|
+
|
3
|
+
module AutoReload
|
4
|
+
# TODO: version constant
|
5
|
+
end
|
6
|
+
|
7
|
+
def autoreload(*files)
|
8
|
+
AutoReload::Reloader.start(*files)
|
100
9
|
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module AutoReload
|
2
|
+
|
3
|
+
# = Library Lookup
|
4
|
+
#
|
5
|
+
# This library is a slightly modified copy of the +plugin+ library.
|
6
|
+
#
|
7
|
+
module Lookup
|
8
|
+
|
9
|
+
extend self
|
10
|
+
|
11
|
+
# Find plugins, searching through standard $LOAD_PATH,
|
12
|
+
# Roll Libraries and RubyGems.
|
13
|
+
#
|
14
|
+
# Provide a +match+ file glob to find plugins.
|
15
|
+
#
|
16
|
+
# Lookup.find('syckle/*')
|
17
|
+
#
|
18
|
+
def find(match, options={})
|
19
|
+
plugins = []
|
20
|
+
plugins.concat find_roll(match, options)
|
21
|
+
plugins.concat find_loadpath(match, options)
|
22
|
+
plugins.concat find_gems(match, options)
|
23
|
+
plugins.uniq
|
24
|
+
end
|
25
|
+
|
26
|
+
# Shortcut for #find.
|
27
|
+
#
|
28
|
+
# Lookup['syckle/*']
|
29
|
+
#
|
30
|
+
alias_method :[], :find
|
31
|
+
|
32
|
+
# Search roll for current or latest libraries.
|
33
|
+
def find_roll(match, options={})
|
34
|
+
plugins = []
|
35
|
+
#directory = options[:directory] || DIRECTORY
|
36
|
+
if defined?(::Roll)
|
37
|
+
::Roll::Library.ledger.each do |name, lib|
|
38
|
+
lib = lib.sort.first if Array===lib
|
39
|
+
lib.loadpath.each do |path|
|
40
|
+
#find = File.join(lib.location, path, directory, match)
|
41
|
+
find = File.join(lib.location, path, match)
|
42
|
+
list = Dir.glob(find)
|
43
|
+
list = list.map{ |d| d.chomp('/') }
|
44
|
+
plugins.concat(list)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
plugins
|
49
|
+
end
|
50
|
+
|
51
|
+
# Search standard $LOAD_PATH.
|
52
|
+
#
|
53
|
+
# Activated gem versions are in here too.
|
54
|
+
|
55
|
+
def find_loadpath(match, options={})
|
56
|
+
plugins = []
|
57
|
+
#directory = options[:directory] || DIRECTORY
|
58
|
+
$LOAD_PATH.uniq.each do |path|
|
59
|
+
path = File.expand_path(path)
|
60
|
+
#list = Dir.glob(File.join(path, directory, match))
|
61
|
+
list = Dir.glob(File.join(path, match))
|
62
|
+
list = list.map{ |d| d.chomp('/') }
|
63
|
+
plugins.concat(list)
|
64
|
+
end
|
65
|
+
plugins
|
66
|
+
end
|
67
|
+
|
68
|
+
# Search latest gem versions.
|
69
|
+
#
|
70
|
+
# TODO: Is there anyway to skip active gems?
|
71
|
+
|
72
|
+
def find_gems(match, options={})
|
73
|
+
plugins = []
|
74
|
+
#directory = options[:directory] || DIRECTORY
|
75
|
+
if defined?(::Gem)
|
76
|
+
::Gem.latest_load_paths do |path|
|
77
|
+
#list = Dir.glob(File.join(path, directory, match))
|
78
|
+
list = Dir.glob(File.join(path, match))
|
79
|
+
list = list.map{ |d| d.chomp('/') }
|
80
|
+
plugins.concat(list)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
plugins
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
# Copyright (C) 2010 Thomas Sawyer
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'autoreload/lookup'
|
3
|
+
|
4
|
+
module AutoReload
|
5
|
+
|
6
|
+
# Reload class does all the heavy lifting
|
7
|
+
# for AutoReload library.
|
8
|
+
#
|
9
|
+
class Reloader
|
10
|
+
|
11
|
+
# Shortcut for Reloader.new(*args).start.
|
12
|
+
def self.start(*args)
|
13
|
+
self.new(*args).start
|
14
|
+
end
|
15
|
+
|
16
|
+
# Default interval is one second.
|
17
|
+
DEFAULT_INTERVAL = 1
|
18
|
+
|
19
|
+
# New Reloader.
|
20
|
+
#
|
21
|
+
# === Options
|
22
|
+
#
|
23
|
+
# :interval - seconds betwee updates
|
24
|
+
# :verbose - true provides reload warning
|
25
|
+
# :reprime - include $0 in reload list
|
26
|
+
#
|
27
|
+
def initialize(*files)
|
28
|
+
options = Hash===files.last ? files.pop : {}
|
29
|
+
|
30
|
+
@files = files.map{ |file| file.to_s } #Dir.glob(file) }.flatten.compact
|
31
|
+
|
32
|
+
@interval = options[:interval] || DEFAULT_INTERVAL
|
33
|
+
@verbose = options[:verbose]
|
34
|
+
@reprime = options[:reprime]
|
35
|
+
|
36
|
+
@status = {}
|
37
|
+
end
|
38
|
+
|
39
|
+
# Start the reload thread.
|
40
|
+
def start
|
41
|
+
update # primate the path loads
|
42
|
+
@thread = Thread.new do
|
43
|
+
loop do
|
44
|
+
begin
|
45
|
+
update
|
46
|
+
rescue Exception
|
47
|
+
warn 'update failed: ' + $!
|
48
|
+
end
|
49
|
+
sleep @interval
|
50
|
+
end
|
51
|
+
end
|
52
|
+
@thread.abort_on_exception = true
|
53
|
+
end
|
54
|
+
|
55
|
+
# Kills the autoreload thread.
|
56
|
+
def stop
|
57
|
+
@thread.kill if @thread
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
attr :thread
|
62
|
+
|
63
|
+
# List of files provided to autoreload.
|
64
|
+
attr :files
|
65
|
+
|
66
|
+
# Status hash, used to track reloads.
|
67
|
+
attr :status
|
68
|
+
|
69
|
+
# The periodic interval of reload.
|
70
|
+
attr :interval
|
71
|
+
|
72
|
+
# Provide warning on reload.
|
73
|
+
def verbose?
|
74
|
+
@verbose || $VERBOSE
|
75
|
+
end
|
76
|
+
|
77
|
+
# Is $0 in the reload list?
|
78
|
+
def reprime?
|
79
|
+
@reprime
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
# List of library files to autoreload.
|
85
|
+
#--
|
86
|
+
# ISSUE: Why include $0 ?
|
87
|
+
#--
|
88
|
+
def libraries
|
89
|
+
if @files.empty?
|
90
|
+
@reprime ? [$0] + $" : $"
|
91
|
+
else
|
92
|
+
@files
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Iterate through all selection library files and reload if needed.
|
97
|
+
def update
|
98
|
+
libraries.each{ |lib| check(lib) }
|
99
|
+
end
|
100
|
+
|
101
|
+
# Check status and reload if out-of-date.
|
102
|
+
def check(lib)
|
103
|
+
if @status.key?(lib)
|
104
|
+
file, mtime = @status[lib]
|
105
|
+
|
106
|
+
return unless file # file never was
|
107
|
+
return unless FileTest.exist?(file) # file has disappered
|
108
|
+
|
109
|
+
curtime = File.mtime(file).to_i
|
110
|
+
|
111
|
+
if mtime < curtime
|
112
|
+
warn "reload: '#{file}'" if verbose?
|
113
|
+
load file
|
114
|
+
@status[lib] = [file, curtime]
|
115
|
+
end
|
116
|
+
else
|
117
|
+
@status[lib] = get_status(lib)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Get library file status.
|
122
|
+
def get_status(lib)
|
123
|
+
file = Lookup.find(lib).first
|
124
|
+
if file #FileTest.exist?(file)
|
125
|
+
[file, File.mtime(file).to_i]
|
126
|
+
else
|
127
|
+
warn "reload fail: library '#{lib}' not found" if verbose?
|
128
|
+
#raise "The library '#{lib}' is not found."
|
129
|
+
#$stdout.puts(message("The library '#{lib}' is not found.")) if @verbose
|
130
|
+
[nil, nil]
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
# Copyright (C) 2003,2007 Kouichirou Eto
|
139
|
+
# Copyright (C) 2010 Thomas Sawyer
|
140
|
+
|
data/test/test_autoreload.rb
CHANGED
@@ -17,43 +17,43 @@ module AutoReload
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
class TestAutoReload < Test::Unit::TestCase
|
21
|
-
def test_autoreload
|
22
|
-
#autoreload(1, true, 'test_autoreload')
|
23
|
-
autoreload(1)
|
20
|
+
class TestAutoReload < Test::Unit::TestCase
|
24
21
|
|
22
|
+
def test_autoreload
|
25
23
|
# create a library
|
26
24
|
dir = Pathname.new(__FILE__).dirname
|
27
25
|
library = dir + 'tmp_library.rb'
|
28
26
|
library.write 'def foo; 1; end'
|
27
|
+
|
28
|
+
autoreload(library, :interval => 1) #, :verbose=>true)
|
29
29
|
|
30
30
|
# require it
|
31
|
-
require library
|
32
|
-
|
31
|
+
require library
|
32
|
+
|
33
|
+
assert_equal(1, foo)
|
33
34
|
|
34
|
-
sleep 2 # wait is
|
35
|
-
# If not, the time stamp will be same with the next file.
|
35
|
+
sleep 2 # wait is needed for time stamp to not be same with the next file.
|
36
36
|
|
37
37
|
# recreate the file
|
38
38
|
library.write 'def foo; 2; end'
|
39
39
|
|
40
|
-
sleep 2 # wait again
|
40
|
+
sleep 2 # wait again for the autoreload loop to repeat.
|
41
41
|
|
42
42
|
# check the number again.
|
43
|
-
assert_equal
|
43
|
+
assert_equal(2, foo)
|
44
44
|
|
45
|
-
# clean
|
45
|
+
# clean up
|
46
46
|
library.unlink
|
47
|
-
assert_equal
|
47
|
+
assert_equal(false, library.exist?)
|
48
48
|
end
|
49
49
|
|
50
|
-
|
51
|
-
def test_all
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
50
|
+
## ruby -w -Ilib test/test_autoreload.rb -n test_all
|
51
|
+
#def test_all
|
52
|
+
# rel = AutoReload::Reloader.new
|
53
|
+
#
|
54
|
+
# # test_warn
|
55
|
+
# str = ''
|
56
|
+
# rel.warn("a", str)
|
57
|
+
# assert_equal "a\n", str
|
58
|
+
#end
|
59
59
|
end
|