Class: Pathname
- Defined in:
- lib/pleasant_path/pathname.rb,
lib/pleasant_path/json/pathname.rb,
lib/pleasant_path/yaml/pathname.rb
Constant Summary collapse
- NULL =
File::NULL
as a Pathname. On POSIX systems, this should be equivalent to Pathname.new(“/dev/null”). Pathname.new(File::NULL)
Instance Method Summary collapse
-
#^(sibling) ⇒ Pathname
Joins the Pathname’s
dirname
with the givensibling
. -
#append_file(source) ⇒ self
Appends the contents of file indicated by
source
to the file indicated by the Pathname. -
#append_lines(lines, eol: $/) ⇒ self
Appends each object in
lines
as a string pluseol
(end-of-line) characters to the file indicated by the Pathname. -
#append_text(text) ⇒ self
Appends
text
to the file indicated by the Pathname. -
#available_name(format = "%{name}_%{i}%{ext}", i: 1) ⇒ Pathname
Finds an available name based on the Pathname.
-
#chdir ⇒ Object
Changes the current working directory to the Pathname.
-
#common_path(other) ⇒ Pathname
Returns the longest path that the Pathname and
other
have in common. -
#copy(destination) ⇒ Pathname
Copies the file or directory indicated by the Pathname to
destination
, in the same manner asFileUtils.cp_r
. -
#copy_as(destination) ⇒ Object
Copies the file or directory indicated by the Pathname to
destination
, replacing any existing file or directory. -
#copy_into(directory, &block) ⇒ Object
Copies the file or directory indicated by the Pathname into
directory
, replacing any existing file or directory of the same basename. -
#delete! ⇒ self
Recursively deletes the directory or file indicated by the Pathname.
-
#dirs ⇒ Array<Pathname>
Returns the direct child directories of the directory indicated by the Pathname.
-
#dirs_r ⇒ Array<Pathname>
Returns all (recursive) descendent directories of the directory indicated by the Pathname.
-
#edit_lines(eol: $/) {|lines| ... } ⇒ self
Reads the file indicated by the Pathname, and yields the entire contents as an Array of lines to the given block for editing.
-
#edit_text {|text| ... } ⇒ self
Reads the file indicated by the Pathname, and yields the entire contents as a String to the given block for editing.
-
#existence ⇒ self?
Returns the Pathname if
exist?
is true, otherwise returns nil. -
#files ⇒ Array<Pathname>
Returns the direct child files of the directory indicated by the Pathname.
-
#files_r ⇒ Array<Pathname>
Returns all (recursive) descendent files of the directory indicated by the Pathname.
-
#find_dirs ⇒ Object
Iterates over all (recursive) descendent directories of the directory indicated by the Pathname.
-
#find_files ⇒ Object
Iterates over all (recursive) descendent files of the directory indicated by the Pathname.
-
#load_json(options = {}) ⇒ Object
Reads the file indicated by the Pathname, and parses the contents as JSON, deserializing arbitrary data types via type information embedded in the JSON.
-
#load_yaml ⇒ Object
Reads the file indicated by the Pathname, and parses the contents as YAML, deserializing arbitrary data types via type information embedded in the YAML.
-
#make_dir ⇒ self
Creates the directory indicated by the Pathname, including any necessary parent directories.
-
#make_dirname ⇒ self
Creates the directory indicated by the Pathname’s
dirname
, including any necessary parent directories. -
#make_file ⇒ self
Creates the file indicated by the Pathname, including any necessary parent directories.
-
#move(destination) ⇒ Pathname
Moves the file or directory indicated by the Pathname to
destination
, in the same manner asFileUtils.mv
. -
#move_as(destination) ⇒ Object
(also: #rename_as)
Moves the file or directory indicated by the Pathname to
destination
, replacing any existing file or directory. -
#move_into(directory, &block) ⇒ Object
Moves the file or directory indicated by the Pathname into
directory
, replacing any existing file or directory of the same basename. -
#parentname ⇒ Pathname
Returns the
basename
of the Pathname’sdirname
. -
#read_json(options = {}) ⇒ nil, ...
Reads the file indicated by the Pathname, and parses the contents as JSON.
-
#read_lines(eol: $/) ⇒ Array<String>
Reads all lines from the file indicated by the Pathname, and returns them with
eol
(end-of-line) characters stripped. -
#read_yaml ⇒ nil, ...
Reads the file indicated by the Pathname, and parses the contents as YAML.
-
#rename_basename(new_basename, &block) ⇒ Object
Renames the file or directory indicated by the Pathname relative to its
dirname
, replacing any existing file or directory of the same basename. -
#rename_extname(new_extname, &block) ⇒ Object
Changes the file extension (
extname
) of the file indicated by the Pathname, replacing any existing file or directory of the same resultant basename. -
#to_pathname ⇒ self
Returns the Pathname unmodified.
-
#write_lines(lines, eol: $/) ⇒ self
Writes each object in
lines
as a string pluseol
(end-of-line) characters to the file indicated by the Pathname, overwriting the file if it exists. -
#write_text(text) ⇒ self
Writes
text
to the file indicated by the Pathname, overwriting the file if it exists.
Instance Method Details
#^(sibling) ⇒ Pathname
Joins the Pathname’s dirname
with the given sibling
.
The mnemonic for this operator is that the result is formed by going up one directory level from the original path, then going back down to sibling
.
29 30 31 |
# File 'lib/pleasant_path/pathname.rb', line 29 def ^(sibling) self.dirname / sibling end |
#append_file(source) ⇒ self
Appends the contents of file indicated by source
to the file indicated by the Pathname. Returns the Pathname.
1105 1106 1107 1108 |
# File 'lib/pleasant_path/pathname.rb', line 1105 def append_file(source) self.open("a"){|destination| IO::copy_stream(source, destination) } self end |
#append_lines(lines, eol: $/) ⇒ self
Appends each object in lines
as a string plus eol
(end-of-line) characters to the file indicated by the Pathname. Creates the file if it does not exist, including any necessary parent directories. Returns the Pathname.
1008 1009 1010 1011 |
# File 'lib/pleasant_path/pathname.rb', line 1008 def append_lines(lines, eol: $/) self.make_dirname.open("a"){|f| f.write_lines(lines, eol: eol) } self end |
#append_text(text) ⇒ self
Appends text
to the file indicated by the Pathname. Creates the file if it does not exist, including any necessary parent directories. Returns the Pathname.
966 967 968 969 |
# File 'lib/pleasant_path/pathname.rb', line 966 def append_text(text) self.make_dirname.open("a"){|f| f.write(text) } self end |
#available_name(format = "%{name}_%{i}%{ext}", i: 1) ⇒ Pathname
Finds an available name based on the Pathname. If the Pathname does not point to an existing file or directory, returns the Pathname. Otherwise, iteratively generates and tests names until one is found that does not point to an existing file or directory.
Names are generated using a Hash-style format string with three populated values:
-
%{name}: original Pathname basename without extname
-
%{ext}: original Pathname extname, including leading dot
-
%{i}: iteration counter; can be initialized via
:i
kwarg
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
# File 'lib/pleasant_path/pathname.rb', line 399 def available_name(format = "%{name}_%{i}%{ext}", i: 1) return self unless self.exist? dirname = File.dirname(self) format = "%{dirname}/" + format unless dirname == "." values = { dirname: dirname, name: File.basename(self, ".*"), ext: self.extname, i: i, } while (path = format % values) && File.exist?(path) values[:i] += 1 end path.to_pathname end |
#chdir ⇒ self #chdir {|working_dir| ... } ⇒ Object
Changes the current working directory to the Pathname. If no block is given, this method returns the Pathname. Otherwise, the block is called with the Pathname, the original working directory is restored after the block exits, and this method returns the return value of the block.
263 264 265 266 267 268 269 270 271 272 |
# File 'lib/pleasant_path/pathname.rb', line 263 def chdir if block_given? Dir.chdir(self) do |dir| yield dir.to_pathname end else Dir.chdir(self) self end end |
#common_path(other) ⇒ Pathname
Returns the longest path that the Pathname and other
have in common.
77 78 79 |
# File 'lib/pleasant_path/pathname.rb', line 77 def common_path(other) File.common_path([self.to_s, other.to_s]).to_pathname end |
#copy(destination) ⇒ Pathname
Copies the file or directory indicated by the Pathname to destination
, in the same manner as FileUtils.cp_r
. Returns destination
as a Pathname.
625 626 627 628 |
# File 'lib/pleasant_path/pathname.rb', line 625 def copy(destination) FileUtils.cp_r(self, destination) destination.to_pathname end |
#copy_as(destination) ⇒ Pathname #copy_as(destination) {|source, destination| ... } ⇒ Pathname
Copies the file or directory indicated by the Pathname to destination
, replacing any existing file or directory.
If a block is given and a file or directory does exist at the destination, the block is called with the source and destination Pathnames, and the return value of the block is used as the new destination. If the block returns the source Pathname or nil, the copy is aborted.
Creates any necessary parent directories of the destination. Returns the destination as a Pathname (or the source Pathname in the case that the copy is aborted).
WARNING: Due to system API limitations, the copy is performed in two steps, non-atomically. First, any file or directory existing at the destination is deleted. Next, the source is copied to the destination. The second step can fail independently of the first, e.g. due to insufficient disk space, leaving the file or directory previously at the destination deleted without replacement.
708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 |
# File 'lib/pleasant_path/pathname.rb', line 708 def copy_as(destination) destination = destination.to_pathname if block_given? && destination.exist? && self.exist? && !File.identical?(self, destination) destination = yield self, destination destination = nil if destination == self end if destination destination.delete! unless File.identical?(self, destination) self.copy(destination.make_dirname) end destination || self end |
#copy_into(directory) ⇒ Pathname #copy_into(directory) {|source, destination| ... } ⇒ Pathname
Copies the file or directory indicated by the Pathname into directory
, replacing any existing file or directory of the same basename.
If a block is given and a file or directory does exist at the resultant destination, the block is called with the source and destination Pathnames, and the return value of the block is used as the new destination. If the block returns the source Pathname or nil, the copy is aborted.
Creates any necessary parent directories of the destination. Returns the destination as a Pathname (or the source Pathname in the case that the copy is aborted).
WARNING: Due to system API limitations, the copy is performed in two steps, non-atomically. First, any file or directory existing at the destination is deleted. Next, the source is copied to the destination. The second step can fail independently of the first, e.g. due to insufficient disk space, leaving the file or directory previously at the destination deleted without replacement.
782 783 784 |
# File 'lib/pleasant_path/pathname.rb', line 782 def copy_into(directory, &block) self.copy_as(directory / self.basename, &block) end |
#delete! ⇒ self
Recursively deletes the directory or file indicated by the Pathname. Similar to Pathname#rmtree, but does not raise an exception if the file does not exist. Returns the Pathname.
354 355 356 357 |
# File 'lib/pleasant_path/pathname.rb', line 354 def delete! self.rmtree if self.exist? self end |
#dirs ⇒ Array<Pathname>
Returns the direct child directories of the directory indicated by the Pathname. Returned Pathnames are prefixed by the original Pathname.
106 107 108 |
# File 'lib/pleasant_path/pathname.rb', line 106 def dirs self.children.tap{|c| c.select!(&:dir?) } end |
#dirs_r ⇒ Array<Pathname>
Returns all (recursive) descendent directories of the directory indicated by the Pathname. Returned Pathnames are prefixed by the original Pathname, and are in depth-first order.
129 130 131 |
# File 'lib/pleasant_path/pathname.rb', line 129 def dirs_r self.find_dirs.to_a end |
#edit_lines(eol: $/) {|lines| ... } ⇒ self
Reads the file indicated by the Pathname, and yields the entire contents as an Array of lines to the given block for editing. Writes the return value of the block back to the file, overwriting previous contents. eol
(end-of-line) characters are stripped from each line when reading, and appended to each line when writing. Returns the Pathname.
1086 1087 1088 1089 |
# File 'lib/pleasant_path/pathname.rb', line 1086 def edit_lines(eol: $/, &block) File.edit_lines(self, eol: eol, &block) self end |
#edit_text {|text| ... } ⇒ self
Reads the file indicated by the Pathname, and yields the entire contents as a String to the given block for editing. Writes the return value of the block back to the file, overwriting previous contents. Returns the Pathname.
1059 1060 1061 1062 |
# File 'lib/pleasant_path/pathname.rb', line 1059 def edit_text(&block) File.edit_text(self, &block) self end |
#existence ⇒ self?
Returns the Pathname if exist?
is true, otherwise returns nil.
54 55 56 |
# File 'lib/pleasant_path/pathname.rb', line 54 def existence self if self.exist? end |
#files ⇒ Array<Pathname>
Returns the direct child files of the directory indicated by the Pathname. Returned Pathnames are prefixed by the original Pathname.
182 183 184 |
# File 'lib/pleasant_path/pathname.rb', line 182 def files self.children.tap{|c| c.select!(&:file?) } end |
#files_r ⇒ Array<Pathname>
Returns all (recursive) descendent files of the directory indicated by the Pathname. Returned Pathnames are prefixed by the original Pathname, and are in depth-first order.
205 206 207 |
# File 'lib/pleasant_path/pathname.rb', line 205 def files_r self.find_files.to_a end |
#find_dirs {|descendent| ... } ⇒ self #find_dirs ⇒ Enumerator<Pathname>
Iterates over all (recursive) descendent directories of the directory indicated by the Pathname. Iterated Pathnames are prefixed by the original Pathname, and are in depth-first order.
If a block is given, each descendent Pathname is yielded, and this method returns the original Pathname. Otherwise, an Enumerator is returned.
149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/pleasant_path/pathname.rb', line 149 def find_dirs return to_enum(__method__) unless block_given? self.find do |path| if path.file? Find.prune elsif path != self yield path end end self end |
#find_files {|descendent| ... } ⇒ self #find_files ⇒ Enumerator<Pathname>
Iterates over all (recursive) descendent files of the directory indicated by the Pathname. Iterated Pathnames are prefixed by the original Pathname, and are in depth-first order.
If a block is given, each descendent Pathname is yielded, and this method returns the original Pathname. Otherwise, an Enumerator is returned.
225 226 227 228 229 230 231 232 233 |
# File 'lib/pleasant_path/pathname.rb', line 225 def find_files return to_enum(__method__) unless block_given? self.find do |path| yield path if path.file? end self end |
#load_json(options = {}) ⇒ Object
Reads the file indicated by the Pathname, and parses the contents as JSON, deserializing arbitrary data types via type information embedded in the JSON. This is UNSAFE for JSON from an untrusted source. To consume untrusted JSON, use #read_json instead.
For information about options
, see JSON.parse
. By default, this method uses JSON.load_default_options
.
For information about serializing custom types to JSON, see the JSON readme.
52 53 54 |
# File 'lib/pleasant_path/json/pathname.rb', line 52 def load_json( = {}) JSON.load(self, nil, ) end |
#load_yaml ⇒ Object
Reads the file indicated by the Pathname, and parses the contents as YAML, deserializing arbitrary data types via type information embedded in the YAML. This is UNSAFE for YAML from an untrusted source. To consume untrusted YAML, use #read_yaml instead.
33 34 35 |
# File 'lib/pleasant_path/yaml/pathname.rb', line 33 def load_yaml YAML.load_file(self) end |
#make_dir ⇒ self
Creates the directory indicated by the Pathname, including any necessary parent directories. Returns the Pathname.
291 292 293 294 |
# File 'lib/pleasant_path/pathname.rb', line 291 def make_dir self.mkpath self end |
#make_dirname ⇒ self
Creates the directory indicated by the Pathname’s dirname
, including any necessary parent directories. Returns the Pathname.
313 314 315 316 |
# File 'lib/pleasant_path/pathname.rb', line 313 def make_dirname self.dirname.make_dir self end |
#make_file ⇒ self
Creates the file indicated by the Pathname, including any necessary parent directories. Returns the Pathname.
335 336 337 338 |
# File 'lib/pleasant_path/pathname.rb', line 335 def make_file self.make_dirname.open("a"){} self end |
#move(destination) ⇒ Pathname
Moves the file or directory indicated by the Pathname to destination
, in the same manner as FileUtils.mv
. Returns destination
as a Pathname.
438 439 440 441 |
# File 'lib/pleasant_path/pathname.rb', line 438 def move(destination) FileUtils.mv(self, destination) destination.to_pathname end |
#move_as(destination) ⇒ Pathname #move_as(destination) {|source, destination| ... } ⇒ Pathname Also known as: rename_as
Moves the file or directory indicated by the Pathname to destination
, replacing any existing file or directory.
If a block is given and a file or directory does exist at the destination, the block is called with the source and destination Pathnames, and the return value of the block is used as the new destination. If the block returns the source Pathname or nil, the move is aborted.
Creates any necessary parent directories of the destination. Returns the destination as a Pathname (or the source Pathname in the case that the move is aborted).
WARNING: Due to system API limitations, the move is performed in two steps, non-atomically. First, any file or directory existing at the destination is deleted. Next, the source is moved to the destination. The second step can fail independently of the first, e.g. due to insufficient disk space, leaving the file or directory previously at the destination deleted without replacement.
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 |
# File 'lib/pleasant_path/pathname.rb', line 521 def move_as(destination) destination = destination.to_pathname if block_given? && destination.exist? && self.exist? && !File.identical?(self, destination) destination = (yield self, destination) || self end if destination != self if File.identical?(self, destination) # FileUtils.mv raises an ArgumentError when both paths refer to # the same file. On case-insensitive file systems, this occurs # even when both paths have different casing. We want to # disregard the ArgumentError at all times, and change the # filename casing when applicable. File.rename(self, destination) else destination.delete! self.move(destination.make_dirname) end end destination end |
#move_into(directory) ⇒ Pathname #move_into(directory) {|source, destination| ... } ⇒ Pathname
Moves the file or directory indicated by the Pathname into directory
, replacing any existing file or directory of the same basename.
If a block is given and a file or directory does exist at the resultant destination, the block is called with the source and destination Pathnames, and the return value of the block is used as the new destination. If the block returns the source Pathname or nil, the move is aborted.
Creates any necessary parent directories of the destination. Returns the destination as a Pathname (or the source Pathname in the case that the move is aborted).
WARNING: Due to system API limitations, the move is performed in two steps, non-atomically. First, any file or directory existing at the destination is deleted. Next, the source is moved to the destination. The second step can fail independently of the first, e.g. due to insufficient disk space, leaving the file or directory previously at the destination deleted without replacement.
602 603 604 |
# File 'lib/pleasant_path/pathname.rb', line 602 def move_into(directory, &block) self.move_as(directory / self.basename, &block) end |
#parentname ⇒ Pathname
Returns the basename
of the Pathname’s dirname
.
39 40 41 |
# File 'lib/pleasant_path/pathname.rb', line 39 def parentname self.dirname.basename end |
#read_json(options = {}) ⇒ nil, ...
Reads the file indicated by the Pathname, and parses the contents as JSON. The returned result will be composed of only basic data types, e.g. nil
, true
, false
, Numeric
, String
, Array
, and Hash
.
For information about options
, see JSON.parse
. By default, this method uses JSON.load_default_options
plus create_additions: false.
23 24 25 |
# File 'lib/pleasant_path/json/pathname.rb', line 23 def read_json( = {}) JSON.load(self, nil, { create_additions: false, ** }) end |
#read_lines(eol: $/) ⇒ Array<String>
Not to be confused with Pathname#readlines, which retains end-of-line characters.
Reads all lines from the file indicated by the Pathname, and returns them with eol
(end-of-line) characters stripped.
1033 1034 1035 |
# File 'lib/pleasant_path/pathname.rb', line 1033 def read_lines(eol: $/) self.open("r"){|f| f.read_lines(eol: eol) } end |
#read_yaml ⇒ nil, ...
Reads the file indicated by the Pathname, and parses the contents as YAML. The returned result will be composed of only basic data types, e.g. nil
, true
, false
, Numeric
, String
, Array
, and Hash
.
16 17 18 |
# File 'lib/pleasant_path/yaml/pathname.rb', line 16 def read_yaml self.open("r"){|f| YAML.safe_load(f, filename: self) } end |
#rename_basename(new_basename) ⇒ Pathname #rename_basename(new_basename) {|source, destination| ... } ⇒ Pathname
Renames the file or directory indicated by the Pathname relative to its dirname
, replacing any existing file or directory of the same basename.
If a block is given and a file or directory does exist at the resultant destination, the block is called with the source and destination Pathnames, and the return value of the block is used as the new destination. If the block returns the source Pathname or nil, the rename is aborted.
Returns the destination as a Pathname (or the source Pathname in the case that the rename is aborted).
WARNING: Due to system API limitations, the rename is performed in two steps, non-atomically. First, any file or directory existing at the destination is deleted. Next, the source is moved to the destination. The second step can fail independently of the first, e.g. due to insufficient disk space, leaving the file or directory previously at the destination deleted without replacement.
846 847 848 |
# File 'lib/pleasant_path/pathname.rb', line 846 def rename_basename(new_basename, &block) self.move_as(self.dirname / new_basename, &block) end |
#rename_extname(new_extname) ⇒ Pathname #rename_extname(new_extname) {|source, destination| ... } ⇒ Pathname
Changes the file extension (extname
) of the file indicated by the Pathname, replacing any existing file or directory of the same resultant basename.
If a block is given and a file or directory does exist at the resultant destination, the block is called with the source and destination Pathnames, and the return value of the block is used as the new destination. If the block returns the source Pathname or nil, the rename is aborted.
Returns the destination as a Pathname (or the source Pathname in the case that the rename is aborted).
WARNING: Due to system API limitations, the rename is performed in two steps, non-atomically. First, any file or directory existing at the destination is deleted. Next, the source is moved to the destination. The second step can fail independently of the first, e.g. due to insufficient disk space, leaving the file or directory previously at the destination deleted without replacement.
925 926 927 |
# File 'lib/pleasant_path/pathname.rb', line 925 def rename_extname(new_extname, &block) self.move_as(self.sub_ext(new_extname), &block) end |
#to_pathname ⇒ self
Returns the Pathname unmodified. Exists for parity with String#to_pathname.
14 15 16 |
# File 'lib/pleasant_path/pathname.rb', line 14 def to_pathname self end |
#write_lines(lines, eol: $/) ⇒ self
Writes each object in lines
as a string plus eol
(end-of-line) characters to the file indicated by the Pathname, overwriting the file if it exists. Creates the file if it does not exist, including any necessary parent directories. Returns the Pathname.
987 988 989 990 |
# File 'lib/pleasant_path/pathname.rb', line 987 def write_lines(lines, eol: $/) self.make_dirname.open("w"){|f| f.write_lines(lines, eol: eol) } self end |
#write_text(text) ⇒ self
Writes text
to the file indicated by the Pathname, overwriting the file if it exists. Creates the file if it does not exist, including any necessary parent directories. Returns the Pathname.
945 946 947 948 |
# File 'lib/pleasant_path/pathname.rb', line 945 def write_text(text) self.make_dirname.open("w"){|f| f.write(text) } self end |