module Sprockets::PathUtils

def absolute_path?(path)

On Windows, ALT_SEPARATOR is \
def absolute_path?(path)
  path[0] == File::SEPARATOR || path[0] == File::ALT_SEPARATOR
end

def absolute_path?(path)

def absolute_path?(path)
  path[0] == File::SEPARATOR
end

def atomic_write(filename)

Returns nothing.

end
file.write('hello')
Utils.atomic_write('important.file') do |file|

don't want other processes or threads to see half-written files.
Internal: Write to a file atomically. Useful for situations where you
def atomic_write(filename)
  tmpname = [
    File.dirname(filename),
    Thread.current.object_id,
    Process.pid,
    rand(1000000)
  ].join('.')
  File.open(tmpname, 'wb+') do |f|
    yield f
  end
  FileUtils.mv(tmpname, filename)
ensure
  FileUtils.rm(tmpname) if File.exist?(tmpname)
end

def entries(path)

Returns an empty `Array` if the directory does not exist.

path - String directory path

swap files.
Internal: A version of `Dir.entries` that filters out `.` files and `~`
def entries(path)
  if File.directory?(path)
    Dir.entries(path).reject { |entry| entry =~ /^\.|~$|^\#.*\#$/ }.sort
  else
    []
  end
end

def file?(path)

Returns true path exists and is a file.

path - String file path.

Internal: Like `File.file?`.
def file?(path)
  if stat = self.stat(path)
    stat.file?
  else
    false
  end
end

def path_extnames(path)

Returns an Array of String extnames.

path - String

Internal: Get path's extensions.
def path_extnames(path)
  File.basename(path).scan(/\.[^.]+/)
end

def paths_split(paths, filename)

Returns [String root, String path]

filename - String path of file expected to be in one of the paths.
paths - Array of String paths

Internal: Detect root path and base for file in a set of paths.
def paths_split(paths, filename)
  paths.each do |path|
    if subpath = split_subpath(path, filename)
      return path, subpath
    end
  end
  nil
end

def relative_path?(path)

Returns true if path is relative, otherwise false.

path - String path.

Starts with "./" or "../".
Internal: Check if path is explicitly relative.
def relative_path?(path)
  path =~ /^\.\.?($|\/)/ ? true : false
end

def split_subpath(path, subpath)

subpath is outside of path.
Returns relative String path if subpath is a subpath of path, or nil if

subpath - String subpath of path
path - String path

Internal: Get relative path for root path and subpath.
def split_subpath(path, subpath)
  path = File.join(path, '')
  if subpath.start_with?(path)
    subpath[path.length..-1]
  else
    nil
  end
end

def stat(path)

Returns nil if the file does not exist.

path - String file or directory path

Internal: Like `File.stat`.
def stat(path)
  if File.exist?(path)
    File.stat(path.to_s)
  else
    nil
  end
end

def stat_directory(dir)

Returns an Enumerator of [path, stat].

dir - A String directory

Internal: Stat all the files under a directory.
def stat_directory(dir)
  return to_enum(__method__, dir) unless block_given?
  self.entries(dir).each do |entry|
    path = File.join(dir, entry)
    if stat = self.stat(path)
      yield path, stat
    end
  end
  nil
end

def stat_tree(dir, &block)

Returns an Enumerator of [path, stat].

dir - A String directory

Internal: Recursive stat all the files under a directory.
def stat_tree(dir, &block)
  return to_enum(__method__, dir) unless block_given?
  self.stat_directory(dir) do |path, stat|
    yield path, stat
    if stat.directory?
      stat_tree(path, &block)
    end
  end
  nil
end