spring 2.0.1 → 2.0.2

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: 1bddca3c690cbffa39ebba5555a9117fb2d967c2
4
- data.tar.gz: 0cd7e5f1cb515f90dc9f7c30c2b54d4c6989d170
3
+ metadata.gz: 42ad763baaed56f6c7dd36b05566eec2e008481b
4
+ data.tar.gz: 6f228d8ea63046f99353e83e732a72ef1900b0fd
5
5
  SHA512:
6
- metadata.gz: 1e4343e2e31bb23ca71fdc2d125859d84a421fedb14fd67f480e3ce2e933528f1dcb24b5bb7cc8cc29f77addeaf6fc647816277db6878606dce00b8c212d8a50
7
- data.tar.gz: 35306479eefb76d7a0ca9c5dfc4ee6ccce8d7563c429edb84f1912e0e2627d5512b46f45cc981bcb0b5362b897257cbd8ce945fc3359ee0004f84abef1ecda95
6
+ metadata.gz: b049078c55028bbba601d2ca065fff5e3904cfd27b4ab6b719b7488e1bd044247cb88716126d46e5f26abb6296818d606b717ae4c0ad4c9c04726ff43e22c50e
7
+ data.tar.gz: 12560b678ff15621efb6b479a443048330088f40ad328b920525785d59aa64064895565f96db5bb14801ce6c516106f3296ec8966a83b55142e915fa0df7bf74
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012-2016 Jon Leighton
1
+ Copyright (c) 2012-2017 Jon Leighton
2
2
 
3
3
  MIT License
4
4
 
@@ -66,7 +66,17 @@ module Spring
66
66
 
67
67
  def start_watcher
68
68
  @watcher = Spring.watcher
69
- @watcher.on_stale { state! :watcher_stale }
69
+
70
+ @watcher.on_stale do
71
+ state! :watcher_stale
72
+ end
73
+
74
+ if @watcher.respond_to? :on_debug
75
+ @watcher.on_debug do |message|
76
+ spring_env.log "[watcher:#{app_env}] #{message}"
77
+ end
78
+ end
79
+
70
80
  @watcher.start
71
81
  end
72
82
 
@@ -92,6 +92,11 @@ module Spring
92
92
 
93
93
  build_and_install_gems
94
94
 
95
+ # TO prevent nokogiri install error in application.bundle.
96
+ if RUBY_VERSION < "2.1.0"
97
+ append_to_file(application.gemfile, "gem 'nokogiri', '~> 1.6.8'")
98
+ end
99
+
95
100
  application.bundle
96
101
 
97
102
  FileUtils.rm_rf application.path("bin")
@@ -162,6 +162,33 @@ module Spring
162
162
  watcher.add './foobar'
163
163
  assert watcher.files.empty?
164
164
  end
165
+
166
+ test "add symlink" do
167
+ File.write("#{dir}/bar", "bar")
168
+ File.symlink("#{dir}/bar", "#{dir}/foo")
169
+ watcher.add './foo'
170
+ assert_equal ["#{dir}/bar"], watcher.files.to_a
171
+ end
172
+
173
+ test "add dangling symlink" do
174
+ File.symlink("#{dir}/bar", "#{dir}/foo")
175
+ watcher.add './foo'
176
+ assert watcher.files.empty?
177
+ end
178
+
179
+ test "add directory with dangling symlink" do
180
+ subdir = "#{@dir}/subdir"
181
+ FileUtils.mkdir(subdir)
182
+ File.symlink("dangling", "#{subdir}/foo")
183
+
184
+ watcher.add subdir
185
+ assert_not_stale
186
+
187
+ # Adding a new file should mark as stale despite the dangling symlink.
188
+ File.write("#{subdir}/new-file", "new")
189
+ watcher.check_stale
190
+ assert_stale
191
+ end
165
192
  end
166
193
  end
167
194
  end
@@ -1,3 +1,3 @@
1
1
  module Spring
2
- VERSION = "2.0.1"
2
+ VERSION = "2.0.2"
3
3
  end
@@ -23,9 +23,21 @@ module Spring
23
23
  @directories = Set.new
24
24
  @stale = false
25
25
  @listeners = []
26
+
27
+ @on_debug = nil
28
+ end
29
+
30
+ def on_debug(&block)
31
+ @on_debug = block
32
+ end
33
+
34
+ def debug
35
+ @on_debug.call(yield) if @on_debug
26
36
  end
27
37
 
28
38
  def add(*items)
39
+ debug { "watcher: add: #{items.inspect}" }
40
+
29
41
  items = items.flatten.map do |item|
30
42
  item = Pathname.new(item)
31
43
 
@@ -36,14 +48,30 @@ module Spring
36
48
  end
37
49
  end
38
50
 
