module Garcon::FileHelper
Class methods that are added when you include Garcon
Public Instance Methods
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
# File lib/garcon/utility/file_helper.rb, line 174 def atomic_id @atomic_id ||= 0 @atomic_id += 1 end
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
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
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 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
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
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
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
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