Class: Aibika::Pathname

Inherits:
Object
  • Object
show all
Defined in:
lib/aibika/pathname.rb

Overview

Path handling class. Ruby’s Pathname class is not used because it is case sensitive and doesn’t handle paths with mixed path separators.

Constant Summary collapse

SEPARATOR_PAT =

}

/[#{Regexp.quote File::ALT_SEPARATOR}#{Regexp.quote File::SEPARATOR}]/.freeze
ABSOLUTE_PAT =
/\A([A-Z]:)?#{SEPARATOR_PAT}/i.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Pathname

Returns a new instance of Pathname.



22
23
24
# File 'lib/aibika/pathname.rb', line 22

def initialize(path)
  @path = path&.encode('UTF-8')
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



16
17
18
# File 'lib/aibika/pathname.rb', line 16

def path
  @path
end

Class Method Details

.pathequal(path_a, path_b) ⇒ Object



12
13
14
# File 'lib/aibika/pathname.rb', line 12

def self.pathequal(path_a, path_b)
  path_a.downcase == path_b.downcase
end

.pwdObject



8
9
10
# File 'lib/aibika/pathname.rb', line 8

def self.pwd
  Pathname.new(Dir.pwd.encode('UTF-8'))
end

Instance Method Details

#/(other) ⇒ Object

Join two pathnames together. Returns the right-hand side if it is an absolute path. Otherwise, returns the full path of the left + right.



62
63
64
65
66
67
68
69
# File 'lib/aibika/pathname.rb', line 62

def /(other)
  other = Aibika.Pathname(other)
  if other.absolute?
    other
  else
    Aibika.Pathname("#{@path}/#{other.path}")
  end
end

#<=>(other) ⇒ Object



119
120
121
# File 'lib/aibika/pathname.rb', line 119

def <=>(other)
  @path.casecmp(other.path)
end

#==(other) ⇒ Object



111
112
113
# File 'lib/aibika/pathname.rb', line 111

def ==(other)
  to_posix.downcase == other.to_posix.downcase
end

#=~(other) ⇒ Object



115
116
117
# File 'lib/aibika/pathname.rb', line 115

def =~(other)
  @path =~ other
end

#absolute?Boolean

Returns:

  • (Boolean)


135
136
137
# File 'lib/aibika/pathname.rb', line 135

def absolute?
  @path =~ ABSOLUTE_PAT
end

#append_to_filename!(append) ⇒ Object



71
72
73
# File 'lib/aibika/pathname.rb', line 71

def append_to_filename!(append)
  @path.sub!(/(\.[^.]*?|)$/) { append.to_s + ::Regexp.last_match(1) }
end

#basenameObject



143
144
145
# File 'lib/aibika/pathname.rb', line 143

def basename
  Pathname.new(File.basename(@path))
end

#directory?Boolean

Returns:

  • (Boolean)


131
132
133
# File 'lib/aibika/pathname.rb', line 131

def directory?
  File.directory?(@path)
end

#dirnameObject



139
140
141
# File 'lib/aibika/pathname.rb', line 139

def dirname
  Pathname.new(File.dirname(@path))
end

#entriesObject



87
88
89
# File 'lib/aibika/pathname.rb', line 87

def entries
  Dir.entries(@path).map { |e| self / e.encode('UTF-8') }
end

#exist?Boolean

Returns:

  • (Boolean)


123
124
125
# File 'lib/aibika/pathname.rb', line 123

def exist?
  File.exist?(@path)
end

#expand(dir = nil) ⇒ Object



147
148
149
# File 'lib/aibika/pathname.rb', line 147

def expand(dir = nil)
  Pathname.new(File.expand_path(@path, dir && Aibika.Pathname(dir)))
end

#ext(new_ext = nil) ⇒ Object



75
76
77
78
79
80
81
# File 'lib/aibika/pathname.rb', line 75

def ext(new_ext = nil)
  if new_ext
    Pathname.new(@path.sub(/(\.[^.]*?)?$/) { new_ext })
  else
    File.extname(@path)
  end
end

#ext?(expected_ext) ⇒ Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/aibika/pathname.rb', line 83

def ext?(expected_ext)
  Pathname.pathequal(ext, expected_ext)
end

#file?Boolean

Returns:

  • (Boolean)


127
128
129
# File 'lib/aibika/pathname.rb', line 127

def file?
  File.file?(@path)
end

#find_all_files(reg) ⇒ Object

Recursively find all files which match a specified regular expression.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/aibika/pathname.rb', line 93

def find_all_files(reg)
  entries.map do |pn|
    if pn.directory?
      if pn.basename =~ /^\.\.?$/
        []
      else
        pn.find_all_files(reg)
      end
    elsif pn.file?
      if pn.basename =~ reg
        pn
      else
        []
      end
    end
  end.flatten
end

#relative_path_from(other) ⇒ Object

Compute the relative path from the ‘src’ path (directory) to ‘tgt’ (directory or file). Return the absolute path to ‘tgt’ if it can’t be reached from ‘src’.



37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/aibika/pathname.rb', line 37

def relative_path_from(other)
  a = @path.split(SEPARATOR_PAT)
  b = other.path.split(SEPARATOR_PAT)
  while a.first && b.first && Pathname.pathequal(a.first, b.first)
    a.shift
    b.shift
  end
  return other if Pathname.new(b.first).absolute?

  b.size.times { a.unshift '..' }
  Pathname.new(a.join('/'))
end

#sizeObject



151
152
153
# File 'lib/aibika/pathname.rb', line 151

def size
  File.size(@path)
end

#subpath?(other) ⇒ Boolean

Determines if ‘src’ is contained in ‘tgt’ (i.e. it is a subpath of ‘tgt’). Both must be absolute paths and not contain ‘..’

Returns:

  • (Boolean)


52
53
54
55
56
57
# File 'lib/aibika/pathname.rb', line 52

def subpath?(other)
  other = Aibika.Pathname(other)
  src_normalized = to_posix.downcase
  tgt_normalized = other.to_posix.downcase
  src_normalized =~ /^#{Regexp.escape tgt_normalized}#{SEPARATOR_PAT}/i
end

#to_nativeObject



26
27
28
# File 'lib/aibika/pathname.rb', line 26

def to_native
  @path.tr File::SEPARATOR, File::ALT_SEPARATOR
end

#to_posixObject Also known as: to_s, to_str



30
31
32
# File 'lib/aibika/pathname.rb', line 30

def to_posix
  @path.tr File::ALT_SEPARATOR, File::SEPARATOR
end