fakefs 0.13.3 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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