Class: Bixby::App::FileFinder

Inherits:
Object
  • Object
show all
Defined in:
lib/bixby-client/app/file_finder.rb

Instance Method Summary collapse

Constructor Details

#initialize(root) ⇒ FileFinder

Returns a new instance of FileFinder.



8
9
10
# File 'lib/bixby-client/app/file_finder.rb', line 8

def initialize(root)
  @root = root
end

Instance Method Details

#find_all_files(path) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/bixby-client/app/file_finder.rb', line 42

def find_all_files(path)
  ret = []
  ret += Dir.glob(File.join(path, "**/**")).find_all{ |f|
    # select only actual script files to look at
    if File.symlink? f then
      ret << find_all_files(File.expand_path(f))
    end

    keep?(f, path)
  }

  return ret.flatten
end

#find_script(script) ⇒ Array<String>

Look for a script matchign the given [partial] filename

Parameters:

  • script (String)

Returns:

  • (Array<String>)

    matches



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/bixby-client/app/file_finder.rb', line 17

def find_script(script)
  return nil if script.nil? or script.empty?
  return script if File.exists? script

  # try relative path
  s = File.expand_path(File.join(@root, script))
  return s if File.exists? s

  # try searching
  matches = find_all_files(@root).
              find_all { |f| f.include?("/bin/") && f.include?(script) }.
              sort { |a,b| ld(script, File.basename(a)) <=> ld(script, File.basename(b)) }

  return matches if matches.size == 1 # only one result, just return it

  # fuzzy search
  fuzzy_matches = FuzzyFileFinder.new(@root).find(script.dup).
                    sort_by { |m| -m[:score] }.
                    map{ |f| f[:path] }.
                    find_all{ |f| keep?(f, @root) }

  # return the union of all unique matches
  return fuzzy_matches + (matches - fuzzy_matches)
end

#keep?(f, path) ⇒ Boolean

Returns:

  • (Boolean)


56
57
58
59
60
61
# File 'lib/bixby-client/app/file_finder.rb', line 56

def keep?(f, path)
  !File.directory? f and
    f !~ /\.(json|test.*)|\/digest$/ and
    File.dirname(f) != path and
    File.dirname(f) !~ /\/(test|lib)$/
end

#levenshtein_distance(a, b) ⇒ Object Also known as: ld

Calculate the levenshtein distance between two strings

via github.com/akirahrkw/levenshtein-distance en.wikipedia.org/wiki/Levenshtein_distance



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/bixby-client/app/file_finder.rb', line 67

def levenshtein_distance(a, b)
  a_len = a.length
  b_len = b.length
  d = Array.new(a_len + 1).map! {
    Array.new(b_len + 1).map!{
      0
    }
  }
  (a_len + 1).times { |i| d[i][0] = i }
  (b_len + 1).times { |i| d[0][i] = i }

  for i in 1..(a_len)
    for j in 1..(b_len)
      cost = (a[i - 1] == b[j - 1]) ? 0 : 1
      d[i][j] = [ d[i-1][j] + 1 , d[i][j-1] + 1 ,d[i-1][j-1] + cost].min
    end
  end
  d[-1][-1]
end