module Wright::Util::File
Various file methods.
Constants
- MODE_MAP
- USER_MAP
Public Class Methods
Expands tilde symbols in file paths. Path elements other than the first one are left alone.
@param path [String] the file path
@example
Wright::Util::File.expand_tilde_path('~root/foo') # => "/root/foo" Wright::Util::File.expand_tilde_path('~root/foo/..') # => "/root/foo/.." Wright::Util::File.expand_tilde_path('../foo/bar') # => "../foo/bar"
@return [String] the expanded path
# File lib/wright/util/file.rb, line 228 def self.expand_tilde_path(path) return path unless path.start_with?('~') first, *rest = path.split(::File::SEPARATOR) ::File.join(::File.expand_path(first), rest) end
Returns a file's owner.
@param path [String] the file's path
@example
FileUtils.touch('foo') FileUtils.chown(0, 0, 'foo') Wright::Util::File.file_group('foo') # => 0 Wright::Util::File.file_group('nonexistent') # => nil
@return [Integer] the file owner's uid or nil if the file does
not exist.
# File lib/wright/util/file.rb, line 208 def self.file_group(path) ::File.exist?(path) ? ::File.stat(path).gid : nil end
Returns a file's current mode.
@param path [String] the file's path
@example
FileUtils.touch('foo') FileUtils.chmod(0644, 'foo') Wright::Util::File.file_mode('foo').to_s(8) # => "644"
@return [Integer] the file mode as an integer or nil
if the
file does not exist
# File lib/wright/util/file.rb, line 170 def self.file_mode(path) ::File.exist?(path) ? (::File.stat(path).mode & 07777) : nil end
Returns a file's owner.
@param path [String] the file's path
@example
FileUtils.touch('foo') FileUtils.chown(0, 0, 'foo') Wright::Util::File.file_owner('foo') # => 0 Wright::Util::File.file_owner('nonexistent') # => nil
@return [Integer] the file owner's uid or nil
if the file
does not exist
# File lib/wright/util/file.rb, line 189 def self.file_owner(path) ::File.exist?(path) ? ::File.stat(path).uid : nil end
Creates symlinks without descending into directories.
If the file denoted by link_name is a symlink to a directory, {ln_sfn} does not descend into it. Behaves similar to GNU ln(1) or OpenBSD ln(1) when using +ln -sfn target link_name+.
@param target [String] the link target @param link_name [String] the link name
@return [void]
# File lib/wright/util/file.rb, line 245 def self.ln_sfn(target, link_name) if ::File.symlink?(link_name) && ::File.directory?(link_name) FileUtils.rm(link_name) end FileUtils.ln_sf(target, link_name) end
Converts a numeric mode string to an integer mode.
@param mode [String, to_i] the numeric mode string
@example
Wright::Util::File.numeric_mode_to_i('0600').to_s(8) # => "600" Wright::Util::File.numeric_mode_to_i('644').to_s(8) # => "644" Wright::Util::File.numeric_mode_to_i(0644).to_s(8) # => "644" Wright::Util::File.numeric_mode_to_i('invalid_mode').to_s(8) # => nil
@return [Integer] the mode in integer form or nil
if the
mode could not be converted
# File lib/wright/util/file.rb, line 145 def self.numeric_mode_to_i(mode) return mode.to_i unless mode.is_a?(String) mode =~ /\A[0-7]{3,4}\Z/ ? mode.to_i(8) : nil end
Converts a symbolic mode string to an integer mode value.
@param mode [String] the symbolic mode string @param base_mode [Integer] the base mode @param filetype [Symbol] the filetype
@example
Wright::Util::File.symbolic_mode_to_i('u=rw,go=r', 0400).to_s(8) # => "644" Wright::Util::File.symbolic_mode_to_i('u=rw,g+r', 0200).to_s(8) # => "640"
@return [Integer] the integer mode
# File lib/wright/util/file.rb, line 76 def self.symbolic_mode_to_i(mode, base_mode, filetype = :file) is_directory = (filetype == :directory) unless symbolic_mode?(mode) fail ArgumentError, "Invalid file mode \"#{mode}\"" end mode_i = base_mode mode.split(/,/).each do |mode_clause| mode_i = mode_clause_to_i(mode_clause, mode_i, is_directory) end mode_i end
Private Class Methods
# File lib/wright/util/file.rb, line 114 def self.apply_user_mode_masks(base_mode_i, user_mask, op, mode_mask) case op when '=' (base_mode_i & ~user_mask) | (user_mask & mode_mask) when '+' base_mode_i | (user_mask & mode_mask) when '-' base_mode_i & ~(user_mask & mode_mask) end end
Converts a single symbolic mode clause to an integer mode value.
@param mode_clause [String] the symbolic mode clause @param base_mode_i [Integer] the integer base mode @param is_directory [Bool] denotes whether the mode_clause
should be treated as a symbolic directory mode clause
@example
Wright::Util::File.mode_clause_to_i('g+r', 0600, false).to_s(8) # => "640" Wright::Util::File.mode_clause_to_i('+rw', 0600, false).to_s(8) # => "666"
@return [Integer] the mode clause as an integer
# File lib/wright/util/file.rb, line 104 def self.mode_clause_to_i(mode_clause, base_mode_i, is_directory) mode_clause = "a#{mode_clause}" if mode_clause =~ /\A[+-=]/ who, op, perm = mode_clause.split(/([+-=])/) perm ||= '' user_mask = user_mask(who) mode_mask = mode_mask(perm, is_directory) apply_user_mode_masks(base_mode_i, user_mask, op, mode_mask) end
# File lib/wright/util/file.rb, line 56 def self.mode_mask(mode, is_directory) mode.tr!('X', 'x') if is_directory mode.chars.reduce(0) { |a, e| a | MODE_MAP[e].to_i } end
# File lib/wright/util/file.rb, line 150 def self.symbolic_mode?(mode_str) return true if mode_str.empty? mode_fragment = /([augo]*[+-=][rwxXst]*)/ mode_re = /\A#{mode_fragment}(,#{mode_fragment})*\Z/ !(mode_str =~ mode_re).nil? end
# File lib/wright/util/file.rb, line 42 def self.user_mask(target) target.chars.reduce(0) { |a, e| a | USER_MAP[e] } end