fakefs 0.13.3 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -87,7 +87,7 @@ module FakeFS
87
87
  new_dir = find(dir)
88
88
  dir_levels.push dir if blk
89
89
 
90
- fail Errno::ENOENT, dir unless new_dir
90
+ raise Errno::ENOENT, dir unless new_dir
91
91
 
92
92
  dir_levels.push dir unless blk
93
93
  yield(dir) if blk
@@ -118,30 +118,30 @@ module FakeFS
118
118
 
119
119
  def find_recurser(dir, parts)
120
120
  return [] unless dir.respond_to? :[]
121
-
122
- pattern, *parts = parts
123
- matches = case pattern
124
- when '**'
125
- case parts
126
- when ['*']
127
- parts = [] # end recursion
128
- directories_under(dir).map do |d|
129
- d.entries.select do |f|
130
- (f.is_a?(FakeFile) || f.is_a?(FakeDir)) &&
131
- f.name.match(/\A(?!\.)/)
132
- end
133
- end.flatten.uniq
134
- when []
135
- parts = [] # end recursion
136
- dir.entries.flatten.uniq
137
- else
138
- directories_under(dir)
139
- end
140
- else
141
- Globber.expand(pattern).flat_map do |subpattern|
142
- dir.matches(Globber.regexp(subpattern))
143
- end
144
- end
121
+ pattern, *parts = parts # rubocop:disable Lint/ShadowedArgument
122
+ matches =
123
+ case pattern
124
+ when '**'
125
+ case parts
126
+ when ['*']
127
+ parts = [] # end recursion
128
+ directories_under(dir).map do |d|
129
+ d.entries.select do |f|
130
+ (f.is_a?(FakeFile) || f.is_a?(FakeDir)) &&
131
+ f.name.match(/\A(?!\.)/)
132
+ end
133
+ end.flatten.uniq
134
+ when []
135
+ parts = [] # end recursion
136
+ dir.entries.flatten.uniq
137
+ else
138
+ directories_under(dir)
139
+ end
140
+ else
141
+ Globber.expand(pattern).flat_map do |subpattern|
142
+ dir.matches(Globber.regexp(subpattern))
143
+ end
144
+ end
145
145
 
146
146
  if parts.empty? # we're done recursing
147
147
  matches
@@ -157,7 +157,7 @@ module FakeFS
157
157
  end
158
158
 
159
159
  def assert_dir(dir)
160
- fail Errno::EEXIST, dir.name unless dir.is_a?(FakeDir)
160
+ raise Errno::EEXIST, dir.name unless dir.is_a?(FakeDir)
161
161
  end
162
162
  end
163
163
  end
@@ -28,18 +28,18 @@ module FakeFS
28
28
  end
29
29
  end
30
30
 
31
- alias_method :mkpath, :mkdir_p
32
- alias_method :makedirs, :mkdir_p
31
+ alias mkpath mkdir_p
32
+ alias makedirs mkdir_p
33
33
 
34
34
  def mkdir(list, _ignored_options = {})
35
35
  list = [list] unless list.is_a?(Array)
36
36
  list.each do |path|
37
37
  parent = path.split('/')
38
38
  parent.pop
39
- fail Errno::ENOENT, path unless parent.join == '' ||
40
- parent.join == '.' ||
41
- FileSystem.find(parent.join('/'))
42
- fail Errno::EEXIST, path if FileSystem.find(path)
39
+ unless parent.join == '' || parent.join == '.' || FileSystem.find(parent.join('/'))
40
+ raise Errno::ENOENT, path
41
+ end
42
+ raise Errno::EEXIST, path if FileSystem.find(path)
43
43
  FileSystem.add(path, FakeDir.new)
44
44
  end
45
45
  end
@@ -49,10 +49,9 @@ module FakeFS
49
49
  list.each do |l|
50
50
  parent = l.split('/')
51
51
  parent.pop
52
- fail Errno::ENOENT, l unless parent.join == '' ||
53
- FileSystem.find(parent.join('/'))
54
- fail Errno::ENOENT, l unless FileSystem.find(l)
55
- fail Errno::ENOTEMPTY, l unless FileSystem.find(l).empty?
52
+ raise Errno::ENOENT, l unless parent.join == '' || FileSystem.find(parent.join('/'))
53
+ raise Errno::ENOENT, l unless FileSystem.find(l)
54
+ raise Errno::ENOTEMPTY, l unless FileSystem.find(l).empty?
56
55
  rm(l)
57
56
  end
58
57
  end
@@ -60,11 +59,11 @@ module FakeFS
60
59
  def rm(list, options = {})
61
60
  Array(list).each do |path|
62
61
  FileSystem.delete(path) ||
63
- (!options[:force] && fail(Errno::ENOENT, path))
62
+ (!options[:force] && raise(Errno::ENOENT, path))
64
63
  end
65
64
  end
66
- alias_method :rm_r, :rm
67
- alias_method :remove, :rm
65
+ alias rm_r rm
66
+ alias remove rm
68
67
 
69
68
  def rm_f(list, options = {})
70
69
  rm(list, options.merge(force: true))
@@ -73,17 +72,17 @@ module FakeFS
73
72
  def rm_rf(list, options = {})
74
73
  rm_r(list, options.merge(force: true))
75
74
  end
76
- alias_method :rmtree, :rm_rf
77
- alias_method :safe_unlink, :rm_f
78
- alias_method :remove_entry_secure, :rm_rf
75
+ alias rmtree rm_rf
76
+ alias safe_unlink rm_f
77
+ alias remove_entry_secure rm_rf
79
78
 
80
79
  def ln_s(target, path, options = {})
81
80
  options = { force: false }.merge(options)
82
- fail(Errno::EEXIST, path) if FileSystem.find(path) && !options[:force]
81
+ raise(Errno::EEXIST, path) if FileSystem.find(path) && !options[:force]
83
82
  FileSystem.delete(path)
84
83
 
85
84
  if !options[:force] && !Dir.exist?(File.dirname(path))
86
- fail Errno::ENOENT, path
85
+ raise Errno::ENOENT, path
87
86
  end
88
87
 
89
88
  FileSystem.add(path, FakeSymlink.new(target))
@@ -93,10 +92,10 @@ module FakeFS
93
92
  ln_s(target, path, force: true)
94
93
  end
95
94
 
96
- alias_method :symlink, :ln_s
95
+ alias symlink ln_s
97
96
 
98
97
  def cp(src, dest, options = {})
99
- fail Errno::ENOTDIR, dest if src.is_a?(Array) && !File.directory?(dest)
98
+ raise Errno::ENOTDIR, dest if src.is_a?(Array) && !File.directory?(dest)
100
99
 
101
100
  # handle `verbose' flag
102
101
  RealFileUtils.cp src, dest, options.merge(noop: true)
@@ -108,12 +107,12 @@ module FakeFS
108
107
  dst_file = FileSystem.find(dest)
109
108
  src_file = FileSystem.find(source)
110
109
 
111
- fail Errno::ENOENT, source unless src_file
110
+ raise Errno::ENOENT, source unless src_file
112
111
 
113
112
  if dst_file && File.directory?(dst_file)
114
113
  FileSystem.add(
115
- File.join(
116
- dest, File.basename(source)), src_file.entry.clone(dst_file))
114
+ File.join(dest, File.basename(source)), src_file.entry.clone(dst_file)
115
+ )
117
116
  else
118
117
  FileSystem.delete(dest)
119
118
  FileSystem.add(dest, src_file.entry.clone)
@@ -123,7 +122,7 @@ module FakeFS
123
122
  nil
124
123
  end
125
124
 
126
- alias_method :copy, :cp
125
+ alias copy cp
127
126
 
128
127
  def copy_file(src, dest, _preserve = false, _dereference = true)
129
128
  # Not a perfect match, but similar to what regular FileUtils does.
@@ -131,10 +130,12 @@ module FakeFS
131
130
  end
132
131
 
133
132
  def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
134
- cp_r(src, dest,
135
- preserve: preserve,
136
- dereference_root: dereference_root,
137
- remove_destination: remove_destination)
133
+ cp_r(
134
+ src, dest,
135
+ preserve: preserve,
136
+ dereference_root: dereference_root,
137
+ remove_destination: remove_destination
138
+ )
138
139
  end
139
140
 
140
141
  def cp_r(src, dest, options = {})
@@ -146,19 +147,11 @@ module FakeFS
146
147
 
147
148
  Array(src).each do |source|
148
149
  dir = FileSystem.find(source)
149
- unless dir
150
- if RUBY_VERSION >= '1.9.1'
151
- fail Errno::ENOENT, source
152
- else
153
- # This error sucks, but it conforms to the original Ruby
154
- # method.
155
- fail "unknown file type: #{source}"
156
- end
157
- end
150
+ raise Errno::ENOENT, source unless dir
158
151
 
159
152
  new_dir = FileSystem.find(dest)
160
- fail Errno::EEXIST, dest if new_dir && !File.directory?(dest)
161
- fail Errno::ENOENT, dest if !new_dir && !FileSystem.find(dest + '/../')
153
+ raise Errno::EEXIST, dest if new_dir && !File.directory?(dest)
154
+ raise Errno::ENOENT, dest if !new_dir && !FileSystem.find(dest + '/../')
162
155
 
163
156
  # This last bit is a total abuse and should be thought hard
164
157
  # about and cleaned up.
@@ -185,43 +178,46 @@ module FakeFS
185
178
 
186
179
  Array(src).each do |path|
187
180
  if (target = FileSystem.find(path))
188
- dest_path = if File.directory?(dest)
189
- File.join(dest, File.basename(path))
190
- else
191
- dest
192
- end
181
+ dest_path =
182
+ if File.directory?(dest)
183
+ File.join(dest, File.basename(path))
184
+ else
185
+ dest
186
+ end
193
187
  if File.directory?(dest_path)
194
- fail Errno::EEXIST, dest_path unless options[:force]
188
+ raise Errno::EEXIST, dest_path unless options[:force]
195
189
  elsif File.directory?(File.dirname(dest_path))
196
190
  FileSystem.delete(dest_path)
197
191
  FileSystem.add(dest_path, target.entry.clone)
198
192
  FileSystem.delete(path)
199
193
  else
200
- fail Errno::ENOENT, dest_path unless options[:force]
194
+ raise Errno::ENOENT, dest_path unless options[:force]
201
195
  end
202
196
  else
203
- fail Errno::ENOENT, path
197
+ raise Errno::ENOENT, path
204
198
  end
