rack-unreloader 1.0.0 → 1.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4e78994d15fb3130a66a1b0c4cddd957bbc7ed5a
4
- data.tar.gz: 3151916048c0f97a461e6bd1a3e5d06cb5945943
3
+ metadata.gz: 8eacfdd6cd0d57685d8835bcfbc35bb716cc0241
4
+ data.tar.gz: eed0b264873367b89e234d9b74f1b47805ce48f3
5
5
  SHA512:
6
- metadata.gz: 184ff5f426d8c587377e045954d2968b562dd8bd3e823c3968efda3556104a33b8df68fafb3aec4269770f7014973e46382302756fddeaf1c99191a39f80dbb9
7
- data.tar.gz: 0877f19d6d65db719317c4d52a0cc1acb283f68b121af8a54b296c1e97cf7303d76bf59d33d293e9e3a06101d38add35a70fb4fe99d356877ead32d3bf3dd0b2
6
+ metadata.gz: 61c47de205a000b7048f516d3c841cc4dc20c88b565be214330e868a3c47a7e2561f90d4bcb7a9ed23eb10d62133639ae0e437e23b528a2f4ff362c8fb179def
7
+ data.tar.gz: 0eb1923fb9131e0a84b4ad020b54538bbd69ae7665bcf6f3bd5dc328685491a67aaec2c522baa01a00e1a4669bbebe0f803d65bc00f8f9eea31b1cd38e40fa40
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ = 1.1.0 (2014-09-25)
2
+
3
+ * Allow monitoring of directories, so that new files can be picked up, and deleted files removed (jeremyevans)
4
+
5
+ * Support ruby 1.8.7 (jeremyevans)
6
+
1
7
  = 1.0.0 (2014-08-12)
2
8
 
3
9
  * Ignore anonymous classes/modules (jeremyevans)
@@ -146,10 +146,19 @@ full path:
146
146
 
147
147
  Unreloader.require '/path/to/app.rb'
148
148
 
149
- You can use the usual file globbing:
149
+ You can use the usual file globbing to load multiple files:
150
150
 
151
151
  Unreloader.require 'models/*.rb'
152
152
 
153
+ If you want to load all files in a given directory you should just give
154
+ the directory path:
155
+
156
+ Unreloader.require 'models'
157
+
158
+ The advantage for doing this is that new files added to the directory will be
159
+ picked up automatically, and files deleted from the directory will be removed
160
+ automatically.
161
+
153
162
  == Speeding Things Up
154
163
 
155
164
  By default, <tt>Rack::Unreloader</tt> uses +ObjectSpace+ before and after requiring each
@@ -165,7 +174,7 @@ of constants to unload. If you do this, <tt>Rack::Unreloader</tt> will no longe
165
174
  to use +ObjectSpace+, which substantially speeds up startup. For example, if all of
166
175
  your models just use a capitalized version of the filename:
167
176
 
168
- Unreloader.require('models/*.rb'){|f| File.basename(f).sub(/\.rb\z/, '').capitalize}
177
+ Unreloader.require('models'){|f| File.basename(f).sub(/\.rb\z/, '').capitalize}
169
178
 
170
179
  == History
171
180
 
@@ -21,6 +21,12 @@ module Rack
21
21
  # with values being the last modified time (or nil if the file has not yet been loaded).
22
22
  @monitor_files = {}
23
23
 
24
+ # Hash of directories being monitored for changes, keyed by absolute path of directory name,
25
+ # with values being the an array with the last modified time (or nil if the directory has not
26
+ # yet been loaded), an array of files in the directory, and a block to pass to
27
+ # require_dependency for new files.
28
+ @monitor_dirs = {}
29
+
24
30
  # Hash of procs returning constants defined in files, keyed by absolute path
25
31
  # of file name. If there is no proc, must call ObjectSpace before and after
26
32
  # loading files to detect changes, which is slower.
@@ -55,6 +61,10 @@ module Rack
55
61
  # If there are any changed files, reload them. If there are no changed
56
62
  # files, do nothing.
57
63
  def reload!
64
+ @monitor_dirs.keys.each do |dir|
65
+ check_monitor_dir(dir)
66
+ end
67
+
58
68
  @monitor_files.to_a.each do |file, time|
59
69
  if file_changed?(file, time)
60
70
  safe_load(file)
@@ -62,6 +72,25 @@ module Rack
62
72
  end
63
73
  end
64
74
 
75
+ # Check a monitored directory for changes, adding new files and removing
76
+ # deleted files.
77
+ def check_monitor_dir(dir)
78
+ time, files, block = @monitor_dirs[dir]
79
+
80
+ if file_changed?(dir, time)
81
+ cur_files = Dir.new(dir).grep(/\.rb\z/).map{|f| F.join(dir, f)}
82
+
83
+ (files - cur_files).each do |f|
84
+ remove(f)
85
+ @monitor_files.delete(f)
86
+ end
87
+
88
+ require_dependencies(cur_files - files, &block)
89
+
90
+ files.replace(cur_files)
91
+ end
92
+ end
93
+
65
94
  # Require the given dependencies, monitoring them for changes.
