pathname3 1.2.3 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/CHANGES +4 -0
  2. data/README +1 -1
  3. data/lib/pathname3.rb +106 -106
  4. data/pathname3.gemspec +1 -1
  5. metadata +6 -5
data/CHANGES CHANGED
@@ -1,5 +1,9 @@
1
1
  = pathname3 Changelog
2
2
 
3
+ == Version 1.2.5
4
+
5
+ * Fixed a bug in Pathname#mkpath (closes https://github.com/stouset/pathname3/issues/1)
6
+
3
7
  == Version 1.2.4
4
8
 
5
9
  * Usage examples in the README
data/README CHANGED
@@ -11,7 +11,7 @@ common.
11
11
  An implementation by Daniel J. Berger, pathname2, improved on the original
12
12
  significantly, adding Windows support, a Facade implementation, and a String-
13
13
  based implementation. While his version is faster, it's still very slow at
14
- instantiation. And it's Facade implementation misses some odd case methods
14
+ instantiation. And its Facade implementation misses some odd case methods
15
15
  like Pathname#join.
16
16
 
17
17
  This version will focus on being fast and lightweight, while still being pure
@@ -8,11 +8,11 @@ require 'find'
8
8
  #
9
9
  class Pathname < String
10
10
  SYMLOOP_MAX = 8 # deepest symlink traversal
11
-
11
+
12
12
  ROOT = '/'.freeze
13
13
  DOT = '.'.freeze
14
14
  DOT_DOT = '..'.freeze
15
-
15
+
16
16
  #
17
17
  # Creates a new Pathname. Any path with a null is rejected.
18
18
  #
@@ -20,10 +20,10 @@ class Pathname < String
20
20
  if path =~ %r{\0}
21
21
  raise ArgumentError, "path cannot contain ASCII NULLs"
22
22
  end
23
-
23
+
24
24
  super(path)
25
25
  end
26
-
26
+
27
27
  #
28
28
  # Compares pathnames, case-sensitively. Sorts directories higher than other
29
29
  # files named similarly.
@@ -33,7 +33,7 @@ class Pathname < String
33
33
  rescue NoMethodError # doesn't respond to to_str
34
34
  nil
35
35
  end
36
-
36
+
37
37
  #
38
38
  # Compares two pathnames for equality. Considers pathnames equal if they
39
39
  # both point to the same location, and are both absolute or both relative.
@@ -41,12 +41,12 @@ class Pathname < String
41
41
  def ==(other)
42
42
  left = self.cleanpath.tr('/', "\0").to_s
43
43
  right = other.to_str.to_path.cleanpath.tr('/', "\0").to_s
44
-
44
+
45
45
  left == right
46
46
  rescue NoMethodError # doesn't implement to_str
47
47
  false
48
48
  end
49
-
49
+
50
50
  #
51
51
  # Appends a component of a path to self. Returns a Pathname to the combined
52
52
  # path. Cleans any redundant components of the path.
@@ -54,7 +54,7 @@ class Pathname < String
54
54
  def +(path)
55
55
  dup << path
56
56
  end
57
-
57
+
58
58
  #
59
59
  # Appends (destructively) a component of a path to self. Replaces the
60
60
  # contents of the current Pathname with the new, combined path. Cleans any
@@ -63,14 +63,14 @@ class Pathname < String
63
63
  def <<(path)
64
64
  replace( join(path).cleanpath! )
65
65
  end
66
-
66
+
67
67
  #
68
68
  # Returns true if this is an absolute path.
69
69
  #
70
70
  def absolute?
71
71
  self[0, 1].to_s == ROOT
72
72
  end
73
-
73
+
74
74
  #
75
75
  # Yields to each component of the path, going up to the root.
76
76
  #
@@ -94,7 +94,7 @@ class Pathname < String
94
94
  yield self.class.join(parts[0, i])
95
95
  end
96
96
  end
97
-
97
+
98
98
  #
99
99
  # Returns all children of this path. "." and ".." are not included, since
100
100
  # they aren't under the current path.
@@ -102,7 +102,7 @@ class Pathname < String
102
102
  def children
103
103
  entries[2..-1]
104
104
  end
105
-
105
+
106
106
  #
107
107
  # Cleans the path by removing consecutive slashes, and useless dots.
108
108
  # Replaces the contents of the current Pathname.
@@ -110,7 +110,7 @@ class Pathname < String
110
110
  def cleanpath!
