autoreload 0.3.1 → 1.0.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.
@@ -1,23 +1,63 @@
1
1
  = RELEASE HISTORY
2
2
 
3
+ == 1.0.0 (2011-07-15)
4
+
5
+ This release overhauls the API. The #autoreload method now
6
+ takes a block. All libraries required within this block
7
+ will be autoreloaded. The old API will raise an error!!!
8
+ This was done to simplify the overaul design of the library
9
+ and consequently make it much more efficient, but also to
10
+ fix a rather nasty bug that prevented scripts required by
11
+ other scripts that were to be autoreloaded from autoreloading
12
+ as well.
13
+
14
+ The new design rely's solely on $LOADED_FEATURES, rather than
15
+ looking up files on the $LOAD_PATH itself. This has an important
16
+ consequence for Ruby 1.8 or older. Becuase older version of Ruby
17
+ do not put the expanded path in $LOADED_FEATURES, autoreloading
18
+ occurs regardless of whether the file has changed or not. On
19
+ Ruby 1.9+ however, where the full path is available, the file will
20
+ only be reloaded if it has changed, it does this by checking the
21
+ mtime of the file.
22
+
23
+ Changes:
24
+
25
+ * Overhaul API to use block form.
26
+ * Remove Lookup module (no longer needed).
27
+ * Fix require of require issue.
28
+
29
+
30
+ == 0.3.1 (2011-05-15)
31
+
32
+ This release simply fixes licensing issues. Autoreload is licensed
33
+ under the GPL v3.
34
+
3
35
 
4
36
  == 0.3.0 (2010-10-14)
5
37
 
38
+ Changes:
39
+
6
40
  * Fix issue with looking up Roller libraries.
7
41
  * Switch testing framework to RSpec2.
8
42
 
9
43
 
10
44
  == 0.2.0 (2010-05-10)
11
45
 
46
+ Changes:
47
+
12
48
  * Completely reworked API.
13
49
 
14
50
 
15
51
  == 0.1.0 (2010-05-01)
16
52
 
53
+ Changes:
54
+
17
55
  * Same as original, but now a RubyWorks project.
18
56
 
19
57
 
20
58
  == 0.0.1 (2007-07-01)
21
59
 
60
+ Changes:
61
+
22
62
  * Initial release
23
63
 
@@ -0,0 +1,14 @@
1
+ #!mast .ruby .yardopts bin lib spec try [A-Z][A-Z]*
2
+ .ruby
3
+ .yardopts
4
+ lib/autoreload/reloader.rb
5
+ lib/autoreload/version.rb
6
+ lib/autoreload.rb
7
+ spec/autoreload_spec.rb
8
+ try/changeme.rb
9
+ try/start.rb
10
+ HISTORY.rdoc
11
+ PROFILE
12
+ README.rdoc
13
+ VERSION
14
+ COPYING.rdoc
data/PROFILE ADDED
@@ -0,0 +1,28 @@
1
+ ---
2
+ title : AutoReload
3
+ summary: Automatically reload library files
4
+
5
+ requirements:
6
+ - detroit (build)
7
+ - minitest (test)
8
+
9
+ authors:
10
+ - Thomas Sawyer <transfire@gmail.com>
11
+ - Kouichirou Eto
12
+
13
+ description:
14
+ Autoreload automatically reloads library files when they have been
15
+ updated. It is especially useful when testing stateless services
16
+ such as web applications.
17
+
18
+ resources:
19
+ home: http://rubyworks.github.com/autoreload
20
+ code: http://github.com/rubyworks/autoreload
21
+ gem: http://rubygems.org/gems/autoreload
22
+
23
+ created: 2007-07-01
24
+
25
+ copyrights:
26
+ - 2010 Thomas Sawyer (BSD-2)
27
+ - 2003 Kouichiro Eto (RUBY)
28
+
@@ -1,19 +1,26 @@
1
- = Autoreload
1
+ = AutoReload
2
2
 
3
- == DESCRIPTION
4
3
 
5
- Autoreload automatically reloads library files when they have been
6
- updated. It is especailly useful when testing stateless services
7
- such as web applications.
4
+ == Description
8
5
 
