module Garcon::FileHelper

Class methods that are added when you include Garcon

Public Instance Methods

all_files_under(path, &ignore) click to toggle source

Get a recusive list of files inside a path.

@param [String] path

some path string or Pathname

@param [Block] ignore

a proc/block that returns true if a given path should be ignored, if a
path is ignored, nothing below it will be searched either.

@return [Array<Pathname>]

array of Pathnames for each file (no directories)
# File lib/garcon/utility/file_helper.rb, line 115
def all_files_under(path, &ignore)
  path = Pathname(path)

  if path.directory?
    path.children.flat_map do |child|
      all_files_under(child, &ignore)
    end.compact
  elsif path.file?
    if block_given? && ignore.call(path)
      []
    else
      [path]
    end
  else
    []
  end
end
atomic_id() click to toggle source
# File lib/garcon/utility/file_helper.rb, line 174
def atomic_id
  @atomic_id ||= 0
  @atomic_id += 1
end
atomic_open(file, mode='r', temp_dir = nil, &block) click to toggle source

Same as ‘File.open`, but acts on a temporary copy of named file, copying the file back to the original on completion.

@uncommon

require 'facets/fileutils/atomic_open'
# File lib/garcon/utility/file_helper.rb, line 185
def atomic_open(file, mode='r', temp_dir = nil, &block)
  temp_dir  = temp_dir || Dir.tmpdir
  temp_file = Tempfile.new("#{aomtic_id}-" + File.basename(file), temp_dir)
  FileUtils.cp(file, temp_file) if File.exist?(file)
  File.open(temp_file, mode, &block)
  FileUtils.cp(temp_file, file)
end
atomic_write(file, temp_dir = nil) { |temp_file| ... } click to toggle source

Write to a file atomically. Useful for situations where you don’t want other processes or threads to see half-written files.

File.atomic_write("important.txt") do |file|
  file.write("hello")
end

If your temporary directory is not on the same filesystem as the file you’re trying to write, you can provide a different temporary directory.

File.atomic_write("important.txt", "tmp") do |file|
  file.write("hello")
end
# File lib/garcon/utility/file_helper.rb, line 207
def atomic_write(file, temp_dir = nil)
  temp_dir  = temp_dir || Dir.tmpdir
  temp_file = Tempfile.new(File.basename(file), temp_dir)

  yield temp_file
  temp_file.close

  begin
    old_stat = File.stat(file)
  rescue Errno::ENOENT
    ext = "#{Thread.current.object_id}.#{Process.pid}.#{rand(1000000)}"
    check_name = File.join(File.dirname(file), ".permissions_check.#{ext}")
    File.open(check_name, "w") { }
    old_stat = File.stat(check_name)
    File.unlink(check_name)
  end

  FileUtils.mv(temp_file.path, file)
  File.chown(old_stat.uid, old_stat.gid, file)
  File.chmod(old_stat.mode, file)
end
command_in_path?(command) click to toggle source

Checks in PATH returns true if the command is found.

@param [String] command

The name of the command to look for.

@return [Boolean]

True if the command is found in the path.
# File lib/garcon/utility/file_helper.rb, line 39
def command_in_path?(command)
  found = ENV['PATH'].split(File::PATH_SEPARATOR).map do |p|
    File.exist?(File.join(p, command))
  end
  found.include?(true)
end
normalize_path(path) click to toggle source

Normalize a path to not include a leading slash

@param [String] path

@return [String]

# File lib/garcon/utility/file_helper.rb, line 170
def normalize_path(path)
  path.sub(%r{^/}, '').tr('', '')
end
path_match(matcher, path) click to toggle source

Takes an object, which can be a literal string or a string containing glob expressions, or a regexp, or a proc, or anything else that responds to match or call, and returns whether or not the given path matches that matcher.

@param [String, match, call] matcher

a matcher String, RegExp, Proc, etc.

@param [String] path

a path as a string

@return [Boolean]

whether the path matches the matcher
# File lib/garcon/utility/file_helper.rb, line 147
def path_match(matcher, path)
  case
  when matcher.is_a?(String)
    if matcher.include? '*'
      File.fnmatch(matcher, path)
    else
      path == matcher
    end
  when matcher.respond_to?(:match)
    !matcher.match(path).nil?
  when matcher.respond_to?(:call)
    matcher.call(path)
  else
    File.fnmatch(matcher.to_s, path)
  end
end
read_list(filepath, options={}) click to toggle source

Reads in a file, removes blank lines and removes lines starting with ‘#’ and then returns an array of all the remaining lines.

Thr remark indicator can be overridden via the :omit: option, which can be a regualar expression or a string that is match against the start of a line.

# File lib/garcon/utility/file_helper.rb, line 236
def read_list(filepath, options={})
  chomp = options[:chomp]
  omit  = case options[:omit]
          when Regexp
            omit
          when nil
            /^\s*\#/
          else
            /^\s*#{Regexp.escape(omit)}/
          end

  list = []
  readlines(filepath).each do |line|
    line = line.strip.chomp(chomp)
    next if line.empty?
    next if omit === line
    list << line
  end
  list
end
whereis(prog, path = ENV['PATH']) { |f| ... } click to toggle source

In block form, yields each program within path. In non-block form, returns an array of each program within path. Returns nil if not found found.

@example

whereis('ruby')
  # => [
      [0] "/opt/chefdk/embedded/bin/ruby",
      [1] "/usr/bin/ruby",
      [2] "/Users/sharding/.rvm/rubies/ruby-2.2.0/bin/ruby",
      [3] "/usr/bin/ruby"
  ]

@param [String] cmd

The name of the command to find.

@param [String] path

The path to search for the command.

@return [String, Array, NilClass]

@api public

# File lib/garcon/utility/file_helper.rb, line 88
def whereis(prog, path = ENV['PATH'])
  dirs = []
  path.split(File::PATH_SEPARATOR).each do |dir|
    f = File.join(dir,prog)
    if File.executable?(f) && !File.directory?(f)
      if block_given?
        yield f
      else
        dirs << f
      end
    end
  end

  dirs.empty? ? nil : dirs
end
which(prog, path = ENV['PATH']) click to toggle source

Looks for the first occurrence of program within path.

@param [String] cmd

The name of the command to find.

@param [String] path

The path to search for the command.

@return [String, NilClass]

@api public

# File lib/garcon/utility/file_helper.rb, line 57
def which(prog, path = ENV['PATH'])
  path.split(File::PATH_SEPARATOR).each do |dir|
    file = File.join(dir, prog)
    return file if File.executable?(file) && !File.directory?(file)
  end

  nil
end