class Build::Files::Path
Represents a file path with an absolute root and a relative offset:
Attributes
Public Class Methods
# File lib/build/files/path.rb, line 88 def self.[] path self === path ? path : self.new(path.to_s) end
Returns a list of components for a path, either represented as a Path
instance or a String.
# File lib/build/files/path.rb, line 43 def self.components(path) if Path === path path.components else path.split(File::SEPARATOR) end end
# File lib/build/files/path.rb, line 25 def self.current self.new(::Dir.pwd) end
Expand a path within a given root.
# File lib/build/files/path.rb, line 206 def self.expand(path, root = Dir.getwd) if path.start_with?(File::SEPARATOR) self.new(path) else self.join(root, path) end end
# File lib/build/files/path.rb, line 201 def self.join(root, relative_path) self.new(File.join(root, relative_path), root) end
Both paths must be full absolute paths, and path must have root as an prefix.
# File lib/build/files/path.rb, line 93 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 end
Returns the length of the prefix which is shared by two strings.
# File lib/build/files/path.rb, line 38 def self.prefix_length(a, b) [a.size, b.size].min.times{|i| return i if a[i] != b[i]} end
# File lib/build/files/path.rb, line 79 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
# File lib/build/files/path.rb, line 51 def self.root(path) if Path === path path.root else File.dirname(path) end end
Return the shortest relative path to get to path from root. Root should be a directory with which you are computing the relative path.
# File lib/build/files/path.rb, line 60 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 components = [".."] * up + path_components[i..-1] if components.empty? return "." else return File.join(components) end end
# File lib/build/files/path.rb, line 29 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
Public Instance Methods
Add a path component to the current path. @param path [String, nil] (Optionally) the path to append.
# File lib/build/files/path.rb, line 160 def +(path) if path self.class.new(File.join(@full_path, path), @root) else self end end
Use the current path to define a new root, with an optional sub-path. @param path [String, nil] (Optionally) the path to append.
# File lib/build/files/path.rb, line 170 def /(path) if path self.class.new(File.join(self, path), self) else self.class.new(self, self) end end
# File lib/build/files/path.rb, line 245 def <=>(other) self.to_s <=> other.to_s end
# File lib/build/files/path.rb, line 154 def append(extension) self.class.new(@full_path + extension, @root) end
# File lib/build/files/path.rb, line 119 def basename self.parts.last end
# File lib/build/files/path.rb, line 115 def components @components ||= @full_path.split(File::SEPARATOR).freeze end
Checks if the path refers to a directory.
# File lib/build/files/system.rb, line 63 def directory? File.directory? self end
# File lib/build/files/path.rb, line 239 def eql?(other) self.class.eql?(other.class) and @root.eql?(other.root) and @full_path.eql?(other.full_path) end
Checks if the file exists in the local file system.
# File lib/build/files/system.rb, line 58 def exist? File.exist? self end
# File lib/build/files/system.rb, line 67 def file? File.file? self end
# File lib/build/files/path.rb, line 264 def for_appending [@full_path, File::CREAT|File::APPEND|File::WRONLY] end
# File lib/build/files/path.rb, line 256 def for_reading [@full_path, File::RDONLY] end
# File lib/build/files/path.rb, line 260 def for_writing [@full_path, File::CREAT|File::TRUNC|File::WRONLY] end
# File lib/build/files/glob.rb, line 26 def glob(pattern) Glob.new(self, pattern) end
# File lib/build/files/path.rb, line 235 def hash [@root, @full_path].hash end
# File lib/build/files/path.rb, line 231 def inspect "#{@root.inspect}/#{relative_path.inspect}" end
# File lib/build/files/path.rb, line 109 def length @full_path.length end
# File lib/build/files/paths.rb, line 74 def list(*relative_paths) Paths.directory(self, relative_paths) end
Match a path with a given pattern, using `File#fnmatch`.
# File lib/build/files/path.rb, line 250 def match(pattern, flags = 0) path = pattern.start_with?('/') ? full_path : relative_path return File.fnmatch(pattern, path, flags) end
Recursively create a directory hierarchy for the given path.
# File lib/build/files/system.rb, line 85 def mkpath FileUtils.mkpath self end
The time the file was last modified.
# File lib/build/files/system.rb, line 80 def modified_time File.mtime self end
Open a file with the specified mode.
# File lib/build/files/system.rb, line 30 def open(mode, &block) File.open(self, mode, &block) end
# File lib/build/files/path.rb, line 123 def parent root = @root full_path = File.dirname(@full_path) while root.size > full_path.size root = Path.root(root) end if root.size == full_path.size root = Path.root(root) end self.class.new(full_path, root) end
Read the entire contents of the file.
# File lib/build/files/system.rb, line 35 def read(mode = File::RDONLY) open(mode) do |file| file.read end end
# File lib/build/files/system.rb, line 75 def readable? File.readable? self end
# File lib/build/files/path.rb, line 178 def rebase(root) self.class.new(File.join(root, relative_path), root) end
# File lib/build/files/path.rb, line 148 def relative_parts dirname, _, basename = self.relative_path.rpartition(File::SEPARATOR) return dirname, basename end
# File lib/build/files/path.rb, line 144 def relative_path @relative_path ||= Path.relative_path(@root.to_s, @full_path.to_s).freeze end
Recursively delete the given path and all contents.
# File lib/build/files/system.rb, line 92 def rm FileUtils.rm_rf self end
# File lib/build/files/path.rb, line 214 def shortest_path(root) self.class.shortest_path(self, root) end
# File lib/build/files/path.rb, line 138 def start_with?(*args) @full_path.start_with?(*args) end
# File lib/build/files/system.rb, line 53 def stat File.stat self end
# File lib/build/files/system.rb, line 71 def symlink? File.symlink? self end
# File lib/build/files/path.rb, line 222 def to_path @full_path end
# File lib/build/files/path.rb, line 226 def to_s # It's not guaranteed to be string. @full_path.to_s end
# File lib/build/files/path.rb, line 218 def to_str @full_path.to_str end
Touch the file, changing it's last modified time.
# File lib/build/files/system.rb, line 49 def touch FileUtils.touch self end
# File lib/build/files/path.rb, line 182 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 a buffer to the file, creating it if it doesn't exist.
# 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