Handle symlink cycles when fuzzy file finding (file open)
This commit is contained in:
parent
88afb72f21
commit
e3c0bcdd18
|
@ -1,6 +1,10 @@
|
|||
Diakonos Changelog
|
||||
------------------
|
||||
|
||||
0.9.8
|
||||
|
||||
- Handle symlink cycles when fuzzy file finding (file open)
|
||||
|
||||
0.9.7
|
||||
- Added ability to move lines up or down.
|
||||
- Made compatible with Ruby 2.4.0.
|
||||
|
|
41
lib/diakonos/vendor/fuzzy_file_finder.rb
vendored
41
lib/diakonos/vendor/fuzzy_file_finder.rb
vendored
|
@ -34,13 +34,6 @@
|
|||
#
|
||||
# And so forth.
|
||||
class FuzzyFileFinder
|
||||
module Version
|
||||
MAJOR = 1
|
||||
MINOR = 0
|
||||
TINY = 4
|
||||
STRING = [MAJOR, MINOR, TINY].join(".")
|
||||
end
|
||||
|
||||
# This is the exception that is raised if you try to scan a
|
||||
# directory tree with too many entries. By default, a ceiling of
|
||||
# 10,000 entries is enforced, but you can change that number via
|
||||
|
@ -112,22 +105,29 @@ class FuzzyFileFinder
|
|||
def initialize( params = {} )
|
||||
@ceiling = params[:ceiling] || 10_000
|
||||
@ignores = Array(params[:ignores])
|
||||
|
||||
if params[:directories]
|
||||
directories = Array(params[:directories])
|
||||
directories << "." if directories.empty?
|
||||
else
|
||||
directories = ['.']
|
||||
end
|
||||
|
||||
@recursive = params[:recursive].nil? ? true : params[:recursive]
|
||||
|
||||
# expand any paths with ~
|
||||
root_dirnames = directories.map { |d| File.expand_path(d) }.select { |d| File.directory?(d) }.uniq
|
||||
root_dirnames = directories.map { |d|
|
||||
File.realpath(d)
|
||||
}.select { |d|
|
||||
File.directory?(d)
|
||||
}.uniq
|
||||
|
||||
@roots = root_dirnames.map { |d| Directory.new(d, true) }
|
||||
@shared_prefix = determine_shared_prefix
|
||||
@shared_prefix_re = Regexp.new("^#{Regexp.escape(shared_prefix)}" + (shared_prefix.empty? ? "" : "/"))
|
||||
|
||||
@files = []
|
||||
@directories = {} # To detect link cycles
|
||||
|
||||
rescan!
|
||||
end
|
||||
|
@ -218,19 +218,24 @@ class FuzzyFileFinder
|
|||
# Recursively scans +directory+ and all files and subdirectories
|
||||
# beneath it, depth-first.
|
||||
def follow_tree(directory)
|
||||
Dir.entries(directory.name).each do |entry|
|
||||
next if entry[0,1] == "."
|
||||
raise TooManyEntries if files.length > ceiling
|
||||
real_dir = File.realpath(directory.name)
|
||||
if ! @directories[real_dir]
|
||||
@directories[real_dir] = true
|
||||
|
||||
full = File.join(directory.name, entry)
|
||||
next if ignore?(full)
|
||||
Dir.entries(directory.name).each do |entry|
|
||||
next if entry[0,1] == "."
|
||||
raise TooManyEntries if files.length > ceiling
|
||||
|
||||
if File.directory?(full)
|
||||
if @recursive
|
||||
follow_tree(Directory.new(full))
|
||||
full = File.join(directory.name, entry)
|
||||
next if ignore?(full)
|
||||
|
||||
if File.directory?(full)
|
||||
if @recursive
|
||||
follow_tree(Directory.new(full))
|
||||
end
|
||||
else
|
||||
files.push(FileSystemEntry.new(directory, entry))
|
||||
end
|
||||
else
|
||||
files.push(FileSystemEntry.new(directory, entry))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module Diakonos
|
||||
VERSION = '0.9.7'
|
||||
LAST_MODIFIED = 'October 2, 2019'
|
||||
VERSION = '0.9.8'
|
||||
LAST_MODIFIED = 'February 26, 2020'
|
||||
|
||||
def self.parse_version( s )
|
||||
if s
|
||||
|
@ -11,7 +11,7 @@ module Diakonos
|
|||
def self.check_ruby_version
|
||||
ruby_version = parse_version( RUBY_VERSION )
|
||||
if ruby_version < [ 2, 1 ]
|
||||
$stderr.puts "This version of Diakonos (#{Diakonos::VERSION}) requires Ruby 2.1, 2.2, 2.3 or 2.4."
|
||||
$stderr.puts "This version of Diakonos (#{Diakonos::VERSION}) requires Ruby 2.1 or higher."
|
||||
if ruby_version >= [ 2, 0 ]
|
||||
$stderr.puts "Version 0.9.5 is the last version of Diakonos which can run under Ruby 2.0."
|
||||
elsif ruby_version >= [ 1, 9 ]
|
||||
|
|
37
spec/fuzzy_file_finder_spec.rb
Normal file
37
spec/fuzzy_file_finder_spec.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FuzzyFileFinder do
|
||||
let(:params) {
|
||||
{
|
||||
ceiling: ceiling,
|
||||
directories: directories,
|
||||
ignores: ignores,
|
||||
recursive: recursive,
|
||||
}
|
||||
}
|
||||
let(:finder) { described_class.new(params) }
|
||||
|
||||
let(:ceiling) { nil }
|
||||
let(:directories) { ['spec/test-files'] }
|
||||
let(:ignores) { [] }
|
||||
let(:recursive) { nil }
|
||||
|
||||
describe "#find" do
|
||||
let(:matches) {
|
||||
finder.find(input).map { |match|
|
||||
match[:path].gsub(/^#{__dir__}/, '')
|
||||
}
|
||||
}
|
||||
|
||||
context "basic input" do
|
||||
let(:input) { 'lo' }
|
||||
|
||||
it "finds the matching files" do
|
||||
expect(matches).to eq [
|
||||
'/test-files/longer-sample-file.rb',
|
||||
'/test-files/lorem-ipsum.txt',
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
1
spec/test-files/self
Symbolic link
1
spec/test-files/self
Symbolic link
|
@ -0,0 +1 @@
|
|||
.
|
Loading…
Reference in a new issue