Class: Build::Files::Path
- Inherits:
-
Object
- Object
- Build::Files::Path
- Defined in:
- lib/build/files/path.rb,
lib/build/files/glob.rb,
lib/build/files/system.rb
Overview
Represents a file path with an absolute root and a relative offset:
Instance Attribute Summary collapse
-
#full_path ⇒ Object
readonly
Returns the value of attribute full_path.
-
#root ⇒ Object
readonly
Returns the value of attribute root.
Class Method Summary collapse
- .[](path) ⇒ Object
-
.components(path) ⇒ Object
Returns a list of components for a path, either represented as a Path instance or a String.
-
.expand(subpath, root = Dir.getwd) ⇒ Object
Expand a subpath within a given root, similar to ‘File.expand_path`.
- .join(root, relative_path) ⇒ Object
-
.prefix_length(a, b) ⇒ Object
Returns the length of the prefix which is shared by two strings.
- .relative_path(root, full_path) ⇒ Object
-
.shortest_path(path, root) ⇒ Object
Return the shortest relative path to get to path from root.
- .split(path) ⇒ Object
Instance Method Summary collapse
- #+(path) ⇒ Object
-
#/(path) ⇒ Object
Define a new root with a sub-path:.
- #==(other) ⇒ Object
- #append(extension) ⇒ Object
- #basename ⇒ Object
- #components ⇒ Object (also: #parts)
-
#directory? ⇒ Boolean
Checks if the path refers to a directory.
- #eql?(other) ⇒ Boolean
-
#exist? ⇒ Boolean
Checks if the file exists in the local file system.
- #for_appending ⇒ Object
- #for_reading ⇒ Object
- #for_writing ⇒ Object
- #glob(pattern) ⇒ Object
- #hash ⇒ Object
-
#initialize(full_path, root = nil, relative_path = nil) ⇒ Path
constructor
Both paths must be full absolute paths, and path must have root as an prefix.
- #inspect ⇒ Object
- #length ⇒ Object
-
#mkpath ⇒ Object
(also: #create)
Recursively create a directory hierarchy for the given path.
-
#modified_time ⇒ Object
The time the file was last modified.
-
#open(mode, &block) ⇒ Object
Open a file with the specified mode.
-
#read(mode = File::RDONLY) ⇒ Object
Read the entire contents of the file.
- #rebase(root) ⇒ Object
- #relative_parts ⇒ Object
- #relative_path ⇒ Object
-
#rm ⇒ Object
(also: #delete)
Recursively delete the given path and all contents.
- #shortest_path(root) ⇒ Object
- #start_with?(*args) ⇒ Boolean
- #to_path ⇒ Object
- #to_s ⇒ Object
- #to_str ⇒ Object
-
#touch ⇒ Object
Touch the file, changing it’s last modified time.
- #with(root: @root, extension: nil, basename: false) ⇒ Object
-
#write(buffer, mode = File::CREAT|File::TRUNC|File::WRONLY) ⇒ Object
Write a buffer to the file, creating it if it doesn’t exist.
Constructor Details
#initialize(full_path, root = nil, relative_path = nil) ⇒ Path
Both paths must be full absolute paths, and path must have root as an prefix.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/build/files/path.rb', line 75 def initialize(full_path, root = nil, relative_path = nil) # This is the object identity: @full_path = full_path if root @root = root @relative_path = relative_path else # Effectively dirname and basename: @root, _, @relative_path = full_path.rpartition(File::SEPARATOR) end # This improves the cost of hash/eql? slightly but the root cannot be deconstructed if it was an instance of Path. # @root = @root.to_s end |
Instance Attribute Details
#full_path ⇒ Object (readonly)
Returns the value of attribute full_path.
92 93 94 |
# File 'lib/build/files/path.rb', line 92 def full_path @full_path end |
#root ⇒ Object (readonly)
Returns the value of attribute root.
91 92 93 |
# File 'lib/build/files/path.rb', line 91 def root @root end |
Class Method Details
.[](path) ⇒ Object
70 71 72 |
# File 'lib/build/files/path.rb', line 70 def self.[] path self === path ? path : self.new(path.to_s) end |
.components(path) ⇒ Object
Returns a list of components for a path, either represented as a Path instance or a String.
39 40 41 42 43 44 45 |
# File 'lib/build/files/path.rb', line 39 def self.components(path) if Path === path path.components else path.split(File::SEPARATOR) end end |
.expand(subpath, root = Dir.getwd) ⇒ Object
Expand a subpath within a given root, similar to ‘File.expand_path`
163 164 165 166 167 168 169 |
# File 'lib/build/files/path.rb', line 163 def self.(subpath, root = Dir.getwd) if subpath.start_with? File::SEPARATOR self.new(subpath) else self.join(root, subpath) end end |
.join(root, relative_path) ⇒ Object
158 159 160 |
# File 'lib/build/files/path.rb', line 158 def self.join(root, relative_path) self.new(File.join(root, relative_path), root) end |
.prefix_length(a, b) ⇒ Object
Returns the length of the prefix which is shared by two strings.
34 35 36 |
# File 'lib/build/files/path.rb', line 34 def self.prefix_length(a, b) [a.size, b.size].min.times{|i| return i if a[i] != b[i]} end |
.relative_path(root, full_path) ⇒ Object
61 62 63 64 65 66 67 68 |
# File 'lib/build/files/path.rb', line 61 def self.relative_path(root, full_path) relative_offset = root.length # Deal with the case where the root may or may not end with the path separator: relative_offset += 1 unless root.end_with?(File::SEPARATOR) return full_path.slice(relative_offset..-1) end |
.shortest_path(path, root) ⇒ Object
Return the shortest relative path to get to path from root. Root should be a directory with which you are computing the relative path.
48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/build/files/path.rb', line 48 def self.shortest_path(path, root) path_components = Path.components(path) root_components = Path.components(root) # Find the common prefix: i = prefix_length(path_components, root_components) || 0 # The difference between the root path and the required path, taking into account the common prefix: up = root_components.size - i return File.join([".."] * up + path_components[i..-1]) end |
.split(path) ⇒ Object
25 26 27 28 29 30 31 |
# File 'lib/build/files/path.rb', line 25 def self.split(path) # Effectively dirname and basename: dirname, separator, filename = path.rpartition(File::SEPARATOR) filename, dot, extension = filename.rpartition('.') return dirname + separator, filename, dot + extension end |
Instance Method Details
#+(path) ⇒ Object
126 127 128 |
# File 'lib/build/files/path.rb', line 126 def +(path) self.class.new(File.join(@full_path, path), @root) end |
#/(path) ⇒ Object
Define a new root with a sub-path:
131 132 133 |
# File 'lib/build/files/path.rb', line 131 def /(path) self.class.new(File.join(self, path), self) end |
#==(other) ⇒ Object
199 200 201 |
# File 'lib/build/files/path.rb', line 199 def ==(other) self.to_s == other.to_s end |
#append(extension) ⇒ Object
122 123 124 |
# File 'lib/build/files/path.rb', line 122 def append(extension) self.class.new(@full_path + extension, @root) end |
#basename ⇒ Object
102 103 104 |
# File 'lib/build/files/path.rb', line 102 def basename self.parts.last end |
#components ⇒ Object Also known as: parts
98 99 100 |
# File 'lib/build/files/path.rb', line 98 def components @components ||= @full_path.split(File::SEPARATOR).freeze end |
#directory? ⇒ Boolean
Checks if the path refers to a directory.
59 60 61 |
# File 'lib/build/files/system.rb', line 59 def directory? File.directory? self end |
#eql?(other) ⇒ Boolean
195 196 197 |
# File 'lib/build/files/path.rb', line 195 def eql?(other) self.class.eql?(other.class) and @root.eql?(other.root) and @full_path.eql?(other.full_path) end |
#exist? ⇒ Boolean
Checks if the file exists in the local file system.
54 55 56 |
# File 'lib/build/files/system.rb', line 54 def exist? File.exist? self end |
#for_appending ⇒ Object
211 212 213 |
# File 'lib/build/files/path.rb', line 211 def for_appending [@full_path, File::CREAT|File::APPEND|File::WRONLY] end |
#for_reading ⇒ Object
203 204 205 |
# File 'lib/build/files/path.rb', line 203 def for_reading [@full_path, File::RDONLY] end |
#for_writing ⇒ Object
207 208 209 |
# File 'lib/build/files/path.rb', line 207 def for_writing [@full_path, File::CREAT|File::TRUNC|File::WRONLY] end |
#glob(pattern) ⇒ Object
26 27 28 |
# File 'lib/build/files/glob.rb', line 26 def glob(pattern) Glob.new(self, pattern) end |
#hash ⇒ Object
191 192 193 |
# File 'lib/build/files/path.rb', line 191 def hash [@root, @full_path].hash end |
#inspect ⇒ Object
187 188 189 |
# File 'lib/build/files/path.rb', line 187 def inspect "#{@root.inspect}/#{relative_path.inspect}" end |
#length ⇒ Object
94 95 96 |
# File 'lib/build/files/path.rb', line 94 def length @full_path.length end |
#mkpath ⇒ Object Also known as: create
Recursively create a directory hierarchy for the given path.
69 70 71 |
# File 'lib/build/files/system.rb', line 69 def mkpath FileUtils.mkpath self end |
#modified_time ⇒ Object
The time the file was last modified.
64 65 66 |
# File 'lib/build/files/system.rb', line 64 def modified_time File.mtime self end |
#open(mode, &block) ⇒ Object
Open a file with the specified mode.
30 31 32 |
# File 'lib/build/files/system.rb', line 30 def open(mode, &block) File.open(self, mode, &block) end |
#read(mode = File::RDONLY) ⇒ Object
Read the entire contents of the file.
35 36 37 38 39 |
# File 'lib/build/files/system.rb', line 35 def read(mode = File::RDONLY) open(mode) do |file| file.read end end |
#rebase(root) ⇒ Object
135 136 137 |
# File 'lib/build/files/path.rb', line 135 def rebase(root) self.class.new(File.join(root, relative_path), root) end |
#relative_parts ⇒ Object
116 117 118 119 120 |
# File 'lib/build/files/path.rb', line 116 def relative_parts dirname, _, basename = self.relative_path.rpartition(File::SEPARATOR) return dirname, basename end |
#relative_path ⇒ Object
112 113 114 |
# File 'lib/build/files/path.rb', line 112 def relative_path @relative_path ||= Path.relative_path(@root.to_s, @full_path).freeze end |
#rm ⇒ Object Also known as: delete
Recursively delete the given path and all contents.
76 77 78 |
# File 'lib/build/files/system.rb', line 76 def rm FileUtils.rm_rf self end |
#shortest_path(root) ⇒ Object
171 172 173 |
# File 'lib/build/files/path.rb', line 171 def shortest_path(root) self.class.shortest_path(self, root) end |
#start_with?(*args) ⇒ Boolean
106 107 108 |
# File 'lib/build/files/path.rb', line 106 def start_with?(*args) @full_path.start_with?(*args) end |
#to_path ⇒ Object
179 180 181 |
# File 'lib/build/files/path.rb', line 179 def to_path @full_path end |
#to_s ⇒ Object
183 184 185 |
# File 'lib/build/files/path.rb', line 183 def to_s @full_path end |
#to_str ⇒ Object
175 176 177 |
# File 'lib/build/files/path.rb', line 175 def to_str @full_path end |
#touch ⇒ Object
Touch the file, changing it’s last modified time.
49 50 51 |
# File 'lib/build/files/system.rb', line 49 def touch FileUtils.touch self end |
#with(root: @root, extension: nil, basename: false) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/build/files/path.rb', line 139 def with(root: @root, extension: nil, basename: false) relative_path = self.relative_path if basename dirname, filename, _ = self.class.split(relative_path) # Replace the filename if the basename is supplied: filename = basename if basename.is_a? String relative_path = dirname + filename end if extension relative_path = relative_path + extension end self.class.new(File.join(root, relative_path), root, relative_path) end |
#write(buffer, mode = File::CREAT|File::TRUNC|File::WRONLY) ⇒ Object
Write a buffer to the file, creating it if it doesn’t exist.
42 43 44 45 46 |
# File 'lib/build/files/system.rb', line 42 def write(buffer, mode = File::CREAT|File::TRUNC|File::WRONLY) open(mode) do |file| file.write(buffer) end end |