111
111
  parts = to_a
112
112
  final = []
113
-
113
+
114
114
  parts.each do |part|
115
115
  case part
116
116
  when DOT then next
@@ -124,28 +124,28 @@ class Pathname < String
124
124
  else final.push(part)
125
125
  end
126
126
  end
127
-
127
+
128
128
  replace(final.empty? ? DOT : self.class.join(*final))
129
129
  end
130
-
130
+
131
131
  #
132
132
  # Cleans the path by removing consecutive slashes, and useless dots.
133
133
  #
134
134
  def cleanpath
135
135
  dup.cleanpath!
136
136
  end
137
-
137
+
138
138
  #
139
139
  # Yields to each component of the path, going down from the root.
140
140
  #
141
- # Pathname.new('/path/to/some/file').ascend {|path| p path }
141
+ # Pathname.new('/path/to/some/file').descend {|path| p path }
142
142
  # "/"
143
143
  # "/path"
144
144
  # "/path/to"
145
145
  # "/path/to/some"
146
146
  # "/path/to/some/file"
147
147
  #
148
- # Pathname.new('a/relative/path').ascend {|path| p path }
148
+ # Pathname.new('a/relative/path').descend {|path| p path }
149
149
  # "a"
150
150
  # "a/relative"
151
151
  # "a/relative/path"
@@ -158,25 +158,25 @@ class Pathname < String
158
158
  yield self.class.join(parts[0, i])
159
159
  end
160
160
  end
161
-
161
+
162
162
  #
163
163
  # Returns true if this path is simply a '.'.
164
164
  #
165
165
  def dot?
166
166
  self == DOT
167
167
  end
168
-
168
+
169
169
  #
170
170
  # Returns true if this path is simply a '..'.
171
171
  #
172
172
  def dot_dot?
173
173
  self == DOT_DOT
174
174
  end
175
-
175
+
176
176
  #
177
177
  # Iterates over every component of the path.
178
178
  #
179
- # Pathname.new('/path/to/some/file').ascend {|path| p path }
179
+ # Pathname.new('/path/to/some/file').each_filename {|path| p path }
180
180
  # "/"
181
181
  # "path"
182
182
  # "to"
@@ -191,51 +191,51 @@ class Pathname < String
191
191
  def each_filename(&blk)
192
192
  to_a.each(&blk)
193
193
  end
194
-
194
+
195
195
  #
196
196
  # Returns true if the path is a mountpoint.
197
197
  #
198
198
  def mountpoint?
199
199
  stat1 = self.lstat
200
200
  stat2 = self.parent.lstat
201
-
201
+
202
202
  stat1.dev != stat2.dev || stat1.ino == stat2.ino
203
203
  rescue Errno::ENOENT
204
204
  false
205
205
  end
206
-
206
+
207
207
  #
208
208
  # Returns a path to the parent directory. Simply appends a "..".
209
209
  #
210
210
  def parent
211
211
  self + '..'
212
212
  end
213
-
213
+
214
214
  #
215
215
  # Resolves a path to locate a real location on the filesystem. Resolves
216
- # symlinks up to a deptho of SYMLOOP_MAX.
216
+ # symlinks up to a depth of SYMLOOP_MAX.
217
217
  #
218
218
  def realpath
219
219
  path = self
220
-
220
+
221
221
  SYMLOOP_MAX.times do
222
222
  link = path.readlink
223
223
  link = path.dirname + link if link.relative?
224
224
  path = link
225
225
  end
226
-
226
+
227
227
  raise Errno::ELOOP, self
228
228
  rescue Errno::EINVAL
229
229
  path.expand_path
230
230
  end
231
-
231
+
232
232
  #
233
233
  # Returns true if this is a relative path.
234
234
  #
235
235
  def relative?
236
236
  !absolute?
237
237
  end
238
-
238
+
239
239
  #
240
240
  # Returns this path as a relative location from +base+. The path and +base+
241
241
  # must both be relative or both be absolute. An ArgumentError is raised if
@@ -245,44 +245,44 @@ class Pathname < String
245
245
  #
246
246
  def relative_path_from(base)
247
247
  base = base.to_path
248
-
248
+
249
249
  # both must be relative, or both must be absolute
250
250
  if self.absolute? != base.absolute?
251
251
  raise ArgumentError, 'no relative path between a relative and absolute'
252
252
  end
