Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #548: fix error when renaming folder #552

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/listen/directory.rb
Expand Up @@ -36,7 +36,7 @@ def self.scan(snapshot, rel_path, options)
end

# TODO: this is not tested properly
previous = previous.reject { |entry, _| current.include? path + entry }
previous = previous.reject { |entry, _| current.include?(path + entry) }

_async_changes(snapshot, Pathname.new(rel_path), previous, options)
rescue Errno::ENOENT, Errno::EHOSTDOWN
Expand Down
41 changes: 22 additions & 19 deletions lib/listen/record.rb
Expand Up @@ -12,14 +12,14 @@ class Record
attr_reader :root

def initialize(directory, silencer)
@tree = _auto_hash
reset_tree
@root = directory.to_s
@silencer = silencer
end

def add_dir(rel_path)
if ![nil, '', '.'].include?(rel_path)
@tree[rel_path] ||= {}
if !empty_dirname?(rel_path.to_s)
@tree[rel_path.to_s]
end
end

Expand All @@ -35,32 +35,32 @@ def unset_path(rel_path)

def file_data(rel_path)
dirname, basename = Pathname(rel_path).split.map(&:to_s)
if [nil, '', '.'].include? dirname
@tree[basename] ||= {}
if empty_dirname?(dirname)
@tree[basename].dup
else
@tree[dirname] ||= {}
@tree[dirname][basename] ||= {}
@tree[dirname][basename].dup
end
end

def dir_entries(rel_path)
subtree = if ['', '.'].include? rel_path.to_s
rel_path_s = rel_path.to_s
subtree = if empty_dirname?(rel_path_s)
@tree
else
@tree[rel_path.to_s] ||= _auto_hash
@tree[rel_path.to_s]
@tree[rel_path_s]
end

subtree.transform_values do |values|
# only get data for file entries
values.key?(:mtime) ? values : {}
subtree.each_with_object({}) do |(key, values), result|
# only return data for file entries inside the dir (which will each be sub-hashes)
if values.is_a?(Hash)
result[key] = values.has_key?(:mtime) ? values : {}
end
end
end

def build
@tree = _auto_hash
reset_tree
# TODO: test with a file name given
# TODO: test other permissions
# TODO: test with mixed encoding
Expand All @@ -72,23 +72,26 @@ def build

private

def _auto_hash
Hash.new { |h, k| h[k] = {} }
def empty_dirname?(dirname)
dirname == '.' || dirname == ''
ColinDKelley marked this conversation as resolved.
Show resolved Hide resolved
end

def reset_tree
@tree = Hash.new { |h, k| h[k] = {} }
end

def _fast_update_file(dirname, basename, data)
if [nil, '', '.'].include?(dirname)
@tree[basename] = (@tree[basename] || {}).merge(data)
if empty_dirname?(dirname.to_s)
@tree[basename] = @tree[basename].merge(data)
else
@tree[dirname] ||= {}
@tree[dirname][basename] = (@tree[dirname][basename] || {}).merge(data)
end
end

def _fast_unset_path(dirname, basename)
# this may need to be reworked to properly remove
# entries from a tree, without adding non-existing dirs to the record
if [nil, '', '.'].include?(dirname)
if empty_dirname?(dirname.to_s)
if @tree.key?(basename)
@tree.delete(basename)
end
Expand Down
10 changes: 9 additions & 1 deletion spec/lib/listen/record_spec.rb
Expand Up @@ -66,7 +66,7 @@ def record_tree(record)
end

context 'with subdir path' do
it 'sets path by spliting dirname and basename' do
it 'sets path by splitting dirname and basename' do
record.update_file('path/file.rb', mtime: 1.1)
expect(record_tree(record)['path']).to eq('file.rb' => { mtime: 1.1 })
end
Expand Down Expand Up @@ -257,6 +257,14 @@ def record_tree(record)
end
it { should be_empty }
end

context 'with path renamed to file' do
before do
record.add_dir('path/subdir')
record.update_file('path', mtime: 1.1)
end
it { should be_empty }
end
end
end

Expand Down