Method: Chef::ChefFS::PathUtils.realest_path

Defined in:
lib/chef/chef_fs/path_utils.rb

.realest_path(path, cwd = Dir.pwd) ⇒ Object

Given a path which may only be partly real (i.e. /x/y/z when only /x exists, or /x/y/*/blah when /x/y/z/blah exists), call File.realpath on the biggest part that actually exists. The paths operated on here are not Chef-FS paths. These are OS paths that may contain symlinks but may not also fully exist.

If /x is a symlink to /foo_bar, and has no subdirectories, then: PathUtils.realest_path(‘/x/y/z’) == ‘/foo_bar/y/z’ PathUtils.realest_path(‘/x/*/z’) == ‘/foo_bar/*/z’ PathUtils.realest_path(‘/*/y/z’) == ‘/*/y/z’

TODO: Move this to wherever util/path_helper is these days.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/chef/chef_fs/path_utils.rb', line 78

def self.realest_path(path, cwd = Dir.pwd)
  path = File.expand_path(path, cwd)
  parent_path = File.dirname(path)
  suffix = []

  # File.dirname happens to return the path as its own dirname if you're
  # at the root (such as at \\foo\bar, C:\ or /)
  until parent_path == path
    # This can occur if a path such as "C:" is given.  Ruby gives the parent as "C:."
    # for reasons only it knows.
    raise ArgumentError "Invalid path segment #{path}" if parent_path.length > path.length

    begin
      path = File.realpath(path)
      break
    rescue Errno::ENOENT, Errno::EINVAL
      suffix << File.basename(path)
      path = parent_path
      parent_path = File.dirname(path)
    end
  end
  File.join(path, *suffix.reverse)
end