class SearchPath

Public Class Methods

new(paths) click to toggle source

Flatten the search path paths by creating a tree of symlinks at dest. For example, if the paths include /usr/bin, and /usr/lib, then dest will be a directory with symlinks bin and lib to the respective directories.

# File lib/fastup.rb, line 57
def initialize(paths)
  @root = {}
  paths.each{ |path| @root = insert!(path) }
end

Public Instance Methods

lookup(path, root=@root) click to toggle source

given a path like 'a/b/c', determine if it exists in the tree, by trying root['b’]

if root is a string, then it should be 'somedir/a'

if root['b'] is a string, then it should be 'somedir/a/b'

if root['b’] is a string, then it should be 'somedir/a/b/c'

in all cases, the return value is 'somedir/a/b/c'

# File lib/fastup.rb, line 71
def lookup(path, root=@root)
  case root
  when String
    if path.nil?
      return root
    else
      File.join(root, path)
    end
  when Hash
    head, rest = path.split(File::SEPARATOR, 2)
    lookup(rest, root[head])
  end
end

Private Instance Methods

insert!(target, root=@root) click to toggle source

Assumption: target is the shortest path not yet tried. If the shortest path cannot be linked directly, then if it's a directory, each element of the directory will be inserted, recursively.

# File lib/fastup.rb, line 91
def insert!(target, root=@root)
  case root
  when String
    # conflict; can't insert ontop of non-directory
    return root unless directory?(root) && directory?(target)

    newroot = {}
    each_entry(root) do |entry|
      newroot[entry] = File.join(root, entry)
    end
    insert! target, newroot
  when Hash
    # conflict; can't insert non-directory ontop of directory
    return root unless directory?(target)

    each_entry(target) do |entry|
      if root.has_key?(entry)
        root[entry] = insert! File.join(target, entry), root[entry]
      else
        root[entry] = File.join(target, entry)
      end
    end
    root
  end
end