mirror of
https://github.com/ruby/ruby.git
synced 2026-07-30 15:41:06 +08:00
166 lines
4.8 KiB
Ruby
166 lines
4.8 KiB
Ruby
# frozen_string_literal: true
|
|
#
|
|
# = pathname.rb
|
|
#
|
|
# Object-Oriented Pathname Class
|
|
#
|
|
# Author:: Tanaka Akira <akr@m17n.org>
|
|
# Documentation:: Author and Gavin Sinclair
|
|
#
|
|
# For documentation, see class Pathname.
|
|
#
|
|
class Pathname
|
|
|
|
# :markup: markdown
|
|
#
|
|
# call-seq:
|
|
# Pathname.find(ignore_error: true) -> nil
|
|
#
|
|
# With a block given, performs a depth-first traversal of the path in `self`;
|
|
# calls the block with each found path:
|
|
#
|
|
# ```ruby
|
|
# paths = []
|
|
# Pathname('lib').find {|path| paths << path }
|
|
# paths.size # => 909
|
|
# paths.take(3)
|
|
# # =>
|
|
# # [#<Pathname:lib>,
|
|
# # #<Pathname:lib/English.gemspec>,
|
|
# # #<Pathname:lib/English.rb>]
|
|
# ```
|
|
#
|
|
# When `self` contains `'.'`, the found paths omit the leading `'./'`:
|
|
#
|
|
# ```ruby
|
|
# paths = []
|
|
# Dir.chdir('lib') do
|
|
# Pathname('.').find {|path| paths << path }
|
|
# end
|
|
# paths.take(3)
|
|
# # # =>
|
|
# # [#<Pathname:.>,
|
|
# # #<Pathname:English.gemspec>,
|
|
# # #<Pathname:English.rb>]
|
|
# ```
|
|
#
|
|
# This method calls method Find.find;
|
|
# therefore method Find.prune may be used in the block:
|
|
#
|
|
# ```ruby
|
|
# files = []
|
|
# Pathname('.').find do |path|
|
|
# Find.prune if File.basename(path) == 'test'
|
|
# next unless File.file?(path) && File.extname(path) == '.rb'
|
|
# files << path
|
|
# end
|
|
# files.size # => 6690
|
|
# files.take(3)
|
|
# # # =>
|
|
# # [#<Pathname:KNOWNBUGS.rb>,
|
|
# # #<Pathname:array.rb>,
|
|
# # #<Pathname:ast.rb>]
|
|
# ```
|
|
#
|
|
# Raises an exception if the path in `self` cannot be read.
|
|
#
|
|
# When keyword argument `ignore_error` is given as `true` (the default),
|
|
# certain exceptions during traversal are ignored (i.e., silently rescued):
|
|
# Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG, Errno::EINVAL;
|
|
# when given as `false`, no exceptions are rescued.
|
|
#
|
|
# Note that these exceptions may be ignored only in `Pathname#find` traversal code;
|
|
# an exception raised before traversal begins,
|
|
# or raised while in the block is not ignored.
|
|
# Each of the calls below raises an Errno::ENOENT exception that is not ignored:
|
|
#
|
|
# ```ruby
|
|
# Pathname('nosuch').find { }
|
|
# Pathname('lib').find {|entry| raise Errno::ENOENT }
|
|
# ```
|
|
#
|
|
# With no block given, returns a new Enumerator.
|
|
def find(ignore_error: true) # :yield: pathname
|
|
return to_enum(__method__, ignore_error: ignore_error) unless block_given?
|
|
require 'find'
|
|
if @path == '.'
|
|
Find.find(@path, ignore_error: ignore_error) {|f| yield self.class.new(f.delete_prefix('./')) }
|
|
else
|
|
Find.find(@path, ignore_error: ignore_error) {|f| yield self.class.new(f) }
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
class Pathname # * FileUtils *
|
|
|
|
# :markup: markdown
|
|
#
|
|
# call-seq:
|
|
# rmtree -> 0
|
|
#
|
|
# Deletes the entire filetree at the path in `self`; returns `0`:
|
|
#
|
|
# ```ruby
|
|
# dir_pn = Pathname('foo/bar/baz') # => #<Pathname:foo/bar/baz>
|
|
# dir_pn.mkpath # Create 'baz' and intermediate directories.
|
|
# file_pn = dir_pn.join('t.tmp') # => #<Pathname:foo/bar/baz/t.tmp>
|
|
# file_pn.write('foo') # Create file at nested directory 'baz'.
|
|
# Pathname('foo').rmtree # Delete the entire tree at directory 'foo'.
|
|
# Pathname('foo').exist? # => false
|
|
# ```
|
|
#
|
|
# Use method #rmdir to delete a single (empty) directory.
|
|
#
|
|
def rmtree(noop: nil, verbose: nil, secure: nil)
|
|
# The name "rmtree" is borrowed from File::Path of Perl.
|
|
# File::Path provides "mkpath" and "rmtree".
|
|
require 'fileutils'
|
|
FileUtils.rm_rf(@path, noop: noop, verbose: verbose, secure: secure)
|
|
self
|
|
end
|
|
end
|
|
|
|
class Pathname # * tmpdir *
|
|
# call-seq:
|
|
# Pathname.mktmpdir -> new_pathname
|
|
# Pathname.mktmpdir {|pathname| ... } -> object
|
|
#
|
|
# Creates:
|
|
#
|
|
# - A temporary directory via Dir.mktmpdir.
|
|
# - A \Pathname object that contains the path to that directory.
|
|
#
|
|
# With no block given, returns the created pathname;
|
|
# the caller should delete the created directory when it is no longer needed
|
|
# (FileUtils.rm_r is a convenient method for the deletion):
|
|
#
|
|
# pathname = Pathname.mktmpdir
|
|
# dirpath = pathname.to_s
|
|
# Dir.exist?(dirpath) # => true
|
|
# # Do something with the directory.
|
|
# require 'fileutils'
|
|
# FileUtils.rm_r(dirpath)
|
|
#
|
|
# With a block given, calls the block with the created pathname;
|
|
# on block exit, automatically deletes the created directory and all its contents;
|
|
# returns the block's exit value:
|
|
#
|
|
# pathname = Pathname.mktmpdir do |p|
|
|
# # Do something with the directory.
|
|
# p
|
|
# end
|
|
# Dir.exist?(pathname.to_s) # => false
|
|
def self.mktmpdir
|
|
require 'tmpdir' unless defined?(Dir.mktmpdir)
|
|
if block_given?
|
|
Dir.mktmpdir do |dir|
|
|
dir = self.new(dir)
|
|
yield dir
|
|
end
|
|
else
|
|
self.new(Dir.mktmpdir)
|
|
end
|
|
end
|
|
end
|