rack-unreloader 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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