Module: Garcon::FileHelper

Extended by:
FileHelper
Included in:
FileHelper, Provider, Resource
Defined in:
lib/garcon/utility/file_helper.rb

Overview

Class methods that are added when you include Garcon

Instance Method Summary collapse

Instance Method Details

#all_files_under(path, &ignore) ⇒ Array<Pathname>

Get a recusive list of files inside a path.

Parameters:

  • path (String)

    some path string or Pathname

  • ignore (Block)

    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.

Returns:

  • (Array<Pathname>)

    array of Pathnames for each file (no directories)



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# 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_idObject



174
175
176
177
# 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) ⇒ Object

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



185
186
187
188
189
190
191
# 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| ... } ⇒ Object

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

Yields:

  • (temp_file)


207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# 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) ⇒ Boolean

Checks in PATH returns true if the command is found.

Parameters:

  • command (String)

    The name of the command to look for.

Returns:

  • (Boolean)

    True if the command is found in the path.



39
40
41
42
43
44
# 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) ⇒ String

Normalize a path to not include a leading slash

Parameters:

Returns:



170
171
172
# File 'lib/garcon/utility/file_helper.rb', line 170

def normalize_path(path)
  path.sub(%r{^/}, '').tr('', '')
end

#path_match(matcher, path) ⇒ Boolean

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.

Parameters:

  • matcher (String, #match, #call)

    a matcher String, RegExp, Proc, etc.

  • path (String)

    a path as a string

Returns:

  • (Boolean)

    whether the path matches the matcher



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# 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 = {}) ⇒ Object

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.



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# 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']) ⇒ String, ...

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.

Examples:

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"
  ]

Parameters:

  • cmd (String)

    The name of the command to find.

  • path (String) (defaults to: ENV['PATH'])

    The path to search for the command.

Returns:



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# 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']) ⇒ String, NilClass

Looks for the first occurrence of program within path.

Parameters:

  • cmd (String)

    The name of the command to find.

  • path (String) (defaults to: ENV['PATH'])

    The path to search for the command.

Returns:



57
58
59
60
61
62
63
64
# 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