Skip to content

Commit

Permalink
Merge pull request #387 from guard/fixing_jruby_support
Browse files Browse the repository at this point in the history
Misc fixes to get JRuby working on Travis
  • Loading branch information
e2 committed May 3, 2016
2 parents 1684919 + b09a3a7 commit acf3d35
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 25 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ rvm:
- 2.2.4
- jruby-head
- rbx-2
- jruby-9.0.5.0
matrix:
allow_failures:
- rvm: jruby-head
Expand Down
2 changes: 2 additions & 0 deletions lib/listen/adapter/linux.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ def _configure(directory, &callback)
end

def _run
Thread.current[:listen_blocking_read_thread] = true
@worker.run
Thread.current[:listen_blocking_read_thread] = false
end

def _process_event(dir, event)
Expand Down
15 changes: 13 additions & 2 deletions lib/listen/directory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def self.scan(snapshot, rel_path, options)

# TODO: use children(with_directory: false)
path = dir + rel_path
current = Set.new(path.children)
current = Set.new(_children(path))

Listen::Logger.debug do
format('%s: %s(%s): %s -> %s',
Expand All @@ -28,7 +28,7 @@ def self.scan(snapshot, rel_path, options)
end
rescue Errno::ENOENT
# The directory changed meanwhile, so rescan it
current = Set.new(path.children)
current = Set.new(_children(path))
retry
end

Expand Down Expand Up @@ -72,5 +72,16 @@ def self._change(snapshot, type, path, options)
opts.delete(:recursive)
snapshot.invalidate(type, path, opts)
end

def self._children(path)
return path.children unless RUBY_ENGINE == 'jruby'

# JRuby inconsistency workaround, see:
# https://github.com/jruby/jruby/issues/3840
exists = path.exist?
directory = path.directory?
return path.children unless exists && !directory
raise Errno::ENOTDIR, path.to_s
end
end
end
10 changes: 9 additions & 1 deletion lib/listen/internals/thread_pool.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,16 @@ def self.stop
return if @threads.empty? # return to avoid using possibly stubbed Queue

killed = Queue.new
# You can't kill a read on a descriptor in JRuby, so let's just
# ignore running threads (listen rb-inotify waiting for disk activity
# before closing) pray threads die faster than they are created...
limit = RUBY_ENGINE == 'jruby' ? [1] : []

killed << @threads.pop.kill until @threads.empty?
killed.pop.join until killed.empty?
until killed.empty?
th = killed.pop
th.join(*limit) unless th[:listen_blocking_read_thread]
end
end
end
end
Expand Down
13 changes: 12 additions & 1 deletion lib/listen/record/entry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def initialize(root, relative, name = nil)

def children
child_relative = _join
(Dir.entries(sys_path) - %w(. ..)).map do |name|
(_entries(sys_path) - %w(. ..)).map do |name|
Entry.new(@root, child_relative, name)
end
end
Expand Down Expand Up @@ -48,6 +48,17 @@ def _join
args = [@relative, @name].compact
args.empty? ? nil : ::File.join(*args)
end

def _entries(dir)
return Dir.entries(dir) unless RUBY_ENGINE == 'jruby'

# JRuby inconsistency workaround, see:
# https://github.com/jruby/jruby/issues/3840
exists = ::File.exist?(dir)
directory = ::File.directory?(dir)
return Dir.entries(dir) unless exists && !directory
raise Errno::ENOTDIR, dir
end
end
end
end
8 changes: 4 additions & 4 deletions listen.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ Gem::Specification.new do |s|
abort "Install 'ruby_dep' gem before building this gem"
end

s.add_dependency 'rb-fsevent', '>= 0.9.3'
s.add_dependency 'rb-inotify', '>= 0.9.7'
s.add_dependency 'rb-fsevent', '~> 0.9', '>= 0.9.7'
s.add_dependency 'rb-inotify', '~> 0.9', '>= 0.9.7'

# Used to show warnings at runtime
s.add_dependency 'ruby_dep', '~> 1.1'
s.add_dependency 'ruby_dep', '~> 1.2'

s.add_development_dependency 'bundler', '>= 1.3.5'
s.add_development_dependency 'bundler', '~> 1.12'
end
41 changes: 24 additions & 17 deletions spec/lib/listen/directory_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ def fake_dir_stat(name, options = {})
instance_double(::File::Stat, name, defaults.merge(options))
end

def fake_children(ex, dir, *args, &block)
if block_given?
ex.send(:allow, dir).to receive(:children, &block)
else
ex.send(:allow, dir).to receive(:children).and_return(*args)
end
ex.send(:allow, dir).to receive(:exist?).and_return(true)
ex.send(:allow, dir).to receive(:directory?).and_return(true)
end

let(:dir) { double(:dir) }
let(:file) { fake_path('file.rb') }
let(:file2) { fake_path('file2.rb') }
Expand Down Expand Up @@ -53,7 +63,7 @@ def fake_dir_stat(name, options = {})
end

context 'with empty dir' do
before { allow(dir).to receive(:children) { [] } }
before { fake_children(self, dir, []) }

it 'sets record dir path' do
expect(record).to receive(:add_dir).with('.')
Expand All @@ -71,9 +81,8 @@ def fake_dir_stat(name, options = {})
end

context 'when subdir is removed' do
before do
allow(dir).to receive(:children) { [file] }

before do
fake_children(self, dir, [file])
allow(::File).to receive(:lstat).with('file.rb').
and_return(fake_file_stat('file.rb'))
end
Expand All @@ -88,7 +97,7 @@ def fake_dir_stat(name, options = {})

context 'when file.rb removed' do
before do
allow(dir).to receive(:children) { [subdir] }
fake_children(self, dir, [subdir])

allow(::File).to receive(:lstat).with('subdir').
and_return(fake_dir_stat('subdir'))
Expand All @@ -102,7 +111,7 @@ def fake_dir_stat(name, options = {})

context 'when file.rb no longer exists after scan' do
before do
allow(dir).to receive(:children).and_return([file], [file2])
fake_children(self, dir, [file], [file2])

allow(::File).to receive(:lstat).with('file.rb').
and_raise(Errno::ENOENT)
Expand All @@ -119,7 +128,7 @@ def fake_dir_stat(name, options = {})

context 'when file2.rb is added' do
before do
allow(dir).to receive(:children) { [file, file2, subdir] }
fake_children(self, dir, [file, file2, subdir])

allow(::File).to receive(:lstat).with('file.rb').
and_return(fake_file_stat('file.rb'))
Expand All @@ -142,7 +151,7 @@ def fake_dir_stat(name, options = {})
let(:record_entries) { {} }

context 'with non-existing dir path' do
before { allow(dir).to receive(:children) { fail Errno::ENOENT } }
before { fake_children(self, dir) { fail Errno::ENOENT } }

it 'reports no changes' do
expect(snapshot).to_not receive(:invalidate)
Expand All @@ -156,7 +165,7 @@ def fake_dir_stat(name, options = {})
end

context 'when network share is disconnected' do
before { allow(dir).to receive(:children) { fail Errno::EHOSTDOWN } }
before { fake_children(self, dir) { fail Errno::EHOSTDOWN } }

it 'reports no changes' do
expect(snapshot).to_not receive(:invalidate)
Expand All @@ -171,7 +180,7 @@ def fake_dir_stat(name, options = {})

context 'with file.rb in dir' do
before do
allow(dir).to receive(:children) { [file] }
fake_children(self, dir, [file])

allow(::File).to receive(:lstat).with('file.rb').
and_return(fake_file_stat('file.rb'))
Expand Down Expand Up @@ -202,9 +211,7 @@ def fake_dir_stat(name, options = {})
end

context 'with empty dir' do
before do
allow(dir).to receive(:children) { [] }
end
before { fake_children(self, dir, []) }

it 'snapshots changes for file & subdir path' do
expect(snapshot).to receive(:invalidate).with(:file, 'file.rb', {})
Expand All @@ -220,7 +227,7 @@ def fake_dir_stat(name, options = {})
let(:subdir2) { fake_path('subdir2', children: []) }

before do
allow(dir).to receive(:children) { [subdir2] }
fake_children(self, dir, [subdir2])
allow(subdir2).to receive(:relative_path_from).with(dir) { 'subdir2' }

allow(::File).to receive(:lstat).with('subdir2').
Expand All @@ -246,7 +253,7 @@ def fake_dir_stat(name, options = {})

context 'with non-existing dir' do
before do
allow(dir).to receive(:children) { fail Errno::ENOENT }
fake_children(self, dir) { fail Errno::ENOENT }
end

it 'reports no changes' do
Expand All @@ -257,8 +264,8 @@ def fake_dir_stat(name, options = {})

context 'with subdir present in dir' do
before do
allow(dir).to receive(:children) { [subdir] }
allow(subdir).to receive(:children) { [] }
fake_children(self, dir, [subdir])
fake_children(self, subdir, [])
allow(::File).to receive(:lstat).with('subdir').
and_return(fake_dir_stat('subdir'))
end
Expand Down

0 comments on commit acf3d35

Please sign in to comment.