205
199
  end
206
200
 
207
201
  nil
208
202
  end
209
203
 
210
- alias_method :move, :mv
204
+ alias move mv
211
205
 
212
206
  def chown(user, group, list, _options = {})
213
207
  list = Array(list)
214
208
  list.each do |f|
215
209
  if File.exist?(f)
216
- uid = if user
217
- user.to_s =~ /\d+/ ? user.to_i : Etc.getpwnam(user).uid
218
- end
219
- gid = if group
220
- group.to_s =~ /\d+/ ? group.to_i : Etc.getgrnam(group).gid
221
- end
210
+ uid =
211
+ if user
212
+ user.to_s =~ /\d+/ ? user.to_i : Etc.getpwnam(user).uid
213
+ end
214
+ gid =
215
+ if group
216
+ group.to_s =~ /\d+/ ? group.to_i : Etc.getgrnam(group).gid
217
+ end
222
218
  File.chown(uid, gid, f)
223
219
  else
224
- fail Errno::ENOENT, f
220
+ raise Errno::ENOENT, f
225
221
  end
226
222
  end
227
223
  list
@@ -244,7 +240,7 @@ module FakeFS
244
240
  if File.exist?(f)
245
241
  File.chmod(mode, f)
246
242
  else
247
- fail Errno::ENOENT, f
243
+ raise Errno::ENOENT, f
248
244
  end
249
245
  end
250
246
  list
@@ -282,15 +278,15 @@ module FakeFS
282
278
  def cd(dir, &block)
283
279
  FileSystem.chdir(dir, &block)
284
280
  end
285
- alias_method :chdir, :cd
281
+ alias chdir cd
286
282
 
287
283
  def compare_file(file1, file2)
288
284
  # we do a strict comparison of both files content
289
285
  File.readlines(file1) == File.readlines(file2)
290
286
  end
291
287
 
292
- alias_method :cmp, :compare_file
293
- alias_method :identical?, :compare_file
288
+ alias cmp compare_file
289
+ alias identical? compare_file
294
290
 
295
291
  def uptodate?(new, old_list)
296
292
  return false unless File.exist?(new)
@@ -15,7 +15,7 @@ module FakeFS
15
15
  case level
16
16
  when 0
17
17
  case chr
18
- when '{'
18
+ when '{' # rubocop:disable Lint/EmptyWhen
19
19
  # noop
20
20
  else
21
21
  part << chr
@@ -25,7 +25,7 @@ module FakeFS
25
25
  when ','
26
26
  result << part
27
27
  part = ''
28
- when '}'
28
+ when '}' # rubocop:disable Lint/EmptyWhen
29
29
  # noop
30
30
  else
31
31
  part << chr
@@ -63,13 +63,15 @@ module FakeFS
63
63
  def regexp(pattern)
64
64
  pattern = pattern.to_s
65
65
 
66
- regex_body = pattern.gsub('.', '\.')
67
- .gsub('+') { '\+' }
68
- .gsub('?', '.')
69
- .gsub('*', '.*')
70
- .gsub('(', '\(')
71
- .gsub(')', '\)')
72
- .gsub('$', '\$')
66
+ regex_body =
67
+ pattern
68
+ .gsub('.', '\.')
69
+ .gsub('+') { '\+' }
70
+ .gsub('?', '.')
71
+ .gsub('*', '.*')
72
+ .gsub('(', '\(')
73
+ .gsub(')', '\)')
74
+ .gsub('$', '\$')
73
75
 
74
76
  # This matches nested braces and attempts to do something correct most of the time
75
77
  # There are known issues (i.e. {,*,*/*}) that cannot be resolved with out a total
@@ -25,8 +25,7 @@ module FakeFS
25
25
  end
26
26
  end
27
27
 
28
- private
29
-
28
+ # NOTE: maybe private
30
29
  def self.hijack(name, &block)
31
30
  captives[:original][name] = ::Kernel.method(name.to_sym)
32
31
  captives[:hijacked][name] = block || proc { |_args| }
@@ -1,1049 +1,1052 @@
1
1
  # FakeFS module
2
2
  module FakeFS
3
- if RUBY_VERSION >= '1.9.3'
3
+ #
4
+ # = pathname.rb - From MRI 1.9.2
5
+ #
6
+ # Object-Oriented Pathname Class
7
+ #
8
+ # Author:: Tanaka Akira <akr@m17n.org>
9
+ # Documentation:: Author and Gavin Sinclair
10
+ #
11
+ # For documentation, see class Pathname.
12
+ #
13
+ class Pathname
14
+ # to_path is implemented so Pathname objects are
15
+ # usable with File.open, etc.
16
+ TO_PATH = :to_path
17
+
18
+ SAME_PATHS =
19
+ if File::FNM_SYSCASE.nonzero?
20
+ proc { |a, b| a.casecmp(b).zero? }
21
+ else
22
+ proc { |a, b| a == b }
23
+ end
24
+
25
+ # :startdoc:
4
26
 
5
27
  #
6
- # = pathname.rb - From MRI 1.9.2
7
- #
8
- # Object-Oriented Pathname Class
9
- #
10
- # Author:: Tanaka Akira <akr@m17n.org>
11
- # Documentation:: Author and Gavin Sinclair
12
- #
13
- # For documentation, see class Pathname.
28
+ # Create a Pathname object from the given String (or String-like object).
29
+ # If +path+ contains a NUL character (<tt>\0</tt>),
30
+ # an ArgumentError is raised.
14
31
  #
15
- class Pathname
16
- # to_path is implemented so Pathname objects are
17
- # usable with File.open, etc.
18
- TO_PATH = :to_path
19
-
20
- SAME_PATHS =
21
- if File::FNM_SYSCASE.nonzero?
22
- proc { |a, b| a.casecmp(b).zero? }
23
- else
24
- proc { |a, b| a == b }
25
- end
26
-
27
- # :startdoc:
32
+ def initialize(path)
33
+ path = path.__send__(TO_PATH) if path.respond_to? TO_PATH
34
+ @path = path.dup
28
35
 
29
- #
30
- # Create a Pathname object from the given String (or String-like object).
31
- # If +path+ contains a NUL character (<tt>\0</tt>),
32
- # an ArgumentError is raised.
33
- #
34
- def initialize(path)
35
- path = path.__send__(TO_PATH) if path.respond_to? TO_PATH
36
- @path = path.dup
37
-
38
- if /\0/ =~ @path
39
- fail ArgumentError, "pathname contains \\0: #{@path.inspect}"
40
- end
41
-
42
- taint if @path.tainted?
36
+ if /\0/ =~ @path
37
+ raise ArgumentError, "pathname contains \\0: #{@path.inspect}"
43
38
  end
44
39
 
45
- def freeze
46
- super
47
- @path.freeze
48
- self
49
- end
40
+ taint if @path.tainted?
41
+ end
50
42
 
51
- def taint
52
- super
53
- @path.taint
54
- self
55
- end
43
+ def freeze
44
+ super
45
+ @path.freeze
46
+ self
47
+ end
56
48
 
57
- def untaint
58
- super
59
- @path.untaint
60
- self
61
- end
49
+ def taint
50
+ super
51
+ @path.taint
52
+ self
53
+ end
62
54
 
63
- #
64
- # Compare this pathname with +other+. The comparison is string-based.
65
- # Be aware that two different paths
66
- # (<tt>foo.txt</tt> and <tt>./foo.txt</tt>) can refer to the same file.
67
- #
68
- def ==(other)
69
- return false unless other.is_a?(Pathname)
70
- other.to_s == @path
71
- end
55
+ def untaint
56
+ super
57
+ @path.untaint
58
+ self
59
+ end
72
60
 
73
- alias_method :===, :==
74
- alias_method :eql?, :==
61
+ #
62
+ # Compare this pathname with +other+. The comparison is string-based.
63
+ # Be aware that two different paths
64
+ # (<tt>foo.txt</tt> and <tt>./foo.txt</tt>) can refer to the same file.
65
+ #
66
+ def ==(other)
67
+ return false unless other.is_a?(Pathname)
68
+ other.to_s == @path
69
+ end
75
70
 
76
- # Provides for comparing pathnames, case-sensitively.
77
- def <=>(other)
78
- return nil unless other.is_a?(Pathname)
79
- @path.tr('/', "\0") <=> other.to_s.tr('/', "\0")
80
- end
71
+ alias === ==
72
+ alias eql? ==
81
73
 
82
- def hash # :nodoc:
83
- @path.hash
84
- end
74
+ # Provides for comparing pathnames, case-sensitively.
75
+ def <=>(other)
76
+ return nil unless other.is_a?(Pathname)
77
+ @path.tr('/', "\0") <=> other.to_s.tr('/', "\0")
78
+ end
85
79
 
86
- # Return the path as a String.
87
- def to_s
88
- @path.dup
89
- end
80
+ def hash # :nodoc:
81
+ @path.hash
82
+ end
90
83
 
91
- # to_path is implemented so Pathname objects are usable
92
- # with File.open, etc.
93
- alias_method TO_PATH, :to_s
84
+ # Return the path as a String.
85
+ def to_s
86
+ @path.dup
87
+ end
94
88
 
95
- def inspect # :nodoc:
96
- "#<#{self.class}:#{@path}>"
97
- end
89
+ # to_path is implemented so Pathname objects are usable
90
+ # with File.open, etc.
91
+ alias_method TO_PATH, :to_s
92
+
93
+ def inspect # :nodoc:
94
+ "#<#{self.class}:#{@path}>"
95
+ end
98
96
 
99
- # Return a pathname which is substituted by String#sub.
100
- def sub(pattern, *rest, &block)
97
+ # Return a pathname which is substituted by String#sub.
98
+ def sub(pattern, *rest, &block)
99
+ path =
101
100
  if block
102
- path = @path.sub(pattern, *rest) do |*args|
101
+ @path.sub(pattern, *rest) do |*args|
103
102
  begin
104
103
  old = Thread.current[:pathname_sub_matchdata]
105
- Thread.current[:pathname_sub_matchdata] = $LAST_MATCH_INFO
106
- eval('$~ = Thread.current[:pathname_sub_matchdata]',
107
- block.binding)
104
+ Thread.current[:pathname_sub_matchdata] = $~
105
+ # TODO: rewrite without using eval
106
+ eval(
107
+ '$~ = Thread.current[:pathname_sub_matchdata]',
108
+ block.binding,
109
+ __FILE__,
110
+ __LINE__ - 3
111
+ )
108
112
  ensure
