Class: Chef::Util::PathHelper

Inherits:
Object
  • Object
show all
Defined in:
lib/chef/util/path_helper.rb

Constant Summary collapse

WIN_MAX_PATH =

Maximum characters in a standard Windows path (260 including drive letter and NUL)

259

Class Method Summary collapse

Class Method Details

.canonical_path(path, add_prefix = true) ⇒ Object

Produces a comparable path.

Raises:

  • (NotImplementedError)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/chef/util/path_helper.rb', line 68

def self.canonical_path(path, add_prefix=true)
  # Rather than find an equivalent for File.absolute_path on 1.8.7, just bail out
  raise NotImplementedError, "This feature is not supported on Ruby versions < 1.9" if RUBY_VERSION.to_f < 1.9

  # First remove extra separators and resolve any relative paths
  abs_path = File.absolute_path(path)

  if Chef::Platform.windows?
    # Add the \\?\ API prefix on Windows unless add_prefix is false
    # Downcase on Windows where paths are still case-insensitive
    abs_path.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR)
    if add_prefix && abs_path !~ /^\\\\?\\/
      abs_path.insert(0, "\\\\?\\")
    end

    abs_path.downcase!
  end

  abs_path
end

.paths_eql?(path1, path2) ⇒ Boolean

Returns:

  • (Boolean)


89
90
91
# File 'lib/chef/util/path_helper.rb', line 89

def self.paths_eql?(path1, path2)
  canonical_path(path1) == canonical_path(path2)
end

.printable?(string) ⇒ Boolean

Returns:

  • (Boolean)


57
58
59
60
61
62
63
64
65
# File 'lib/chef/util/path_helper.rb', line 57

def self.printable?(string)
  # returns true if string is free of non-printable characters (escape sequences)
  # this returns false for whitespace escape sequences as well, e.g. \n\t
  if string =~ /[^[:print:]]/
    false
  else
    true
  end
end

.validate_path(path) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/chef/util/path_helper.rb', line 28

def self.validate_path(path)
  if Chef::Platform.windows?
    unless printable?(path)
      msg = "Path '#{path}' contains non-printable characters. Check that backslashes are escaped with another backslash (e.g. C:\\\\Windows) in double-quoted strings."
      Chef::Log.error(msg)
      raise Chef::Exceptions::ValidationFailed, msg
    end

    if windows_max_length_exceeded?(path)
      Chef::Log.debug("Path '#{path}' is longer than #{WIN_MAX_PATH}, prefixing with'\\\\?\\'")
      path.insert(0, "\\\\?\\")
    end
  end

  path
end

.windows_max_length_exceeded?(path) ⇒ Boolean

Returns:

  • (Boolean)


45
46
47
48
49
50
51
52
53
54
55
# File 'lib/chef/util/path_helper.rb', line 45

def self.windows_max_length_exceeded?(path)
  # Check to see if paths without the \\?\ prefix are over the maximum allowed length for the Windows API
  # http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
  unless path =~ /^\\\\?\\/
    if path.length > WIN_MAX_PATH
      return true
    end
  end

  false
end