66
95
  # Paths should be a file glob or an array of file globs.
67
96
  def require_dependencies(paths, &block)
@@ -76,8 +105,15 @@ module Rack
76
105
  uniq.
77
106
  each do |file|
78
107
 
79
- @constants_defined[file] = block
80
- @monitor_files[file] = nil
108
+ if F.directory?(file)
109
+ @monitor_dirs[file] = [nil, [], block]
110
+ check_monitor_dir(file)
111
+ next
112
+ else
113
+ @constants_defined[file] = block
114
+ @monitor_files[file] = nil
115
+ end
116
+
81
117
  begin
82
118
  safe_load(file, options)
83
119
  rescue NameError, LoadError => error
@@ -285,7 +321,7 @@ module Rack
285
321
  # Call the app with the environment.
286
322
  def call(env)
287
323
  if @cooldown && Time.now > @last + @cooldown
288
- Thread.exclusive{@reloader.reload!}
324
+ Thread.respond_to?(:exclusive) ? Thread.exclusive{@reloader.reload!} : @reloader.reload!
289
325
  @last = Time.now
290
326
  end
291
327
  @app_block.call.call(env)
@@ -1,5 +1,16 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), '../lib/rack/unreloader')
2
2
 
3
+ if defined?(RSpec)
4
+ require 'rspec/version'
5
+ if RSpec::Version::STRING >= '2.11.0'
6
+ RSpec.configure do |config|
7
+ config.expect_with :rspec do |c|
8
+ c.syntax = :should
9
+ end
10
+ end
11
+ end
12
+ end
13
+
3
14
  module ModifiedAt
4
15
  def set_modified_time(file, time)
5
16
  modified_times[File.expand_path(file)] = time
@@ -256,4 +267,60 @@ describe Rack::Unreloader do
256
267
  "Error removing constant: Foo",
257
268
  %r{\ARemoved feature .*/spec/app.rb\z}
258
269
  end
270
+
271
+ describe "with a directory" do
272
+ before do
273
+ Dir.mkdir('spec/dir')
274
+ end
275
+
276
+ after do
277
+ Dir['spec/dir/*.rb'].each{|f| File.delete(f)}
278
+ Dir.rmdir('spec/dir')
279
+ end
280
+
281
+ it "should pick up changes to files in that directory" do
282
+ base_ru
283
+ update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require 'spec/dir'")
284
+ update_app("App.call[:foo] = 1", 'spec/dir/a.rb')
285
+ @ru.require('spec/app.rb')
286
+ ru.call({}).should == {:foo=>1}
287
+ update_app("App.call[:foo] = 2", 'spec/dir/a.rb')
288
+ ru.call({}).should == {:foo=>2}
289
+ log_match %r{\ALoading.*spec/app\.rb\z},
290
+ %r{\ALoading.*spec/dir/a\.rb\z},
291
+ %r{\ANew classes in .*spec/app\.rb: App\z},
292
+ %r{\ANew features in .*spec/app\.rb: .*spec/dir/a\.rb\z},
293
+ %r{\AReloading .*/spec/dir/a.rb\z},
294
+ %r{\ARemoved feature .*/spec/dir/a.rb\z}
295
+ end
296
+
297
+ it "should pick up new files added to the directory" do
298
+ base_ru
299
+ update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require 'spec/dir'")
300
+ @ru.require('spec/app.rb')
301
+ ru.call({}).should == {}
302
+ update_app("App.call[:foo] = 2", 'spec/dir/a.rb')
303
+ ru.call({}).should == {:foo=>2}
304
+ log_match %r{\ALoading.*spec/app\.rb\z},
305
+ %r{\ANew classes in .*spec/app\.rb: App\z},
306
+ %r{\ALoading.*spec/dir/a\.rb\z}
307
+ end
308
+
309
+ it "should drop files deleted from the directory" do
310
+ base_ru
311
+ update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require 'spec/dir'")
312
+ update_app("App.call[:foo] = 1", 'spec/dir/a.rb')
313
+ @ru.require('spec/app.rb')
314
+ ru.call({}).should == {:foo=>1}
315
+ File.delete('spec/dir/a.rb')
316
+ update_app("App.call[:foo] = 2", 'spec/dir/b.rb')
317
+ ru.call({}).should == {:foo=>2}
318
+ log_match %r{\ALoading.*spec/app\.rb\z},
319
+ %r{\ALoading.*spec/dir/a\.rb\z},
320
+ %r{\ANew classes in .*spec/app\.rb: App\z},
321
+ %r{\ANew features in .*spec/app\.rb: .*spec/dir/a\.rb\z},
322
+ %r{\ARemoved feature .*/spec/dir/a.rb\z},
323
+ %r{\ALoading.*spec/dir/b\.rb\z}
324
+ end
325
+ end
259
326
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-unreloader
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-12 00:00:00.000000000 Z
11
+ date: 2014-09-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  Rack::Unreloader is a rack middleware that reloads application files when it