autoreload 0.0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY ADDED
@@ -0,0 +1,14 @@
1
+ = RELEASE HISTORY
2
+
3
+ == 0.2.0 2010-05-10
4
+
5
+ * Completely reworked API.
6
+
7
+ == 0.1.0 2010-05-01
8
+
9
+ * Same as original, but now a RubyWorks project.
10
+
11
+ == 0.0.1 2007-07-01
12
+
13
+ * Initial release
14
+
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
@@ -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
@@ -0,0 +1,5 @@
1
+ name : autoreload
2
+ major: 0
3
+ minor: 2
4
+ patch: 0
5
+ date : 2010-05-10
@@ -1,100 +1,9 @@
1
- # Copyright (C) 2003-2007 Kouichirou Eto, All rights reserved.
2
- # License: Ruby License
3
-
4
- require 'thread'
5
-
6
- module AutoReload #:nodoc:
7
- module VERSION #:nodoc:
8
- MAJOR = 0
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
+
@@ -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
- assert_equal 1, foo
31
+ require library
32
+
33
+ assert_equal(1, foo)
33
34
 
34
- sleep 2 # wait is necessary.
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. wait for the autoreload will be started.
40
+ sleep 2 # wait again for the autoreload loop to repeat.
41
41
 
42
42
  # check the number again.
43
- assert_equal 2, foo
43
+ assert_equal(2, foo)
44
44
 
45
- # clean it
45
+ # clean up
46
46
  library.unlink
47
- assert_equal false, library.exist?
47
+ assert_equal(false, library.exist?)
48
48
  end
49
49
 
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
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