6
+ Autoreload automatically reloads library files after they
7
+ have been updated. It is especailly useful when testing
8
+ stateless services such as web applications.
9
9
 
10
- == RESOURCES
10
+ IMPORTANT! Version 1.0+ has a new API. It also works best
11
+ under Ruby 1.9 or above. Under Ruby 1.8 or older files are
12
+ reloaded regardless of whether they actually have changed
13
+ since the last load. Whereas in Ruby 1.9+, they only reload
14
+ if the mtime on the file is newer than the previous time.
11
15
 
12
- * home: http://rubyworks.github.com/autoreload
13
- * work: http://github.com/rubyworks/autoreload
14
16
 
17
+ == Resources
15
18
 
16
- == HOW TO USE
19
+ * {Homepage}[http://rubyworks.github.com/autoreload]
20
+ * {Source Code}[http://github.com/rubyworks/autoreload]
21
+
22
+
23
+ == Synopsis
17
24
 
18
25
  Say we have a library <tt>foo.rb</tt> in our load path:
19
26
 
@@ -24,24 +31,31 @@ Say we have a library <tt>foo.rb</tt> in our load path:
24
31
  We can then run the following script, <tt>example.rb</tt>:
25
32
 
26
33
  require 'autoreload'
27
- require 'foo'
28
34
 
29
- autoreload('foo.rb', :interval=>2, :verbose=>true)
35
+ autoreload(:interval=>2, :verbose=>true) do
36
+ require 'foo.rb'
37
+ end
30
38
 
31
39
  loop {
32
40
  puts foo
33
41
  sleep 2
34
42
  }
35
43
 
36
- With that running we can change <tt>foo.rb</tt> and the change will take
37
- effect in <tt>example.rb</tt> within two seconds of being made.
44
+ With that running we can change <tt>foo.rb</tt> and the change
45
+ will take effect in <tt>example.rb</tt> within two seconds of
46
+ being made.
47
+
48
+ Note, that autoreload only works with _required_ files. It cannot
49
+ monitor files that are broght in with _load_. This is because
50
+ $LOADED_FEATURES is used to track which files are monitored.
51
+
38
52
 
53
+ == Copyrights
39
54
 
40
- == COPYRIGHT
55
+ Copyright (c) 2003,2007 Kouichirou Eto
41
56
 
42
- (GPL v3 License)
57
+ Copyright (c) 2010 Thomas Sawyer
43
58
 
44
- * Copyright (c) 2007 Kouichirou Eto
45
- * Copyright (c) 2010 Thomas Sawyer
59
+ BSD 2-Clause License
46
60
 
47
61
  See COPYING.rdoc for more information.
@@ -0,0 +1,9 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << "lib"
5
+ t.libs << "tmp"
6
+ t.test_files = FileList['spec/*_spec.rb']
7
+ t.verbose = false
8
+ end
9
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,143 @@
1
+ # encoding: utf-8
2
+
3
+ require 'yaml'
4
+
5
+ Gem::Specification.new do |gemspec|
6
+
7
+ manifest = Dir.glob('manifest{,.txt)', File::FNM_CASEFOLD).first
8
+
9
+ scm = case
10
+ when File.directory?('.git')
11
+ :git
12
+ end
13
+
14
+ files = case
15
+ when manifest
16
+ File.readlines(manifest).
17
+ map{ |line| line.srtip }.
18
+ reject{ |line| line.empty? || line[0,1] == '#' }
19
+ when scm == :git
20
+ `git ls-files -z`.split("\0")
21
+ else
22
+ Dir.glob('{**/}{.*,*}') # TODO: be more specific using standard locations ?
23
+ end.select{ |path| File.file?(path) }
24
+
25
+ patterns = {
26
+ :bin_files => 'bin/*',
27
+ :lib_files => 'lib/{**/}*.rb',
28
+ :ext_files => 'ext/{**/}extconf.rb',
29
+ :doc_files => '*.{txt,rdoc,md,markdown,tt,textile}',
30
+ :test_files => '{test/{**/}*_test.rb,spec/{**/}*_spec.rb}'
31
+ }
32
+
33
+ glob_files = lambda { |pattern|
34
+ Dir.glob(pattern).select { |path|
35
+ File.file?(path) && files.include?(path)
36
+ }
37
+ }
38
+
39
+ #files = glob_files[patterns[:files]]
40
+
41
+ executables = glob_files[patterns[:bin_files]].map do |path|
42
+ File.basename(path)
43
+ end
44
+
45
+ extensions = glob_files[patterns[:ext_files]].map do |path|
46
+ File.basename(path)
47
+ end
48
+
49
+ metadata = YAML.load_file('.ruby')
50
+
51
+ # build-out the gemspec
52
+
53
+ case metadata['revision']
54
+ when 0
55
+ gemspec.name = metadata['name']
56
+ gemspec.version = metadata['version']
57
+ gemspec.summary = metadata['summary']
58
+ gemspec.description = metadata['description']
59
+
60
+ metadata['authors'].each do |author|
61
+ gemspec.authors << author['name']
62
+
63
+ if author.has_key?('email')
64
+ if gemspec.email
65
+ gemspec.email << author['email']
66
+ else
67
+ gemspec.email = [author['email']]
68
+ end
69
+ end
70
+ end
71
+
72
+ gemspec.licenses = metadata['licenses']
73
+
74
+ metadata['requirements'].each do |req|
75
+ name = req['name']
76
+ version = req['version']
77
+ groups = req['groups']
78
+
79
+ #development = req['development']
80
+ #if development
81
+ # # populate development dependencies
82
+ # if gemspec.respond_to?(:add_development_dependency)
83
+ # gemspec.add_development_dependency(name,*version)
84
+ # else
85
+ # gemspec.add_dependency(name,*version)
86
+ # end
87
+ #else
88
+ # # populate runtime dependencies
89
+ # if gemspec.respond_to?(:add_runtime_dependency)
90
+ # gemspec.add_runtime_dependency(name,*version)
91
+ # else
92
+ # gemspec.add_dependency(name,*version)
93
+ # end
94
+ #end
95
+
96
+ if groups.empty? or groups.include?('runtime')
97
+ # populate runtime dependencies
98
+ if gemspec.respond_to?(:add_runtime_dependency)
99
+ gemspec.add_runtime_dependency(name,*version)
100
+ else
101
+ gemspec.add_dependency(name,*version)
102
+ end
103
+ else
104
+ # populate development dependencies
105
+ if gemspec.respond_to?(:add_development_dependency)
106
+ gemspec.add_development_dependency(name,*version)
107
+ else
108
+ gemspec.add_dependency(name,*version)
109
+ end
110
+ end
111
+ end
112
+
113
+ # convert external dependencies into a requirements
114
+ if metadata['external_dependencies']
115
+ ##gemspec.requirements = [] unless metadata['external_dependencies'].empty?
116
+ metadata['external_dependencies'].each do |req|
117
+ gemspec.requirements << req.to_s
118
+ end
119
+ end
120
+
121
+ # determine homepage from resources
122
+ homepage = metadata['resources'].find{ |key, url| key =~ /^home/ }
123
+ gemspec.homepage = homepage.last if homepage
124
+
125
+ gemspec.require_paths = metadata['load_path'] || ['lib']
126
+ gemspec.post_install_message = metadata['install_message']
127
+
128
+ # RubyGems specific metadata
129
+ gemspec.files = files
130
+ gemspec.extensions = extensions
131
+ gemspec.executables = executables
132
+
133
+ if Gem::VERSION < '1.7.'
134
+ gemspec.default_executable = gemspec.executables.first
135
+ end
136
+
137
+ gemspec.test_files = glob_files[patterns[:test_files]]
138
+
139
+ unless gemspec.files.include?('.document')
140
+ gemspec.extra_rdoc_files = glob_files[patterns[:doc_files]]
141
+ end
142
+ end
143
+ end
@@ -1,6 +1,7 @@
1
1
  require 'autoreload/version'
2
2
  require 'autoreload/reloader'
3
3
 
4
- def autoreload(*files)
5
- AutoReload::Reloader.start(*files)
4
+ # Reload features automatically at given intervals.
5
+ def autoreload(options={}, &block)
6
+ AutoReload::Reloader.start(options, &block)
6
7
  end
@@ -1,5 +1,4 @@
1
1
  require 'thread'
2
- require 'autoreload/lookup'
3
2
 
4
3
  module AutoReload
5
4
 
@@ -9,8 +8,8 @@ module AutoReload
9
8
  class Reloader
10
9
 
11
10
  # Shortcut for Reloader.new(*args).start.
12
- def self.start(*args)
13
- self.new(*args).start
11
+ def self.start(*args, &block)
12
+ self.new(*args, &block).start
14
13
  end
15
14
 
16
15
  # Default interval is one second.
@@ -20,31 +19,35 @@ module AutoReload
20
19
  #
21
20
  # === Options
22
21
  #
23
- # :interval - seconds betwee updates
22
+ # :interval - seconds between updates
24
23
  # :verbose - true provides reload warning
25
24
  # :reprime - include $0 in reload list
26
25
  #
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
-
26
+ def initialize(options={}, &block)
32
27
  @interval = options[:interval] || DEFAULT_INTERVAL
33
28
  @verbose = options[:verbose]
34
29
  @reprime = options[:reprime]
35
30
 
36
31
  @status = {}
32
+
33
+ features = $".dup
34
+ if block
35
+ block.call
36
+ @files = ($" - features).reverse
37
+ else
38
+ @files = []
39
+ end
37
40
  end
38
41
 
39
42
  # Start the reload thread.
40
43
  def start
41
- update # primate the path loads
44
+ update # prime the path loads
42
45
  @thread = Thread.new do
43
46
  loop do
44
47
  begin
45
48
  update
46
49
  rescue Exception
47
- warn 'update failed: ' + $!
50
+ warn 'autoreload failed unexpectedly: ' + $!
48
51
  end
49
52
  sleep @interval
50
53
  end
@@ -74,14 +77,14 @@ module AutoReload
74
77
  @verbose || $VERBOSE
75
78
  end
76
79
 
77
- # Is $0 in the reload list?
80
+ # Put $0 in the reload list?
78
81
  def reprime?
79
82
  @reprime
80
83
  end
81
84
 
82
85
  private
83
86
 
84
- # List of library files to autoreload.
87
+ # The library files to autoreload.
85
88
  #--
86
89
  # ISSUE: Why include $0 ?
87
90
  #--
@@ -98,30 +101,41 @@ module AutoReload
98
101
  libraries.each{ |lib| check(lib) }
99
102
  end
100
103
 
101
- # Check status and reload if out-of-date.
102
- def check(lib)
103
- if @status.key?(lib)
104
+ # We can't check mtime under 1.8 b/c $LOADED_FEATURES does not
105
+ # store the full path.
106
+ if RUBY_VERSION < '1.9'
107
+ def check(lib)
108
+ warn "reload: '#{lib}'" if verbose?
109
+ begin
110
+ load lib
111
+ rescue LoadError
112
+ # file has been removed
113
+ end
114
+ end
115
+ else
116
+ # Check status and reload if out-of-date.
117
+ def check(lib)
104
118
  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]
119
+ if file
120
+ if FileTest.exist?(file)
121
+ curtime = File.mtime(file).to_i
122
+ if mtime < curtime
123
+ warn "reload: '#{file}'" if verbose?
124
+ load file
125
+ @status[lib] = [file, curtime]
126
+ end
127
+ else
128
+ # file has been removed
129
+ end
130
+ else
131
+ @status[lib] = get_status(lib)
115
132
  end
116
- else
117
- @status[lib] = get_status(lib)
118
133
  end
119
134
  end
120
135
 
121
136
  # Get library file status.
122
- def get_status(lib)
123
- file = Lookup.find(lib).first
124
- if file #FileTest.exist?(file)
137
+ def get_status(file)
138
+ if FileTest.exist?(file)
125
139
  [file, File.mtime(file).to_i]
126
140
  else
127
141
  warn "reload fail: library '#{lib}' not found" if verbose?
@@ -135,5 +149,4 @@ module AutoReload
135
149
 
136
150
  end
137
151
 
138
- # Copyright (C) 2003,2007 Kouichirou Eto
139
- # Copyright (C) 2010 Thomas Sawyer
152
+ # Copyright (C) 2010 Thomas Sawyer (BSD-2-Clause)