109
113
  Thread.current[:pathname_sub_matchdata] = old
110
114
  end
111
115
  yield(*args)
112
116
  end
113
117
  else
114
- path = @path.sub(pattern, *rest)
118
+ @path.sub(pattern, *rest)
115
119
  end
116
- self.class.new(path)
117
- end
120
+ self.class.new(path)
121
+ end
118
122
 
119
- if File::ALT_SEPARATOR
120
- SEPARATOR_LIST = "#{Regexp.quote File::ALT_SEPARATOR}" \
121
- "#{Regexp.quote File::SEPARATOR}".freeze
122
- SEPARATOR_PAT = /[#{SEPARATOR_LIST}]/
123
- else
124
- SEPARATOR_LIST = "#{Regexp.quote File::SEPARATOR}".freeze
125
- SEPARATOR_PAT = /#{Regexp.quote File::SEPARATOR}/
126
- end
123
+ if File::ALT_SEPARATOR
124
+ SEPARATOR_LIST = "#{Regexp.quote File::ALT_SEPARATOR}" \
125
+ "#{Regexp.quote File::SEPARATOR}".freeze
126
+ SEPARATOR_PAT = /[#{SEPARATOR_LIST}]/
127
+ else
128
+ SEPARATOR_LIST = (Regexp.quote File::SEPARATOR).to_s.freeze
129
+ SEPARATOR_PAT = /#{Regexp.quote File::SEPARATOR}/
130
+ end
127
131
 
128
- # Return a pathname which the extension of the basename is substituted by
129
- # <i>repl</i>.
130
- #
131
- # If self has no extension part, <i>repl</i> is appended.
132
- def sub_ext(repl)
133
- ext = File.extname(@path)
134
- self.class.new(@path.chomp(ext) + repl)
135
- end
132
+ # Return a pathname which the extension of the basename is substituted by
133
+ # <i>repl</i>.
134
+ #
135
+ # If self has no extension part, <i>repl</i> is appended.
136
+ def sub_ext(repl)
137
+ ext = File.extname(@path)
138
+ self.class.new(@path.chomp(ext) + repl)
139
+ end
136
140
 
137
- # chop_basename(path) -> [pre-basename, basename] or nil
138
- def chop_basename(path)
139
- base = File.basename(path)
140
- if /\A#{SEPARATOR_PAT}?\z/o =~ base
141
- return nil
142
- else
143
- return path[0, path.rindex(base)], base
144
- end
141
+ # chop_basename(path) -> [pre-basename, basename] or nil
142
+ def chop_basename(path)
143
+ base = File.basename(path)
144
+ if /\A#{SEPARATOR_PAT}?\z/o =~ base
145
+ return nil
146
+ else
147
+ return path[0, path.rindex(base)], base
145
148
  end
146
- private :chop_basename
147
-
148
- # split_names(path) -> prefix, [name, ...]
149
- def split_names(path)
150
- names = []
151
- while (r = chop_basename(path))
152
- path, basename = r
153
- names.unshift basename
154
- end
149
+ end
150
+ private :chop_basename
155
151
 
156
- [path, names]
152
+ # split_names(path) -> prefix, [name, ...]
153
+ def split_names(path)
154
+ names = []
155
+ while (r = chop_basename(path))
156
+ path, basename = r
157
+ names.unshift basename
157
158
  end
158
159
 
159
- private :split_names
160
+ [path, names]
161
+ end
160
162
 
161
- def prepend_prefix(prefix, relpath)
162
- if relpath.empty?
163
- File.dirname(prefix)
164
- elsif /#{SEPARATOR_PAT}/o =~ prefix
165
- prefix = File.dirname(prefix)
166
- prefix = File.join(prefix, '') if File.basename(prefix + 'a') != 'a'
167
- prefix + relpath
168
- else
169
- prefix + relpath
170
- end
163
+ private :split_names
164
+
165
+ def prepend_prefix(prefix, relpath)
166
+ if relpath.empty?
167
+ File.dirname(prefix)
168
+ elsif /#{SEPARATOR_PAT}/o =~ prefix
169
+ prefix = File.dirname(prefix)
170
+ prefix = File.join(prefix, '') if File.basename(prefix + 'a') != 'a'
171
+ prefix + relpath
172
+ else
173
+ prefix + relpath
171
174
  end
172
- private :prepend_prefix
173
-
174
- # Returns clean pathname of +self+ with consecutive slashes and
175
- # useless dots removed. The filesystem is not accessed.
176
- #
177
- # If +consider_symlink+ is +true+, then a more conservative algorithm
178
- # is used to avoid breaking symbolic linkages.
179
- # This may retain more <tt>..</tt> entries than absolutely necessary,
180
- # but without accessing the filesystem, this can't be avoided.
181
- # See #realpath.
182
- #
183
- def cleanpath(consider_symlink = false)
184
- if consider_symlink
185
- cleanpath_conservative
186
- else
187
- cleanpath_aggressive
188
- end
175
+ end
176
+ private :prepend_prefix
177
+
178
+ # Returns clean pathname of +self+ with consecutive slashes and
179
+ # useless dots removed. The filesystem is not accessed.
180
+ #
181
+ # If +consider_symlink+ is +true+, then a more conservative algorithm
182
+ # is used to avoid breaking symbolic linkages.
183
+ # This may retain more <tt>..</tt> entries than absolutely necessary,
184
+ # but without accessing the filesystem, this can't be avoided.
185
+ # See #realpath.
186
+ #
187
+ def cleanpath(consider_symlink = false)
188
+ if consider_symlink
189
+ cleanpath_conservative
190
+ else
191
+ cleanpath_aggressive
189
192
  end
193
+ end
190
194
 
191
- #
192
- # Clean the path simply by resolving and removing excess
193
- # "." and ".." entries.
194
- # Nothing more, nothing less.
195
- #
196
- def cleanpath_aggressive
197
- path = @path
198
- names = []
199
- pre = path
200
- while (r = chop_basename(pre))
201
- pre, base = r
202
- case base
203
- when '.'
204
- when '..'
205
- names.unshift base
195
+ #
196
+ # Clean the path simply by resolving and removing excess
197
+ # "." and ".." entries.
198
+ # Nothing more, nothing less.
199
+ #
200
+ def cleanpath_aggressive
201
+ path = @path
202
+ names = []
203
+ pre = path
204
+ while (r = chop_basename(pre))
205
+ pre, base = r
206
+ case base
207
+ when '.' # rubocop:disable Lint/EmptyWhen
208
+ when '..'
209
+ names.unshift base
210
+ else
211
+ if names[0] == '..'
212
+ names.shift
206
213
  else
207
- if names[0] == '..'
208
- names.shift
209
- else
210
- names.unshift base
211
- end
214
+ names.unshift base
212
215
  end
213
216
  end
214
- if /#{SEPARATOR_PAT}/o =~ File.basename(pre)
215
- names.shift while names[0] == '..'
216
- end
217
- self.class.new(prepend_prefix(pre, File.join(*names)))
218
217
  end
219
- private :cleanpath_aggressive
218
+ if /#{SEPARATOR_PAT}/o =~ File.basename(pre)
219
+ names.shift while names[0] == '..'
220
+ end
221
+ self.class.new(prepend_prefix(pre, File.join(*names)))
222
+ end
223
+ private :cleanpath_aggressive
220
224
 
221
- # trailing_separator?(path) -> bool
222
- def trailing_separator?(path)
223
- if (r = chop_basename(path))
224
- pre, basename = r
225
- pre.length + basename.length < path.length
226
- else
227
- false
228
- end
225
+ # trailing_separator?(path) -> bool
226
+ def trailing_separator?(path)
227
+ if (r = chop_basename(path))
228
+ pre, basename = r
229
+ pre.length + basename.length < path.length
230
+ else
231
+ false
229
232
  end
233
+ end
230
234
 
231
- private :trailing_separator?
235
+ private :trailing_separator?
232
236
 
233
- # add_trailing_separator(path) -> path
234
- def add_trailing_separator(path)
235
- if File.basename(path + 'a') == 'a'
236
- path
237
- else
238
- # xxx: Is File.join is appropriate to add separator?
239
- File.join(path, '')
240
- end
237
+ # add_trailing_separator(path) -> path
238
+ def add_trailing_separator(path)
239
+ if File.basename(path + 'a') == 'a'
240
+ path
241
+ else
242
+ # xxx: Is File.join is appropriate to add separator?
243
+ File.join(path, '')
241
244
  end
242
- private :add_trailing_separator
243
-
244
- def del_trailing_separator(path)
245
- if (r = chop_basename(path))
246
- pre, basename = r
247
- pre + basename
248
- elsif /#{SEPARATOR_PAT}+\z/o =~ path
249
- $` + File.dirname(path)[/#{SEPARATOR_PAT}*\z/o]
250
- else
251
- path
252
- end
245
+ end
246
+ private :add_trailing_separator
247
+
248
+ def del_trailing_separator(path)
249
+ if (r = chop_basename(path))
250
+ pre, basename = r
251
+ pre + basename
252
+ elsif /#{SEPARATOR_PAT}+\z/o =~ path
253
+ $` + File.dirname(path)[/#{SEPARATOR_PAT}*\z/o]
254
+ else
255
+ path
253
256
  end
254
- private :del_trailing_separator
255
-
256
- def cleanpath_conservative
257
- path = @path
258
- names = []
259
- pre = path
260
- while (r = chop_basename(pre))
261
- pre, base = r
262
- names.unshift base if base != '.'
263
- end
264
- if /#{SEPARATOR_PAT}/o =~ File.basename(pre)
265
- names.shift while names[0] == '..'
266
- end
267
- if names.empty?
268
- self.class.new(File.dirname(pre))
269
- else
270
- names << '.' if names.last != '..' && File.basename(path) == '.'
257
+ end
258
+ private :del_trailing_separator
271
259
 
272
- result = prepend_prefix(pre, File.join(*names))
273
- if /\A(?:\.|\.\.)\z/ !~ names.last && trailing_separator?(path)
274
- self.class.new(add_trailing_separator(result))
275
- else
276
- self.class.new(result)
277
- end
278
- end
260
+ def cleanpath_conservative
261
+ path = @path
262
+ names = []
263
+ pre = path
264
+ while (r = chop_basename(pre))
265
+ pre, base = r
266
+ names.unshift base if base != '.'
279
267
  end
280
- private :cleanpath_conservative
281
-
282
- #
283
- # Returns the real (absolute) pathname of +self+ in the actual
284
- # filesystem not containing symlinks or useless dots.
285
- #
286
- # All components of the pathname must exist when this method is
287
- # called.
288
- #
289
- def realpath(basedir = nil)
290
- self.class.new(File.realpath(@path, basedir))
268
+ if /#{SEPARATOR_PAT}/o =~ File.basename(pre)
269
+ names.shift while names[0] == '..'
291
270
  end
271
+ if names.empty?
272
+ self.class.new(File.dirname(pre))
273
+ else
274
+ names << '.' if names.last != '..' && File.basename(path) == '.'
292
275
 
293
- #
294
- # Returns the real (absolute) pathname of +self+ in the actual filesystem.
295
- # The real pathname doesn't contain symlinks or useless dots.
296
- #
297
- # The last component of the real pathname can be nonexistent.
298
- #
299
- def realdirpath(basedir = nil)
300
- self.class.new(File.realdirpath(@path, basedir))
276
+ result = prepend_prefix(pre, File.join(*names))
277
+ if /\A(?:\.|\.\.)\z/ !~ names.last && trailing_separator?(path)
278
+ self.class.new(add_trailing_separator(result))
279
+ else
280
+ self.class.new(result)
281
+ end
301
282
  end
283
+ end
284
+ private :cleanpath_conservative
302
285
 
303
- # #parent returns the parent directory.
304
- #
305
- # This is same as <tt>self + '..'</tt>.
306
- def parent
307
- self + '..'
308
- end
286
+ #
287
+ # Returns the real (absolute) pathname of +self+ in the actual
288
+ # filesystem not containing symlinks or useless dots.
289
+ #
290
+ # All components of the pathname must exist when this method is
291
+ # called.
292
+ #
293
+ def realpath(basedir = nil)
294
+ self.class.new(File.realpath(@path, basedir))
295
+ end
309
296
 
310
- # #mountpoint? returns +true+ if <tt>self</tt> points to a mountpoint.
311
- def mountpoint?
312
- stat1 = lstat
313
- begin
314
- stat2 = parent.lstat
315
- stat1.dev == stat2.dev && stat1.ino == stat2.ino ||
316
- stat1.dev != stat2.dev
317
- rescue Errno::ENOENT
318
- false
319
- end
320
- end
297
+ #
298
+ # Returns the real (absolute) pathname of +self+ in the actual filesystem.
299
+ # The real pathname doesn't contain symlinks or useless dots.
300
+ #
301
+ # The last component of the real pathname can be nonexistent.
302
+ #
303
+ def realdirpath(basedir = nil)
304
+ self.class.new(File.realdirpath(@path, basedir))
305
+ end
321
306
 
322
- #
323
- # #root? is a predicate for root directories.
324
- # I.e. it returns +true+ if the
325
- # pathname consists of consecutive slashes.
326
- #
327
- # It doesn't access actual filesystem. So it may return +false+ for some
328
- # pathnames which points to roots such as <tt>/usr/..</tt>.
329
- #
330
- def root?
331
- chop_basename(@path).nil? && /#{SEPARATOR_PAT}/o =~ @path
332
- end
307
+ # #parent returns the parent directory.
308
+ #
309
+ # This is same as <tt>self + '..'</tt>.
310
+ def parent
311
+ self + '..'
312
+ end
333
313
 
334
- # Predicate method for testing whether a path is absolute.
335
- # It returns +true+ if the pathname begins with a slash.
336
- def absolute?
337
- !relative?
314
+ # #mountpoint? returns +true+ if <tt>self</tt> points to a mountpoint.
315
+ def mountpoint?
316
+ stat1 = lstat
317
+ begin
318
+ stat2 = parent.lstat
319
+ stat1.dev == stat2.dev && stat1.ino == stat2.ino ||
320
+ stat1.dev != stat2.dev
321
+ rescue Errno::ENOENT
322
+ false
338
323
  end
324
+ end
339
325
 
340
- # The opposite of #absolute?
341
- def relative?
342
- path = @path
343
- while (r = chop_basename(path))
344
- path, _basename = r
345
- end
346
- path == ''
347
- end
326
+ #
327
+ # #root? is a predicate for root directories.
328
+ # I.e. it returns +true+ if the
329
+ # pathname consists of consecutive slashes.
330
+ #
331
+ # It doesn't access actual filesystem. So it may return +false+ for some
332
+ # pathnames which points to roots such as <tt>/usr/..</tt>.
333
+ #
334
+ def root?
335
+ chop_basename(@path).nil? && /#{SEPARATOR_PAT}/o =~ @path
336
+ end
348
337
 
349
- #
350
- # Iterates over each component of the path.
351
- #
352
- # Pathname.new("/usr/bin/ruby").each_filename { |filename| ... }
353
- # # yields "usr", "bin", and "ruby".
354
- #
355
- def each_filename # :yield: filename
356
- return to_enum(__method__) unless block_given?
357
- _prefix, names = split_names(@path)
358
- names.each { |filename| yield filename }
359
- nil
360
- end
338
+ # Predicate method for testing whether a path is absolute.
339
+ # It returns +true+ if the pathname begins with a slash.
340
+ def absolute?
341
+ !relative?
342
+ end
361
343
 
362
- # Iterates over and yields a new Pathname object
363
- # for each element in the given path in descending order.
364
- #
365
- # Pathname.new('/path/to/some/file.rb').descend { |v| p v}
366
- # #<Pathname:/>
367
- # #<Pathname:/path>
368
- # #<Pathname:/path/to>
369
- # #<Pathname:/path/to/some>
370
- # #<Pathname:/path/to/some/file.rb>
371
- #
372
- # Pathname.new('path/to/some/file.rb').descend { |v| p v}
373
- # #<Pathname:path>
374
- # #<Pathname:path/to>
375
- # #<Pathname:path/to/some>
376
- # #<Pathname:path/to/some/file.rb>
377
- #
378
- # It doesn't access actual filesystem.
379
- #
380
- # This method is available since 1.8.5.
381
- #
382
- def descend
383
- vs = []
384
- ascend { |v| vs << v }
385
- vs.reverse_each { |v| yield v }
386
- nil
344
+ # The opposite of #absolute?
345
+ def relative?
346
+ path = @path
347
+ while (r = chop_basename(path))
348
+ path, _basename = r
387
349
  end
350
+ path == ''
351
+ end
388
352
 
389
- # Iterates over and yields a new Pathname object
390
- # for each element in the given path in ascending order.
391
- #
392
- # Pathname.new('/path/to/some/file.rb').ascend { |v| p v}
393
- # #<Pathname:/path/to/some/file.rb>
394
- # #<Pathname:/path/to/some>
395
- # #<Pathname:/path/to>
396
- # #<Pathname:/path>
397
- # #<Pathname:/>
398
- #
399
- # Pathname.new('path/to/some/file.rb').ascend { |v| p v}
400
- # #<Pathname:path/to/some/file.rb>
401
- # #<Pathname:path/to/some>
402
- # #<Pathname:path/to>
403
- # #<Pathname:path>
404
- #
405
- # It doesn't access actual filesystem.
406
- #
407
- # This method is available since 1.8.5.
408
- #
409
- def ascend
410
- path = @path
411
- yield self
412
- while (r = chop_basename(path))
413
- path, _name = r
414
- break if path.empty?
415
- yield self.class.new(del_trailing_separator(path))
416
- end
417
- end
353
+ #
354
+ # Iterates over each component of the path.
355
+ #
356
+ # Pathname.new("/usr/bin/ruby").each_filename { |filename| ... }
357
+ # # yields "usr", "bin", and "ruby".
358
+ #
359
+ def each_filename # :yield: filename
360
+ return to_enum(__method__) unless block_given?
361
+ _prefix, names = split_names(@path)
362
+ names.each { |filename| yield filename }
363
+ nil
364
+ end
365
+
366
+ # Iterates over and yields a new Pathname object
367
+ # for each element in the given path in descending order.
368
+ #
369
+ # Pathname.new('/path/to/some/file.rb').descend { |v| p v}
370
+ # #<Pathname:/>
371
+ # #<Pathname:/path>
372
+ # #<Pathname:/path/to>
373
+ # #<Pathname:/path/to/some>
374
+ # #<Pathname:/path/to/some/file.rb>
375
+ #
376
+ # Pathname.new('path/to/some/file.rb').descend { |v| p v}
377
+ # #<Pathname:path>
378
+ # #<Pathname:path/to>
379
+ # #<Pathname:path/to/some>
380
+ # #<Pathname:path/to/some/file.rb>
381
+ #
382
+ # It doesn't access actual filesystem.
383
+ #
384
+ # This method is available since 1.8.5.
385
+ #
386
+ def descend
387
+ vs = []
388
+ ascend { |v| vs << v }
389
+ vs.reverse_each { |v| yield v }
390
+ nil
391
+ end
418
392
 
419
- #
420
- # Pathname#+ appends a pathname fragment to this one to produce a new
421
- # Pathname
422
- # object.
423
- #
424
- # p1 = Pathname.new("/usr") # Pathname:/usr
425
- # p2 = p1 + "bin/ruby" # Pathname:/usr/bin/ruby
426
- # p3 = p1 + "/etc/passwd" # Pathname:/etc/passwd
427
- #
428
- # This method doesn't access the file system; it is pure string
429
- # manipulation.
430
- #
431
- def +(other)
432
- other = Pathname.new(other) unless other.is_a?(Pathname)
433
- Pathname.new(plus(@path, other.to_s))
393
+ # Iterates over and yields a new Pathname object
394
+ # for each element in the given path in ascending order.
395
+ #
396
+ # Pathname.new('/path/to/some/file.rb').ascend { |v| p v}
397
+ # #<Pathname:/path/to/some/file.rb>
398
+ # #<Pathname:/path/to/some>
399
+ # #<Pathname:/path/to>
400
+ # #<Pathname:/path>
401
+ # #<Pathname:/>
402
+ #
403
+ # Pathname.new('path/to/some/file.rb').ascend { |v| p v}
404
+ # #<Pathname:path/to/some/file.rb>
405
+ # #<Pathname:path/to/some>
406
+ # #<Pathname:path/to>
407
+ # #<Pathname:path>
408
+ #
409
+ # It doesn't access actual filesystem.
410
+ #
411
+ # This method is available since 1.8.5.
412
+ #
413
+ def ascend
414
+ path = @path
415
+ yield self
416
+ while (r = chop_basename(path))
417
+ path, _name = r
418
+ break if path.empty?
419
+ yield self.class.new(del_trailing_separator(path))
434
420
  end
435
- alias_method :/, :+
436
-
437
- def plus(path1, path2) # -> path
438
- prefix2 = path2
439
- index_list2 = []
440
- basename_list2 = []
441
- while (r2 = chop_basename(prefix2))
442
- prefix2, basename2 = r2
443
- index_list2.unshift prefix2.length
444
- basename_list2.unshift basename2
445
- end
421
+ end
446
422
 
447
- return path2 if prefix2 != ''
423
+ #
424
+ # Pathname#+ appends a pathname fragment to this one to produce a new
425
+ # Pathname
426
+ # object.
427
+ #
428
+ # p1 = Pathname.new("/usr") # Pathname:/usr
429
+ # p2 = p1 + "bin/ruby" # Pathname:/usr/bin/ruby
430
+ # p3 = p1 + "/etc/passwd" # Pathname:/etc/passwd
431
+ #
432
+ # This method doesn't access the file system; it is pure string
433
+ # manipulation.
434
+ #
435
+ def +(other)
436
+ other = Pathname.new(other) unless other.is_a?(Pathname)
437
+ Pathname.new(plus(@path, other.to_s))
438
+ end
439
+ alias / +
448
440
 
449
- prefix1 = path1
450
- while (r1 = chop_basename(prefix1))
451
- while !basename_list2.empty? && basename_list2.first == '.'
452
- index_list2.shift
453
- basename_list2.shift
454
- end
441
+ def plus(path1, path2) # -> path
442
+ prefix2 = path2
443
+ index_list2 = []
444
+ basename_list2 = []
445
+ while (r2 = chop_basename(prefix2))
446
+ prefix2, basename2 = r2
447
+ index_list2.unshift prefix2.length
448
+ basename_list2.unshift basename2
449
+ end
455
450
 
456
- prefix1, basename1 = r1
457
- next if basename1 == '.'
458
- if basename1 == '..' ||
459
- basename_list2.empty? ||
460
- basename_list2.first != '..'
461
- prefix1 += basename1
462
- break
463
- end
451
+ return path2 if prefix2 != ''
452
+
453
+ prefix1 = path1
454
+ while (r1 = chop_basename(prefix1))
455
+ while !basename_list2.empty? && basename_list2.first == '.'
464
456
  index_list2.shift
465
457
  basename_list2.shift
466
458
  end
467
459
 
468
- r1 = chop_basename(prefix1)
469
- if !r1 && /#{SEPARATOR_PAT}/o =~ File.basename(prefix1)
470
- while !basename_list2.empty? && basename_list2.first == '..'
471
- index_list2.shift
472
- basename_list2.shift
473
- end
460
+ prefix1, basename1 = r1
461
+ next if basename1 == '.'
462
+ if basename1 == '..' ||
463
+ basename_list2.empty? ||
464
+ basename_list2.first != '..'
465
+ prefix1 += basename1
466
+ break
474
467
  end
475
-
476
- if !basename_list2.empty?
477
- suffix2 = path2[index_list2.first..-1]
478
- r1 ? File.join(prefix1, suffix2) : prefix1 + suffix2
479
- else
480
- r1 ? prefix1 : File.dirname(prefix1)
481
- end
482
- end
483
- private :plus
484
-
485
- #
486
- # Pathname#join joins pathnames.
487
- #
488
- # <tt>path0.join(path1, ..., pathN)</tt> is the same as
489
- # <tt>path0 + path1 + ... + pathN</tt>.
490
- #
491
- def join(*args)
492
- args.unshift self
493
- result = args.pop
494
- result = Pathname.new(result) unless result.is_a?(Pathname)
495
- return result if result.absolute?
496
- args.reverse_each do |arg|
497
- arg = Pathname.new(arg) unless arg.is_a?(Pathname)
498
- result = arg + result
499
- return result if result.absolute?
500
- end
501
- result
468
+ index_list2.shift
469
+ basename_list2.shift
502
470
  end
503
471
 
504
- #
505
- # Returns the children of the directory (files and subdirectories, not
506
- # recursive) as an array of Pathname objects. By default, the returned
507
- # pathnames will have enough information to access the files. If you set
508
- # +with_directory+ to +false+, then the returned
509
- # pathnames will contain the
510
- # filename only.
511
- #
512
- # For example:
513
- # pn = Pathname("/usr/lib/ruby/1.8")
514
- # pn.children
515
- # # -> [ Pathname:/usr/lib/ruby/1.8/English.rb,
516
- # Pathname:/usr/lib/ruby/1.8/Env.rb,
517
- # Pathname:/usr/lib/ruby/1.8/abbrev.rb, ... ]
518
- # pn.children(false)
519
- # # -> [ Pathname:English.rb,
520
- # Pathname:Env.rb,
521
- # Pathname:abbrev.rb, ... ]
522
- #
523
- # Note that the result never contain the entries
524
- # <tt>.</tt> and <tt>..</tt> in
525
- # the directory because they are not children.
526
- #
527
- # This method has existed since 1.8.1.
528
- #
529
- def children(with_directory = true)
530
- with_directory = false if @path == '.'
531
- result = []
532
- Dir.foreach(@path) do |e|
533
- next if e == '.' || e == '..'
534
- result <<
535
- if with_directory
536
- self.class.new(File.join(@path, e))
537
- else
538
- self.class.new(e)
539
- end
472
+ r1 = chop_basename(prefix1)
473
+ if !r1 && /#{SEPARATOR_PAT}/o =~ File.basename(prefix1)
474
+ while !basename_list2.empty? && basename_list2.first == '..'
475
+ index_list2.shift
476
+ basename_list2.shift
540
477
  end
541
- result
542
478
  end
543
479
 
544
- # Iterates over the children of the directory
545
- # (files and subdirectories, not recursive).
546
- # It yields Pathname object for each child.
547
- # By default, the yielded pathnames will have enough information to access
548
- # the files.
549
- # If you set +with_directory+ to +false+,
550
- # then the returned pathnames will contain the filename only.
551
- #
552
- # Pathname("/usr/local").each_child { |f| p f }
553
- # #=> #<Pathname:/usr/local/share>
554
- # # #<Pathname:/usr/local/bin>
555
- # # #<Pathname:/usr/local/games>
556
- # # #<Pathname:/usr/local/lib>
557
- # # #<Pathname:/usr/local/include>
558
- # # #<Pathname:/usr/local/sbin>
559
- # # #<Pathname:/usr/local/src>
560
- # # #<Pathname:/usr/local/man>
561
- #
562
- # Pathname("/usr/local").each_child(false) { |f| p f }
563
- # #=> #<Pathname:share>
564
- # # #<Pathname:bin>
565
- # # #<Pathname:games>
566
- # # #<Pathname:lib>
567
- # # #<Pathname:include>
568
- # # #<Pathname:sbin>
569
- # # #<Pathname:src>
570
- # # #<Pathname:man>
571
- #
572
- def each_child(with_directory = true, &b)
573
- children(with_directory).each(&b)
480
+ if !basename_list2.empty?
481
+ suffix2 = path2[index_list2.first..-1]
482
+ r1 ? File.join(prefix1, suffix2) : prefix1 + suffix2
483
+ else
484
+ r1 ? prefix1 : File.dirname(prefix1)
574
485
  end
486
+ end
487
+ private :plus
575
488
 
576
- #
577
- # #relative_path_from returns a relative path from the argument to the
578
- # receiver. If +self+ is absolute, the argument must be absolute too. If
579
- # +self+ is relative, the argument must be relative too.
580
- #
581
- # #relative_path_from doesn't access the filesystem.
582
- # It assumes no symlinks.
583
- #
584
- # ArgumentError is raised when it cannot find a relative path.
585
- #
586
- # This method has existed since 1.8.1.
587
- #
588
- def relative_path_from(base_directory)
589
- dest_directory = cleanpath.to_s
590
- base_directory = base_directory.cleanpath.to_s
591
- dest_prefix = dest_directory
592
- dest_names = []
593
- while (r = chop_basename(dest_prefix))
594
- dest_prefix, basename = r
595
- dest_names.unshift basename if basename != '.'
596
- end
597
- base_prefix = base_directory
598
- base_names = []
599
- while (r = chop_basename(base_prefix))
600
- base_prefix, basename = r
601
- base_names.unshift basename if basename != '.'
602
- end
603
- unless SAME_PATHS[dest_prefix, base_prefix]
604
- fail ArgumentError, "different prefix: #{dest_prefix.inspect} " \
605
- "and #{base_directory.inspect}"
606
- end
607
- while !dest_names.empty? &&
608
- !base_names.empty? &&
609
- SAME_PATHS[dest_names.first, base_names.first]
610
- dest_names.shift
611
- base_names.shift
612
- end
613
- if base_names.include? '..'
614
- fail ArgumentError, "base_directory has ..: #{base_directory.inspect}"
615
- end
616
- base_names.fill('..')
617
- relpath_names = base_names + dest_names
618
- if relpath_names.empty?
619
- Pathname.new('.')
620
- else
621
- Pathname.new(File.join(*relpath_names))
622
- end
489
+ #
490
+ # Pathname#join joins pathnames.
491
+ #
492
+ # <tt>path0.join(path1, ..., pathN)</tt> is the same as
493
+ # <tt>path0 + path1 + ... + pathN</tt>.
494
+ #
495
+ def join(*args)
496
+ args.unshift self
497
+ result = args.pop
498
+ result = Pathname.new(result) unless result.is_a?(Pathname)
499
+ return result if result.absolute?
500
+ args.reverse_each do |arg|
501
+ arg = Pathname.new(arg) unless arg.is_a?(Pathname)
502
+ result = arg + result
503
+ return result if result.absolute?
623
504
  end
505
+ result
624
506
  end
625
507
 
626
- # Pathname class
627
- class Pathname # * IO *
628
- #
629
- # #each_line iterates over the line in the file.
630
- # It yields a String object for each line.
631
- #
632
- # This method has existed since 1.8.1.
633
- #
634
- def each_line(*args, &block) # :yield: line
635
- if block_given?
636
- File.open(@path, 'r') do |io|
637
- io.each_line(*args, &block)
508
+ #
509
+ # Returns the children of the directory (files and subdirectories, not
510
+ # recursive) as an array of Pathname objects. By default, the returned
511
+ # pathnames will have enough information to access the files. If you set
512
+ # +with_directory+ to +false+, then the returned
513
+ # pathnames will contain the
514
+ # filename only.
515
+ #
516
+ # For example:
517
+ # pn = Pathname("/usr/lib/ruby/1.8")
518
+ # pn.children
519
+ # # -> [ Pathname:/usr/lib/ruby/1.8/English.rb,
520
+ # Pathname:/usr/lib/ruby/1.8/Env.rb,
521
+ # Pathname:/usr/lib/ruby/1.8/abbrev.rb, ... ]
522
+ # pn.children(false)
523
+ # # -> [ Pathname:English.rb,
524
+ # Pathname:Env.rb,
525
+ # Pathname:abbrev.rb, ... ]
526
+ #
527
+ # Note that the result never contain the entries
528
+ # <tt>.</tt> and <tt>..</tt> in
529
+ # the directory because they are not children.
530
+ #
531
+ # This method has existed since 1.8.1.
532
+ #
533
+ def children(with_directory = true)
534
+ with_directory = false if @path == '.'
535
+ result = []
536
+ Dir.foreach(@path) do |e|
537
+ next if ['.', '..'].include?(e)
538
+ result <<
539
+ if with_directory
540
+ self.class.new(File.join(@path, e))
541
+ else
542
+ self.class.new(e)
638
543
  end
639
- else
640
- enum_for(:each_line, *args)
641
- end
642
544
  end
545
+ result
546
+ end
643
547
 
644
- # See <tt>IO.read</tt>. Returns all data from the file,
645
- # or the first +N+ bytes if specified.
646
- def read(*args)
647
- File.read(@path, *args)
648
- end
548
+ # Iterates over the children of the directory
549
+ # (files and subdirectories, not recursive).
550
+ # It yields Pathname object for each child.
551
+ # By default, the yielded pathnames will have enough information to access
552
+ # the files.
553
+ # If you set +with_directory+ to +false+,
554
+ # then the returned pathnames will contain the filename only.
555
+ #
556
+ # Pathname("/usr/local").each_child { |f| p f }
557
+ # #=> #<Pathname:/usr/local/share>
558
+ # # #<Pathname:/usr/local/bin>
559
+ # # #<Pathname:/usr/local/games>
560
+ # # #<Pathname:/usr/local/lib>
561
+ # # #<Pathname:/usr/local/include>
562
+ # # #<Pathname:/usr/local/sbin>
563
+ # # #<Pathname:/usr/local/src>
564
+ # # #<Pathname:/usr/local/man>
565
+ #
566
+ # Pathname("/usr/local").each_child(false) { |f| p f }
567
+ # #=> #<Pathname:share>
568
+ # # #<Pathname:bin>
569
+ # # #<Pathname:games>
570
+ # # #<Pathname:lib>
571
+ # # #<Pathname:include>
572
+ # # #<Pathname:sbin>
573
+ # # #<Pathname:src>
574
+ # # #<Pathname:man>
575
+ #
576
+ def each_child(with_directory = true, &block)
577
+ children(with_directory).each(&block)
578
+ end
649
579
 
650
- # See <tt>IO.binread</tt>. Returns all the bytes from the file,
651
- # or the first +N+ if specified.
652
- def binread(*args)
653
- File.binread(@path, *args)
580
+ #
581
+ # #relative_path_from returns a relative path from the argument to the
582
+ # receiver. If +self+ is absolute, the argument must be absolute too. If
583
+ # +self+ is relative, the argument must be relative too.
584
+ #
585
+ # #relative_path_from doesn't access the filesystem.
586
+ # It assumes no symlinks.
587
+ #
588
+ # ArgumentError is raised when it cannot find a relative path.
589
+ #
590
+ # This method has existed since 1.8.1.
591
+ #
592
+ def relative_path_from(base_directory)
593
+ dest_directory = cleanpath.to_s
594
+ base_directory = base_directory.cleanpath.to_s
595
+ dest_prefix = dest_directory
596
+ dest_names = []
597
+ while (r = chop_basename(dest_prefix))
598
+ dest_prefix, basename = r
599
+ dest_names.unshift basename if basename != '.'
600
+ end
601
+ base_prefix = base_directory
602
+ base_names = []
603
+ while (r = chop_basename(base_prefix))
604
+ base_prefix, basename = r
605
+ base_names.unshift basename if basename != '.'
606
+ end
607
+ unless SAME_PATHS[dest_prefix, base_prefix]
608
+ raise ArgumentError, "different prefix: #{dest_prefix.inspect} " \
609
+ "and #{base_directory.inspect}"
610
+ end
611
+ while !dest_names.empty? &&
612
+ !base_names.empty? &&
613
+ SAME_PATHS[dest_names.first, base_names.first]
614
+ dest_names.shift
615
+ base_names.shift
616
+ end
617
+ if base_names.include? '..'
618
+ raise ArgumentError, "base_directory has ..: #{base_directory.inspect}"
619
+ end
620
+ base_names.fill('..')
621
+ relpath_names = base_names + dest_names
622
+ if relpath_names.empty?
623
+ Pathname.new('.')
624
+ else
625
+ Pathname.new(File.join(*relpath_names))
654
626
  end
627
+ end
628
+ end
655
629
 
656
- # See <tt>IO.readlines</tt>. Returns all the lines from the file.
657
- def readlines(*args)
658
- File.readlines(@path, *args)
630
+ # Pathname class
631
+ class Pathname # * IO *
632
+ #
633
+ # #each_line iterates over the line in the file.
634
+ # It yields a String object for each line.
635
+ #
636
+ # This method has existed since 1.8.1.
637
+ #
638
+ def each_line(*args, &block) # :yield: line
639
+ if block_given?
640
+ File.open(@path, 'r') do |io|
641
+ io.each_line(*args, &block)
642
+ end
643
+ else
644
+ enum_for(:each_line, *args)
659
645
  end
646
+ end
660
647
 
661
- # See <tt>IO.sysopen</tt>. Not supported by fakefs.
662
- def sysopen(*_args)
663
- fail NotImplementedError, 'sysopen is not supported by fakefs'
664
- end
648
+ # See <tt>IO.read</tt>. Returns all data from the file,
649
+ # or the first +N+ bytes if specified.
650
+ def read(*args)
651
+ File.read(@path, *args)
665
652
  end
666
653
 
667
- # Pathname class
668
- class Pathname # * File *
669
- # See <tt>File.atime</tt>. Returns last access time.
670
- def atime
671
- File.atime(@path)
672
- end
654
+ # See <tt>IO.binread</tt>. Returns all the bytes from the file,
655
+ # or the first +N+ if specified.
656
+ def binread(*args)
657
+ File.binread(@path, *args)
658
+ end
673
659
 
674
- # See <tt>File.ctime</tt>.
675
- # Returns last (directory entry, not file) change time.
676
- def ctime
677
- File.ctime(@path)
678
- end
660
+ # See <tt>IO.readlines</tt>. Returns all the lines from the file.
661
+ def readlines(*args)
662
+ File.readlines(@path, *args)
663
+ end
679
664
 
680
- # See <tt>File.mtime</tt>. Returns last modification time.
681
- def mtime
682
- File.mtime(@path)
683
- end
665
+ # See <tt>IO.sysopen</tt>. Not supported by fakefs.
666
+ def sysopen(*_args)
667
+ raise NotImplementedError, 'sysopen is not supported by fakefs'
668
+ end
669
+ end
684
670
 
685
- # See <tt>File.chmod</tt>. Changes permissions.
686
- def chmod(mode)
687
- File.chmod(mode, @path)
688
- end
671
+ # Pathname class
672
+ class Pathname # * File *
673
+ # See <tt>File.atime</tt>. Returns last access time.
674
+ def atime
675
+ File.atime(@path)
676
+ end
689
677
 
690
- # See <tt>File.lchmod</tt>.
691
- def lchmod(mode)
692
- File.lchmod(mode, @path)
693
- end
678
+ # See <tt>File.ctime</tt>.
679
+ # Returns last (directory entry, not file) change time.
680
+ def ctime
681
+ File.ctime(@path)
682
+ end
694
683
 
695
- # See <tt>File.chown</tt>. Change owner and group of file.
696
- def chown(owner, group)
697
- File.chown(owner, group, @path)
698
- end
684
+ # See <tt>File.mtime</tt>. Returns last modification time.
685
+ def mtime
686
+ File.mtime(@path)
687
+ end
699
688
 
700
- # See <tt>File.lchown</tt>.
701
- def lchown(owner, group)
702
- File.lchown(owner, group, @path)
703
- end
689
+ # See <tt>File.chmod</tt>. Changes permissions.
690
+ def chmod(mode)
691
+ File.chmod(mode, @path)
692
+ end
704
693
 
705
- # See <tt>File.fnmatch</tt>. Return +true+
706
- # if the receiver matches the given pattern
707
- def fnmatch(pattern, *args)
708
- File.fnmatch(pattern, @path, *args)
709
- end
694
+ # See <tt>File.lchmod</tt>.
695
+ def lchmod(mode)
696
+ File.lchmod(mode, @path)
697
+ end
710
698
 
711
- # See <tt>File.fnmatch?</tt> (same as #fnmatch).
712
- def fnmatch?(pattern, *args)
713
- File.fnmatch?(pattern, @path, *args)
714
- end
699
+ # See <tt>File.chown</tt>. Change owner and group of file.
700
+ def chown(owner, group)
701
+ File.chown(owner, group, @path)
702
+ end
715
703
 
716
- # See <tt>File.ftype</tt>. Returns "type" of file ("file", "directory",
717
- # etc).
718
- def ftype
719
- File.ftype(@path)
720
- end
704
+ # See <tt>File.lchown</tt>.
705
+ def lchown(owner, group)
706
+ File.lchown(owner, group, @path)
707
+ end
721
708
 
722
- # See <tt>File.link</tt>. Creates a hard link.
723
- def make_link(old)
724
- File.link(old, @path)
725
- end
709
+ # See <tt>File.fnmatch</tt>. Return +true+
710
+ # if the receiver matches the given pattern
711
+ def fnmatch(pattern, *args)
712
+ File.fnmatch(pattern, @path, *args)
713
+ end
726
714
 
727
- # See <tt>File.open</tt>. Opens the file for reading or writing.
728
- def open(*args, &block) # :yield: file
729
- File.open(@path, *args, &block)
730
- end
715
+ # See <tt>File.fnmatch?</tt> (same as #fnmatch).
716
+ def fnmatch?(pattern, *args)
717
+ File.fnmatch?(pattern, @path, *args)
718
+ end
731
719
 
732
- # See <tt>File.readlink</tt>. Read symbolic link.
733
- def readlink
734
- self.class.new(File.readlink(@path))
735
- end
720
+ # See <tt>File.ftype</tt>. Returns "type" of file ("file", "directory",
721
+ # etc).
722
+ def ftype
723
+ File.ftype(@path)
724
+ end
736
725
 
737
- # See <tt>File.rename</tt>. Rename the file.
738
- def rename(to)
739
- File.rename(@path, to)
740
- end
726
+ # See <tt>File.link</tt>. Creates a hard link.
727
+ def make_link(old)
728
+ File.link(old, @path)
729
+ end
741
730
 
742
- # See <tt>File.stat</tt>. Returns a <tt>File::Stat</tt> object.
743
- def stat
744
- File.stat(@path)
745
- end
731
+ # See <tt>File.open</tt>. Opens the file for reading or writing.
732
+ def open(*args, &block) # :yield: file
733
+ File.open(@path, *args, &block)
734
+ end
746
735
 
747
- # See <tt>File.lstat</tt>.
748
- def lstat
749
- File.lstat(@path)
750
- end
736
+ # See <tt>File.readlink</tt>. Read symbolic link.
737
+ def readlink
738
+ self.class.new(File.readlink(@path))
739
+ end
751
740
 
752
- # See <tt>File.symlink</tt>. Creates a symbolic link.
753
- def make_symlink(old)
754
- File.symlink(old, @path)
755
- end
741
+ # See <tt>File.rename</tt>. Rename the file.
742
+ def rename(to)
743
+ File.rename(@path, to)
744
+ end
756
745
 
757
- # See <tt>File.truncate</tt>. Truncate the file to +length+ bytes.
758
- def truncate(length)
759
- File.truncate(@path, length)
760
- end
746
+ # See <tt>File.stat</tt>. Returns a <tt>File::Stat</tt> object.
747
+ def stat
748
+ File.stat(@path)
749
+ end
761
750
 
762
- # See <tt>File.utime</tt>. Update the access and modification times.
763
- def utime(atime, mtime)
764
- File.utime(atime, mtime, @path)
765
- end
751
+ # See <tt>File.lstat</tt>.
752
+ def lstat
753
+ File.lstat(@path)
754
+ end
766
755
 
767
- # See <tt>File.basename</tt>. Returns the last component of the path.
768
- def basename(*args)
769
- self.class.new(File.basename(@path, *args))
770
- end
756
+ # See <tt>File.symlink</tt>. Creates a symbolic link.
757
+ def make_symlink(old)
758
+ File.symlink(old, @path)
759
+ end
771
760
 
772
- # See <tt>File.dirname</tt>. Returns all but the last
773
- # component of the path.
774
- def dirname
775
- self.class.new(File.dirname(@path))
776
- end
761
+ # See <tt>File.truncate</tt>. Truncate the file to +length+ bytes.
762
+ def truncate(length)
763
+ File.truncate(@path, length)
764
+ end
777
765
 
778
- # See <tt>File.extname</tt>. Returns the file's extension.
779
- def extname
780
- File.extname(@path)
781
- end
766
+ # See <tt>File.utime</tt>. Update the access and modification times.
767
+ def utime(atime, mtime)
768
+ File.utime(atime, mtime, @path)
769
+ end
782
770
 
783
- # See <tt>File.expand_path</tt>.
784
- def expand_path(*args)
785
- self.class.new(File.expand_path(@path, *args))
786
- end
771
+ # See <tt>File.basename</tt>. Returns the last component of the path.
772
+ def basename(*args)
773
+ self.class.new(File.basename(@path, *args))
774
+ end
787
775
 
788
- # See <tt>File.split</tt>. Returns the #dirname and the #basename in an
789
- # Array.
790
- def split
791
- File.split(@path).map { |f| self.class.new(f) }
792
- end
776
+ # See <tt>File.dirname</tt>. Returns all but the last
777
+ # component of the path.
778
+ def dirname
779
+ self.class.new(File.dirname(@path))
780
+ end
793
781
 
794
- # See <tt>File.write</tt>. Returns the number of bytes written.
795
- def write(path, data)
796
- File.open(path, 'wb') do |file|
797
- return file.write(data)
798
- end
799
- end
782
+ # See <tt>File.extname</tt>. Returns the file's extension.
783
+ def extname
784
+ File.extname(@path)
800
785
  end
801
786
 
802
- # Pathname class
803
- class Pathname # * FileTest *
804
- # See <tt>FileTest.blockdev?</tt>.
805
- def blockdev?
806
- FileTest.blockdev?(@path)
807
- end
787
+ # See <tt>File.expand_path</tt>.
788
+ def expand_path(*args)
789
+ self.class.new(File.expand_path(@path, *args))
790
+ end
808
791
 
809
- # See <tt>FileTest.chardev?</tt>.
810
- def chardev?
811
- FileTest.chardev?(@path)
812
- end
792
+ # See <tt>File.split</tt>. Returns the #dirname and the #basename in an
793
+ # Array.
794
+ def split
795
+ File.split(@path).map { |f| self.class.new(f) }
796
+ end
813
797
 
814
- # See <tt>FileTest.executable?</tt>.
815
- def executable?
816
- FileTest.executable?(@path)
798
+ # See <tt>File.write</tt>. Returns the number of bytes written.
799
+ def write(path, data)
800
+ File.open(path, 'wb') do |file|
801
+ return file.write(data)
817
802
  end
803
+ end
804
+ end
818
805
 
819
- # See <tt>FileTest.executable_real?</tt>.
820
- def executable_real?
821
- FileTest.executable_real?(@path)
822
- end
806
+ # Pathname class
807
+ class Pathname # * FileTest *
808
+ # See <tt>FileTest.blockdev?</tt>.
809
+ def blockdev?
810
+ FileTest.blockdev?(@path)
811
+ end
823
812
 
824
- # See <tt>FileTest.exist?</tt>.
825
- def exist?
826
- FileTest.exist?(@path)
827
- end
813
+ # See <tt>FileTest.chardev?</tt>.
814
+ def chardev?
815
+ FileTest.chardev?(@path)
816
+ end
828
817
 
829
- # See <tt>FileTest.grpowned?</tt>.
830
- def grpowned?
831
- FileTest.grpowned?(@path)
832
- end
818
+ # See <tt>FileTest.executable?</tt>.
819
+ def executable?
820
+ FileTest.executable?(@path)
821
+ end
833
822
 
834
- # See <tt>FileTest.directory?</tt>.
835
- def directory?
836
- FileTest.directory?(@path)
837
- end
823
+ # See <tt>FileTest.executable_real?</tt>.
824
+ def executable_real?
825
+ FileTest.executable_real?(@path)
826
+ end
838
827
 
839
- # See <tt>FileTest.file?</tt>.
840
- def file?
841
- FileTest.file?(@path)
842
- end
828
+ # See <tt>FileTest.exist?</tt>.
829
+ def exist?
830
+ FileTest.exist?(@path)
831
+ end
843
832
 
844
- # See <tt>FileTest.pipe?</tt>.
845
- def pipe?
846
- FileTest.pipe?(@path)
847
- end
833
+ # See <tt>FileTest.grpowned?</tt>.
834
+ def grpowned?
835
+ FileTest.grpowned?(@path)
836
+ end
848
837
 
849
- # See <tt>FileTest.socket?</tt>.
850
- def socket?
851
- FileTest.socket?(@path)
852
- end
838
+ # See <tt>FileTest.directory?</tt>.
839
+ def directory?
840
+ FileTest.directory?(@path)
841
+ end
853
842
 
854
- # See <tt>FileTest.owned?</tt>.
855
- def owned?
856
- FileTest.owned?(@path)
857
- end
843
+ # See <tt>FileTest.file?</tt>.
844
+ def file?
845
+ FileTest.file?(@path)
846
+ end
858
847
 
859
- # See <tt>FileTest.readable?</tt>.
860
- def readable?
861
- FileTest.readable?(@path)
862
- end
848
+ # See <tt>FileTest.pipe?</tt>.
849
+ def pipe?
850
+ FileTest.pipe?(@path)
851
+ end
863
852
 
864
- # See <tt>FileTest.world_readable?</tt>.
865
- def world_readable?
866
- FileTest.world_readable?(@path)
867
- end
853
+ # See <tt>FileTest.socket?</tt>.
854
+ def socket?
855
+ FileTest.socket?(@path)
856
+ end
868
857
 
869
- # See <tt>FileTest.readable_real?</tt>.
870
- def readable_real?
871
- FileTest.readable_real?(@path)
872
- end
858
+ # See <tt>FileTest.owned?</tt>.
859
+ def owned?
860
+ FileTest.owned?(@path)
861
+ end
873
862
 
874
- # See <tt>FileTest.setuid?</tt>.
875
- def setuid?
876
- FileTest.setuid?(@path)
877
- end
863
+ # See <tt>FileTest.readable?</tt>.
864
+ def readable?
865
+ FileTest.readable?(@path)
866
+ end
878
867
 
879
- # See <tt>FileTest.setgid?</tt>.
880
- def setgid?
881
- FileTest.setgid?(@path)
882
- end
868
+ # See <tt>FileTest.world_readable?</tt>.
869
+ def world_readable?
870
+ FileTest.world_readable?(@path)
871
+ end
883
872
 
884
- # See <tt>FileTest.size</tt>.
885
- def size
886
- FileTest.size(@path)
887
- end
873
+ # See <tt>FileTest.readable_real?</tt>.
874
+ def readable_real?
875
+ FileTest.readable_real?(@path)
876
+ end
888
877
 
889
- # See <tt>FileTest.size?</tt>.
890
- def size?
891
- FileTest.size?(@path)
892
- end
878
+ # See <tt>FileTest.setuid?</tt>.
879
+ def setuid?
880
+ FileTest.setuid?(@path)
881
+ end
893
882
 
894
- # See <tt>FileTest.sticky?</tt>.
895
- def sticky?
896
- FileTest.sticky?(@path)
897
- end
883
+ # See <tt>FileTest.setgid?</tt>.
884
+ def setgid?
885
+ FileTest.setgid?(@path)
886
+ end
898
887
 
899
- # See <tt>FileTest.symlink?</tt>.
900
- def symlink?
901
- FileTest.symlink?(@path)
902
- end
888
+ # See <tt>FileTest.size</tt>.
889
+ def size
890
+ FileTest.size(@path)
891
+ end
903
892
 
904
- # See <tt>FileTest.writable?</tt>.
905
- def writable?
906
- FileTest.writable?(@path)
907
- end
893
+ # See <tt>FileTest.size?</tt>.
894
+ def size?
895
+ FileTest.size?(@path)
896
+ end
908
897
 
909
- # See <tt>FileTest.world_writable?</tt>.
910
- def world_writable?
911
- FileTest.world_writable?(@path)
912
- end
898
+ # See <tt>FileTest.sticky?</tt>.
899
+ def sticky?
900
+ FileTest.sticky?(@path)
901
+ end
913
902
 
914
- # See <tt>FileTest.writable_real?</tt>.
915
- def writable_real?
916
- FileTest.writable_real?(@path)
917
- end
903
+ # See <tt>FileTest.symlink?</tt>.
904
+ def symlink?
905
+ FileTest.symlink?(@path)
906
+ end
918
907
 
919
- # See <tt>FileTest.zero?</tt>.
920
- def zero?
921
- FileTest.zero?(@path)
922
- end
908
+ # See <tt>FileTest.writable?</tt>.
909
+ def writable?
910
+ FileTest.writable?(@path)
923
911
  end
924
912
 
925
- # Pathname class
926
- class Pathname # * Dir *
927
- # See <tt>Dir.glob</tt>. Returns or yields Pathname objects.
928
- def self.glob(*args) # :yield: pathname
929
- if block_given?
930
- Dir.glob(*args) { |f| yield new(f) }
931
- else
932
- Dir.glob(*args).map { |f| new(f) }
933
- end
934
- end
913
+ # See <tt>FileTest.world_writable?</tt>.
914
+ def world_writable?
915
+ FileTest.world_writable?(@path)
916
+ end
935
917
 
936
- # See <tt>Dir.getwd</tt>. Returns the current working directory
937
- # as a Pathname.
938
- def self.getwd
939
- new(Dir.getwd)
918
+ # See <tt>FileTest.writable_real?</tt>.
919
+ def writable_real?
920
+ FileTest.writable_real?(@path)
921
+ end
922
+
923
+ # See <tt>FileTest.zero?</tt>.
924
+ def zero?
925
+ FileTest.zero?(@path)
926
+ end
927
+ end
928
+
929
+ # Pathname class
930
+ class Pathname # * Dir *
931
+ # See <tt>Dir.glob</tt>. Returns or yields Pathname objects.
932
+ def self.glob(*args) # :yield: pathname
933
+ if block_given?
934
+ Dir.glob(*args) { |f| yield new(f) }
935
+ else
936
+ Dir.glob(*args).map { |f| new(f) }
940
937
  end
938
+ end
941
939
 
942
- class << self; alias_method :pwd, :getwd end
940
+ # See <tt>Dir.getwd</tt>. Returns the current working directory
941
+ # as a Pathname.
942
+ def self.getwd
943
+ new(Dir.getwd)
944
+ end
943
945
 
944
- # Return the entries (files and subdirectories) in the directory, each as
945
- # a Pathname object.
946
- def entries
947
- Dir.entries(@path).map { |f| self.class.new(f) }
948
- end
946
+ class << self; alias pwd getwd end
949
947
 
950
- # Iterates over the entries (files and subdirectories) in the directory.
951
- # It yields a Pathname object for each entry.
952
- #
953
- # This method has existed since 1.8.1.
954
- def each_entry(*) # :yield: pathname
955
- Dir.foreach(@path) { |f| yield self.class.new(f) }
956
- end
948
+ # Return the entries (files and subdirectories) in the directory, each as
949
+ # a Pathname object.
950
+ def entries
951
+ Dir.entries(@path).map { |f| self.class.new(f) }
952
+ end
957
953
 
958
- # See <tt>Dir.mkdir</tt>. Create the referenced directory.
959
- def mkdir(*args)
960
- Dir.mkdir(@path, *args)
961
- end
954
+ # Iterates over the entries (files and subdirectories) in the directory.
955
+ # It yields a Pathname object for each entry.
956
+ #
957
+ # This method has existed since 1.8.1.
958
+ def each_entry(*) # :yield: pathname
959
+ Dir.foreach(@path) { |f| yield self.class.new(f) }
960
+ end
962
961
 
963
- # See <tt>Dir.rmdir</tt>. Remove the referenced directory.
964
- def rmdir
965
- Dir.rmdir(@path)
966
- end
962
+ # See <tt>Dir.mkdir</tt>. Create the referenced directory.
963
+ def mkdir(*args)
964
+ Dir.mkdir(@path, *args)
965
+ end
967
966
 
968
- # See <tt>Dir.open</tt>.
969
- def opendir(&block) # :yield: dir
970
- Dir.open(@path, &block)
971
- end
967
+ # See <tt>Dir.rmdir</tt>. Remove the referenced directory.
968
+ def rmdir
969
+ Dir.rmdir(@path)
972
970
  end
973
971
 
974
- # Pathname class
975
- class Pathname # * Find *
976
- #
977
- # Pathname#find is an iterator to traverse a directory tree
978
- # in a depth first manner.
979
- # It yields a Pathname for each file under "this" directory.
980
- #
981
- # Since it is implemented by <tt>find.rb</tt>, <tt>Find.prune</tt>
982
- # can be used to control the traverse.
983
- #
984
- # If +self+ is <tt>.</tt>, yielded pathnames begin with
985
- # a filename in the current directory, not <tt>./</tt>.
986
- #
987
- def find(*) # :yield: pathname
988
- require 'find'
989
- if @path == '.'
990
- Find.find(@path) { |f| yield self.class.new(f.sub(%r{/\A\./}, '')) }
991
- else
992
- Find.find(@path) { |f| yield self.class.new(f) }
993
- end
994
- end
972
+ # See <tt>Dir.open</tt>.
973
+ def opendir(&block) # :yield: dir
974
+ Dir.open(@path, &block)
995
975
  end
976
+ end
996
977
 
997
- # Pathname class
998
- class Pathname # * FileUtils *
999
- # See <tt>FileUtils.mkpath</tt>. Creates a full path, including any
1000
- # intermediate directories that don't yet exist.
1001
- def mkpath
1002
- require 'fileutils'
1003
- FileUtils.mkpath(@path)
1004
- nil
978
+ # Pathname class
979
+ class Pathname # * Find *
980
+ #
981
+ # Pathname#find is an iterator to traverse a directory tree
982
+ # in a depth first manner.
983
+ # It yields a Pathname for each file under "this" directory.
984
+ #
985
+ # Since it is implemented by <tt>find.rb</tt>, <tt>Find.prune</tt>
986
+ # can be used to control the traverse.
987
+ #
988
+ # If +self+ is <tt>.</tt>, yielded pathnames begin with
989
+ # a filename in the current directory, not <tt>./</tt>.
990
+ #
991
+ def find(*) # :yield: pathname
992
+ require 'find'
993
+ if @path == '.'
994
+ Find.find(@path) { |f| yield self.class.new(f.sub(%r{/\A\./}, '')) }
995
+ else
996
+ Find.find(@path) { |f| yield self.class.new(f) }
1005
997
  end
998
+ end
999
+ end
1000
+
1001
+ # Pathname class
1002
+ class Pathname # * FileUtils *
1003
+ # See <tt>FileUtils.mkpath</tt>. Creates a full path, including any
1004
+ # intermediate directories that don't yet exist.
1005
+ def mkpath
1006
+ require 'fileutils'
1007
+ FileUtils.mkpath(@path)
1008
+ nil
1009
+ end
1006
1010
 
1007
- # See <tt>FileUtils.rm_r</tt>. Deletes a directory and all beneath it.
1008
- def rmtree
1009
- # The name "rmtree" is borrowed from File::Path of Perl.
1010
- # File::Path provides "mkpath" and "rmtree".
1011
- require 'fileutils'
1012
- FileUtils.rm_r(@path)
1013
- nil
1011
+ # See <tt>FileUtils.rm_r</tt>. Deletes a directory and all beneath it.
1012
+ def rmtree
1013
+ # The name "rmtree" is borrowed from File::Path of Perl.
1014
+ # File::Path provides "mkpath" and "rmtree".
1015
+ require 'fileutils'
1016
+ FileUtils.rm_r(@path)
1017
+ nil
1018
+ end
1019
+ end
1020
+
1021
+ # Pathname class
1022
+ class Pathname # * mixed *
1023
+ # Removes a file or directory, using <tt>File.unlink</tt> or
1024
+ # <tt>Dir.unlink</tt> as necessary.
1025
+ def unlink
1026
+ if File.directory? @path
1027
+ Dir.unlink @path
1028
+ else
1029
+ File.unlink @path
1014
1030
  end
1015
1031
  end
1016
1032
 
1017
- # Pathname class
1018
- class Pathname # * mixed *
1019
- # Removes a file or directory, using <tt>File.unlink</tt> or
1020
- # <tt>Dir.unlink</tt> as necessary.
1021
- def unlink
1033
+ alias delete unlink
1034
+
1035
+ if RUBY_VERSION > '2.4'
1036
+ # Checks if a file or directory is empty, using
1037
+ # <tt>FileTest.empty?</tt> or <tt>Dir.empty?</tt> as necessary.
1038
+ def empty?
1022
1039
  if File.directory? @path
1023
- Dir.unlink @path
1040
+ Dir.empty? @path
1024
1041
  else
1025
- File.unlink @path
1026
- end
1027
- end
1028
-
1029
- alias_method :delete, :unlink
1030
-
1031
- if RUBY_VERSION > '2.4'
1032
- # Checks if a file or directory is empty, using
1033
- # <tt>FileTest.empty?</tt> or <tt>Dir.empty?</tt> as necessary.
1034
- def empty?
1035
- if File.directory? @path
1036
- Dir.empty? @path
1037
- else
1038
- FileTest.empty? @path
1039
- end
1042
+ FileTest.empty? @path
1040
1043
  end
1041
1044
  end
1042
1045
  end
1046
+ end
1043
1047
 
1044
- # Pathname class
1045
- class Pathname
1046
- undef =~
1047
- end
1048
- end # RUBY_VERSION >= 1.9.3
1048
+ # Pathname class
1049
+ class Pathname
1050
+ undef =~
1051
+ end
1049
1052
  end