39
- items = items.select(&:exist?)
51
+ items = items.select do |item|
52
+ if item.symlink?
53
+ item.readlink.exist?.tap do |exists|
54
+ if !exists
55
+ debug { "add: ignoring dangling symlink: #{item.inspect} -> #{item.readlink.inspect}" }
56
+ end
57
+ end
58
+ else
59
+ item.exist?
60
+ end
61
+ end
40
62
 
41
63
  synchronize {
42
64
  items.each do |item|
43
65
  if item.directory?
44
66
  directories << item.realpath.to_s
45
67
  else
46
- files << item.realpath.to_s
68
+ begin
69
+ files << item.realpath.to_s
70
+ rescue Errno::ENOENT
71
+ # Race condition. Ignore symlinks whose target was removed
72
+ # since the check above, or are deeply chained.
73
+ debug { "add: ignoring now-dangling symlink: #{item.inspect} -> #{item.readlink.inspect}" }
74
+ end
47
75
  end
48
76
  end
49
77
 
@@ -56,16 +84,19 @@ module Spring
56
84
  end
57
85
 
58
86
  def on_stale(&block)
87
+ debug { "added listener: #{block.inspect}" }
59
88
  @listeners << block
60
89
  end
61
90
 
62
91
  def mark_stale
63
92
  return if stale?
64
93
  @stale = true
94
+ debug { "marked stale, calling listeners: listeners=#{@listeners.inspect}" }
65
95
  @listeners.each(&:call)
66
96
  end
67
97
 
68
98
  def restart
99
+ debug { "restarting" }
69
100
  stop
70
101
  start
71
102
  end
@@ -12,7 +12,13 @@ module Spring
12
12
  end
13
13
 
14
14
  def check_stale
15
- synchronize { mark_stale if mtime < compute_mtime }
15
+ synchronize do
16
+ computed = compute_mtime
17
+ if mtime < computed
18
+ debug { "check_stale: mtime=#{mtime.inspect} < computed=#{computed.inspect}" }
19
+ mark_stale
20
+ end
21
+ end
16
22
  end
17
23
 
18
24
  def add(*)
@@ -21,36 +27,67 @@ module Spring
21
27
  end
22
28
 
23
29
  def start
30
+ debug { "start: poller=#{@poller.inspect}" }
24
31
  unless @poller
25
32
  @poller = Thread.new {
26
33
  Thread.current.abort_on_exception = true
27
34
 
28
- loop do
29
- Kernel.sleep latency
30
- check_stale
35
+ begin
36
+ until stale?
37
+ Kernel.sleep latency
38
+ check_stale
39
+ end
40
+ rescue Exception => e
41
+ debug do
42
+ "poller: aborted: #{e.class}: #{e}\n #{e.backtrace.join("\n ")}"
43
+ end
44
+ raise
45
+ ensure
46
+ @poller = nil
31
47
  end
32
48
  }
33
49
  end
34
50
  end
35
51
 
36
52
  def stop
53
+ debug { "stopping poller: #{@poller.inspect}" }
37
54
  if @poller
38
55
  @poller.kill
39
56
  @poller = nil
40
57
  end
41
58
  end
42
59
 
60
+ def running?
61
+ @poller && @poller.alive?
62
+ end
63
+
43
64
  def subjects_changed
44
- @mtime = compute_mtime
65
+ computed = compute_mtime
66
+ debug { "subjects_changed: mtime #{@mtime} -> #{computed}" }
67
+ @mtime = computed
45
68
  end
46
69
 
47
70
  private
48
71
 
49
72
  def compute_mtime
50
- expanded_files.map { |f| File.mtime(f).to_f }.max || 0
51
- rescue Errno::ENOENT
52
- # if a file does no longer exist, the watcher is always stale.
53
- Float::MAX
73
+ expanded_files.map do |f|
74
+ # Get the mtime of symlink targets. Ignore dangling symlinks.
75
+ if File.symlink?(f)
76
+ begin
77
+ File.mtime(f)
78
+ rescue Errno::ENOENT
79
+ 0
80
+ end
81
+ # If a file no longer exists, treat it as changed.
82
+ else
83
+ begin
84
+ File.mtime(f)
85
+ rescue Errno::ENOENT
86
+ debug { "compute_mtime: no longer exists: #{f}" }
87
+ Float::MAX
88
+ end
89
+ end.to_f
90
+ end.max || 0
54
91
  end
55
92
 
56
93
  def expanded_files
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spring
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Leighton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-21 00:00:00.000000000 Z
11
+ date: 2017-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -121,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
121
  version: '0'
122
122
  requirements: []
123
123
  rubyforge_project:
124
- rubygems_version: 2.5.1
124
+ rubygems_version: 2.6.8
125
125
  signing_key:
126
126
  specification_version: 4
127
127
  summary: Rails application preloader