253
-
253
+
254
254
  return self if base.dot?
255
255
  return DOT.to_path if self == base
256
-
256
+
257
257
  base = base.cleanpath.to_a
258
258
  dest = self.cleanpath.to_a
259
-
259
+
260
260
  while !dest.empty? && !base.empty? && dest[0] == base[0]
261
261
  base.shift
262
262
  dest.shift
263
263
  end
264
-
264
+
265
265
  base.shift if base[0] == DOT
266
266
  dest.shift if dest[0] == DOT
267
-
267
+
268
268
  if base.include?(DOT_DOT)
269
269
  raise ArgumentError, "base directory may not contain '#{DOT_DOT}'"
270
270
  end
271
-
271
+
272
272
  path = base.fill(DOT_DOT) + dest
273
273
  path = self.class.join(*path)
274
274
  path = DOT.to_path if path.empty?
275
-
275
+
276
276
  path
277
277
  end
278
-
278
+
279
279
  #
280
280
  # Returns true if this path points to the root of the filesystem.
281
281
  #
282
282
  def root?
283
283
  !!(self =~ %r{^#{ROOT}+$})
284
284
  end
285
-
285
+
286
286
  #
287
287
  # Splits the path into an array of its components.
288
288
  #
@@ -292,14 +292,14 @@ class Pathname < String
292
292
  array.insert(0, ROOT) if absolute?
293
293
  array
294
294
  end
295
-
295
+
296
296
  #
297
297
  # Returns self.
298
298
  #
299
299
  def to_path
300
300
  self
301
301
  end
302
-
302
+
303
303
  #
304
304
  # Unlinks the file or directory at the path.
305
305
  #
@@ -315,27 +315,27 @@ end
315
315
  class Pathname
316
316
  # See Dir::[]
317
317
  def self.[](pattern); Dir[pattern].map! {|d| d.to_path }; end
318
-
318
+
319
319
  # See Dir::pwd
320
320
  def self.pwd; Dir.pwd.to_path; end
321
-
321
+
322
322
  # See Dir::entries
323
323
  def entries; Dir.entries(self).map! {|e| e.to_path }; end
324
-
324
+
325
325
  # See Dir::mkdir
326
326
  def mkdir(mode = 0777); Dir.mkdir(self, mode); end
327
-
327
+
328
328
  # See Dir::open
329
329
  def opendir(&blk); Dir.open(self, &blk); end
330
-
330
+
331
331
  # See Dir::rmdir
332
332
  def rmdir; Dir.rmdir(self); end
333
-
333
+
334
334
  # See Dir::glob
335
335
  def self.glob(pattern, flags = 0)
336
336
  dirs = Dir.glob(pattern, flags)
337
337
  dirs.map! {|path| path.to_path }
338
-
338
+
339
339
  if block_given?
340
340
  dirs.each {|dir| yield dir }
341
341
  nil
@@ -343,16 +343,16 @@ class Pathname
343
343
  dirs
344
344
  end
345
345
  end
346
-
346
+
347
347
  # See Dir::glob
348
348
  def glob(pattern, flags = 0, &block)
349
349
  patterns = [pattern].flatten
350
350
  patterns.map! {|p| self.class.glob(self.to_s + p, flags, &block) }
351
351
  patterns.flatten
352
352
  end
353
-
353
+
354
354
  # See Dir::chdir
355
- def chdir
355
+ def chdir
356
356
  blk = lambda { yield self } if block_given?
357
357
  Dir.chdir(self, &blk)
358
358
  end
@@ -361,67 +361,67 @@ end
361
361
  class Pathname
362
362
  # See FileTest::blockdev?
363
363
  def blockdev?; FileTest.blockdev?(self); end
364
-
364
+
365
365
  # See FileTest::chardev?
366
366
  def chardev?; FileTest.chardev?(self); end
367
-
367
+
368
368
  # See FileTest::directory?
369
369
  def directory?; FileTest.directory?(self); end
370
-
370
+
371
371
  # See FileTest::executable?
372
372
  def executable?; FileTest.executable?(self); end
373
-
373
+
374
374
  # See FileTest::executable_real?
375
375
  def executable_real?; FileTest.executable_real?(self); end
376
-
376
+
377
377
  # See FileTest::exists?
378
378
  def exists?; FileTest.exists?(self); end
379
-
379
+
380
380
  # See FileTest::file?
381
381
  def file?; FileTest.file?(self); end
382
-
382
+
383
383
  # See FileTest::grpowned?
384
384
  def grpowned?; FileTest.grpowned?(self); end
385
-
385
+
386
386
  # See FileTest::owned?
387
387
  def owned?; FileTest.owned?(self); end
388
-
388
+
389
389
  # See FileTest::pipe?
390
390
  def pipe?; FileTest.pipe?(self); end
391
-
391
+
392
392
  # See FileTest::readable?
393
393
  def readable?; FileTest.readable?(self); end
394
-
394
+
395
395
  # See FileTest::readable_real?
396
396
  def readable_real?; FileTest.readable_real?(self); end
397
-
397
+
398
398
  # See FileTest::setgid?
399
399
  def setgid?; FileTest.setgit?(self); end
400
-
400
+
401
401
  # See FileTest::setuid?
402
402
  def setuid?; FileTest.setuid?(self); end
403
-
403
+
404
404
  # See FileTest::socket?
405
405
  def socket?; FileTest.socket?(self); end
406
-
406
+
407
407
  # See FileTest::sticky?
408
408
  def sticky?; FileTest.sticky?(self); end
409
-
409
+
410
410
  # See FileTest::symlink?
411
411
  def symlink?; FileTest.symlink?(self); end
412
-
412
+
413
413
  # See FileTest::world_readable?
414
414
  def world_readable?; FileTest.world_readable?(self); end
415
-
415
+
416
416
  # See FileTest::world_writable?
417
417
  def world_writable?; FileTest.world_writable?(self); end
418
-
418
+
419
419
  # See FileTest::writable?
420
420
  def writable?; FileTest.writable?(self); end
421
-
421
+
422
422
  # See FileTest::writable_real?
423
423
  def writable_real?; FileTest.writable_real?(self); end
424
-
424
+
425
425
  # See FileTest::zero?
426
426
  def zero?; FileTest.zero?(self); end
427
427
  end
@@ -429,22 +429,22 @@ end
429
429
  class Pathname
430
430
  # See File::atime
431
431
  def atime; File.atime(self); end
432
-
432
+
433
433
  # See File::ctime
434
434
  def ctime; File.ctime(self); end
435
-
435
+
436
436
  # See File::ftype
437
437
  def ftype; File.ftype(self); end
438
-
438
+
439
439
  # See File::lstat
440
440
  def lstat; File.lstat(self); end
441
-
441
+
442
442
  # See File::mtime
443
443
  def mtime; File.mtime(self); end
444
-
444
+
445
445
  # See File::stat
446
446
  def stat; File.stat(self); end
447
-
447
+
448
448
  # See File::utime
449
449
  def utime(atime, mtime); File.utime(self, atime, mtime); end
450
450
  end
@@ -452,72 +452,72 @@ end
452
452
  class Pathname
453
453
  # See File::join
454
454
  def self.join(*parts); File.join(*parts.reject {|p| p.empty? }).to_path; end
455
-
455
+
456
456
  # See File::basename
457
457
  def basename; File.basename(self).to_path; end
458
-
458
+
459
459
  # See File::chmod
460
460
  def chmod(mode); File.chmod(mode, self); end
461
-
461
+
462
462
  # See File::chown
463
463
  def chown(owner, group); File.chown(owner, group, self); end
464
-
464
+
465
465
  # See File::dirname
466
466
  def dirname; File.dirname(self).to_path; end
467
-
467
+
468
468
  # See File::expand_path
469
469
  def expand_path(from = nil); File.expand_path(self, from).to_path; end
470
-
470
+
471
471
  # See File::extname
472
472
  def extname; File.extname(self); end
473
-
473
+
474
474
  # See File::fnmatch
475
475
  def fnmatch?(pat, flags = 0); File.fnmatch(pat, self, flags); end
476
-
476
+
477
477
  # See File::join
478
478
  def join(*parts); self.class.join(self, *parts); end
479
-
479
+
480
480
  # See File::lchmod
481
481
  def lchmod(mode); File.lchmod(mode, self); end
482
-
482
+
483
483
  # See File::lchown
484
484
  def lchown(owner, group); File.lchown(owner, group, self); end
485
-
485
+
486
486
  # See File::link
487
487
  def link(to); File.link(self, to); end
488
-
488
+
489
489
  # See File::open
490
490
  def open(mode = 'r', perm = nil, &blk); File.open(self, mode, perm, &blk); end
491
-
491
+
492
492
  # See File::readlink
493
493
  def readlink; File.readlink(self).to_path; end
494
-
494
+
495
495
  # See File::rename
496
496
  def rename(to); File.rename(self, to); replace(to); end
497
-
497
+
498
498
  # See File::size
499
499
  def size; File.size(self); end
500
-
500
+
501
501
  # See File::size?
502
502
  def size?; File.size?(self); end
503
-
503
+
504
504
  # See File::split
505
505
  def split; File.split(self).map {|part| part.to_path }; end
506
-
506
+
507
507
  # See File::symlink
508
508
  def symlink(to); File.symlink(self, to); end
509
-
509
+
510
510
  # See File::truncate
511
511
  def truncate; File.truncate(self); end
512
512
  end
513
513
 
514
514
  class Pathname
515
515
  # See FileUtils::mkpath
516
- def mkpath; FileUtils.mkpath(self).to_path; end
517
-
516
+ def mkpath; FileUtils.mkpath(self).first.to_path; end
517
+
518
518
  # See FileUtils::rmtree
519
519
  def rmtree; FileUtils.rmtree(self).first.to_path; end
520
-
520
+
521
521
  # See FileUtils::touch
522
522
  def touch; FileUtils.touch(self).first.to_path; end
523
523
  end
@@ -525,13 +525,13 @@ end
525
525
  class Pathname
526
526
  # See IO::each_line
527
527
  def each_line(sep = $/, &blk); IO.foreach(self, sep, &blk); end
528
-
528
+
529
529
  # See IO::read
530
530
  def read(len = nil, off = 0); IO.read(self, len, off); end
531
-
531
+
532
532
  # See IO::readlines
533
533
  def readlines(sep = $/); IO.readlines(self, sep); end
534
-
534
+
535
535
  # See IO::sysopen
536
536
  def sysopen(mode = 'r', perm = nil); IO.sysopen(self, mode, perm); end
537
537
  end
@@ -545,7 +545,7 @@ class Pathname
545
545
  class << self
546
546
  alias getwd pwd
547
547
  end
548
-
548
+
549
549
  alias absolute expand_path
550
550
  alias delete unlink
551
551
  alias exist? exists?
@@ -4,7 +4,7 @@ Gem::Specification.new do |s|
4
4
  s.homepage = 'http://github.com/stouset/pathname3/'
5
5
 
6
6
  s.name = 'pathname3'
7
- s.version = '1.2.3'
7
+ s.version = '1.2.5'
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.description = 'Faster replacement for pathname and pathname2'
10
10
  s.summary = <<-DESC.strip.gsub(/\s+/, ' ')
metadata CHANGED
@@ -1,7 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pathname3
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ prerelease:
5
+ version: 1.2.5
5
6
  platform: ruby
6
7
  authors:
7
8
  - Stephen Touset
@@ -9,7 +10,7 @@ autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
12
 
12
- date: 2010-02-17 00:00:00 -05:00
13
+ date: 2011-03-21 00:00:00 -04:00
13
14
  default_executable:
14
15
  dependencies: []
15
16
 
@@ -39,21 +40,21 @@ rdoc_options: []
39
40
  require_paths:
40
41
  - lib
41
42
  required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
42
44
  requirements:
43
45
  - - ">="
44
46
  - !ruby/object:Gem::Version
45
47
  version: "0"
46
- version:
47
48
  required_rubygems_version: !ruby/object:Gem::Requirement
49
+ none: false
48
50
  requirements:
49
51
  - - ">="
50
52
  - !ruby/object:Gem::Version
51
53
  version: "0"
52
- version:
53
54
  requirements: []
54
55
 
55
56
  rubyforge_project:
56
- rubygems_version: 1.3.5
57
+ rubygems_version: 1.5.0
57
58
  signing_key:
58
59
  specification_version: 3
59
60
  summary: pathname3 is a third attempt at rewriting the eminently useful Pathname library in Ruby. The first version (packaged with Ruby) is extremely slow for many operations, as is the second one (by Daniel J. Berger). This version attempts to combine the best parts of both predecessors, while also maintaining speed. Namely, we use Daniel's String-based approach, while dumping Facade and sending messages to FileTest, File, Dir, and FileUtils explicitly (for clarity and predictability). Windows support will be provided in a later release. Donations of code toward this end would be appreciated.