class GodObject::FilePermissions::ComplexMode

An aggregate of Mode and SpecialMode to represent normal file permissions in a POSIX environment.

Attributes

group[RW]

@return [GodObject::FilePermissions::Mode] permissions for the owning

group
other[RW]

@return [GodObject::FilePermissions::Mode] permissions for everyone

else
special[RW]

@return [GodObject::FilePermissions::SpecialMode] special file flags

user[RW]

@return [GodObject::FilePermissions::Mode] permissions for the owner

Public Class Methods

build(mode) click to toggle source

@overload build(complex_mode)

Returns an existing instance of
  GodObject::FilePermissions::ComplexMode
@param [GodObject::FilePermissions::ComplexMode] complex_mode an
  already existing ComplexMode
@return [GodObject::FilePermissions::ComplexMode] the same
  ComplexMode object

@overload build(numeric)

Returns a new ComplexMode object with the given numeric
representation.
@param [Integer] numeric a numeric representation
@return [GodObject::FilePermissions::ComplexMode] a new ComplexMode
  object

@overload build(enabled_digits)

Returns a new ComplexMode object with the given enabled digits
@param [Array<:user_read, :user_write, :user_execute,
  :group_read, :group_write, :group_execute, :other_read,
  :other_write, :other_execute, :setuid, :setgid, :sticky>]
  enabled_digits a list of enabled digits
@return [GodObject::FilePermissions::ComplexMode] a new ComplexMode
  object
# File lib/god_object/file_permissions/complex_mode.rb, line 70
def build(mode)
  if mode.kind_of?(self)
    mode
  else
    new(mode)
  end
end
from_file(path, symlink_handling = :resolve_symlinks) click to toggle source

Creates a new complex mode from filesystem object given by path.

@param [Pathname, String] path path of the source filesystem object @param [:resolve_symlinks, :target_symlinks] symlink_handling if set

to :target_symlinks and the target is a symlink, the symlink will
not be resolved but is itself used as source. By default, the
symlink will be resolved
# File lib/god_object/file_permissions/complex_mode.rb, line 85
def from_file(path, symlink_handling = :resolve_symlinks)
  file = to_pathname(path)

  case symlink_handling
  when :resolve_symlinks
    new(file.stat.mode)
  when :target_symlinks
    new(file.lstat.mode)
  else
    raise ArgumentError, "Invalid symlink handling: #{symlink_handling.inspect}"
  end
end
new(*mode_components) click to toggle source

@overload initialize(numeric)

Returns a new ComplexMode object with the given numeric
representation.
@param [Integer] numeric a numeric representation
@return [GodObject::FilePermissions::ComplexMode] a new ComplexMode
  object

@overload initialize(enabled_digits)

Returns a new ComplexMode object with the given enabled digits
@param [Array<:user_read, :user_write, :user_execute, :group_read,
  :group_write, :group_execute, :other_read, :other_write,
  :other_execute, :setuid, :setgid, :sticky>] enabled_digits a list
  of enabled digits
@return [GodObject::FilePermissions::ComplexMode] a new ComplexMode
  object
# File lib/god_object/file_permissions/complex_mode.rb, line 114
def initialize(*mode_components)
  sub_mode_components = Hash.new{|hash, key| hash[key] = Set.new }

  if mode_components.size == 1 && mode_components.first.respond_to?(:to_int)
    integer = mode_components.first

    [:other, :group, :user, :special].each do |mode|
      sub_mode_components[mode] = integer & 0b111
      integer = integer >> 3 unless mode == :special
    end
  else
    if mode_components.size == 1 && mode_components.first.is_a?(Enumerable)
      mode_components = mode_components.first
    end

    mode_components.flatten.each do |digit|
      case digit
      when /^user_(.*)$/
        sub_mode_components[:user] << $1.to_sym
      when /^group_(.*)$/
        sub_mode_components[:group] << $1.to_sym
      when /^other_(.*)$/
        sub_mode_components[:other] << $1.to_sym
      else
        sub_mode_components[:special] << digit
      end
    end
  end

  @user    = Mode.new(sub_mode_components[:user])
  @group   = Mode.new(sub_mode_components[:group])
  @other   = Mode.new(sub_mode_components[:other])
  @special = SpecialMode.new(sub_mode_components[:special])
end

Public Instance Methods

assign_to_file(path, symlink_handling = :resolve_symlinks) click to toggle source

Assigns the mode to a filesystem object given by path.

@param [Pathname, String] path path of the target filesystem object @param [:resolve_symlinks, :target_symlinks] symlink_handling if set to

:target_symlinks and the target is a symlink, the symlink will not be
resolved but is itself used as target. By default, the symlink will
be resolved
# File lib/god_object/file_permissions/complex_mode.rb, line 156
def assign_to_file(path, symlink_handling = :resolve_symlinks)
  file = to_pathname(path)

  case symlink_handling
  when :resolve_symlinks
    file.chmod(to_i)
  when :target_symlinks
    begin
      file.lchmod(to_i)
    rescue ::NotImplementedError, Errno::ENOSYS
      raise NotImplementedError, "lchmod function is not available in current OS or Ruby environment"
    end
  else
    raise ArgumentError, "Invalid symlink handling: #{symlink_handling.inspect}"
  end
end
inspect() click to toggle source

Represents the ComplexMode as String for debugging.

@return [String] a String representation for debugging

# File lib/god_object/file_permissions/complex_mode.rb, line 176
def inspect
  "#<#{self.class}: #{to_s.inspect}>"
end
to_i() click to toggle source

Converts the ComplexMode to a four-digit octal representation

@return [Integer] four-digit octal representation

# File lib/god_object/file_permissions/complex_mode.rb, line 221
def to_i
  result = 0

  [@special, @user, @group, @other].each do |mode|
    result = (result << 3) | mode.to_i
  end

  result
end
to_s() click to toggle source

Represents the ComplexMode as String.

Uses the format used by the ‘ls` utility.

@return [String] a String representation

# File lib/god_object/file_permissions/complex_mode.rb, line 185
def to_s
  string = ''

  string << case [@special.setuid?, @user.execute?]
            when [true, true]
              @user.to_s[0..1] << 's'
            when [true, false]
              @user.to_s[0..1] << 'S'
            else
              @user.to_s
            end

  string << case [@special.setgid?, @group.execute?]
            when [true, true]
              @group.to_s[0..1] << 's'
            when [true, false]
              @group.to_s[0..1] << 'S'
            else
              @group.to_s
            end

  string << case [@special.sticky?, @other.execute?]
            when [true, true]
              @other.to_s[0..1] << 't'
            when [true, false]
              @other.to_s[0..1] << 'T'
            else
              @other.to_s
            end

  string
end