pathname2 1.5.0 → 1.5.1
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.
- data/CHANGES +9 -0
- data/README +11 -5
- data/lib/pathname2.rb +50 -50
- data/test/tc_pathname.rb +29 -2
- data/test/tc_pathname_win.rb +14 -4
- metadata +31 -28
data/CHANGES
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
== 1.5.1 - 28-Aug-2006
|
2
|
+
* Added the Kernel#pn method as a shortcut for Pathname.new.
|
3
|
+
* The Pathname#readlink now properly handles symbolic links. The 'fix'
|
4
|
+
from 1.4.4 did not work.
|
5
|
+
* The C extension uses your system's realpath() function for the
|
6
|
+
Pathname#readlink method if it has one.
|
7
|
+
* Added the '/' alias for '+'. So, p1 / p2 is the same as p1 + p2.
|
8
|
+
* The windows-pr package is now required on MS Windows.
|
9
|
+
|
1
10
|
== 1.5.0 - 17-Apr-2006
|
2
11
|
* Better subclass handling, in that some methods that previously returned
|
3
12
|
hardcoded Pathname.new now return self.class.new.
|
data/README
CHANGED
@@ -3,7 +3,10 @@
|
|
3
3
|
|
4
4
|
== Prerequisites
|
5
5
|
* Ruby 1.8.0 or later
|
6
|
-
* facade 1.0.0 or later (available on the RAA)
|
6
|
+
* facade 1.0.0 or later (available on the RAA and as a gem)
|
7
|
+
* windows-pr 0.5.1 or later (available on the RAA and as a gem)
|
8
|
+
|
9
|
+
The windows-pr package is only required on MS Windows.
|
7
10
|
|
8
11
|
== Installation, pure Ruby
|
9
12
|
=== Manual Installation
|
@@ -31,6 +34,7 @@
|
|
31
34
|
path2 = "../zap"
|
32
35
|
|
33
36
|
path1 + path2 # "/foo/bar/zap"
|
37
|
+
path1 / path2 # "/foo/bar/zap" (same as +)
|
34
38
|
path1.exists? # Does this path exist?
|
35
39
|
path1.dirname # "/foo/bar"
|
36
40
|
path1.to_a # ['foo','bar','baz']
|
@@ -43,7 +47,7 @@
|
|
43
47
|
path1.root # "C:\\"
|
44
48
|
path1.to_a # ['C:','foo','bar','baz']
|
45
49
|
|
46
|
-
==
|
50
|
+
== Windows Notes
|
47
51
|
All forward slashes are converted to backslashes for Pathname objects.
|
48
52
|
|
49
53
|
== Differences between Unix and Windows
|
@@ -52,7 +56,7 @@
|
|
52
56
|
while on Unix "." is returned. I consider this an extreme edge case and
|
53
57
|
will not worry myself with it.
|
54
58
|
|
55
|
-
== Differences between the
|
59
|
+
== Differences between Pathname in the standard library and this version
|
56
60
|
* It is a subclass of String (and thus, mixes in Enumerable).
|
57
61
|
* It has sensical to_a and root instance methods.
|
58
62
|
* It works on Windows and Unix. The current implementation does not work
|
@@ -60,15 +64,17 @@
|
|
60
64
|
paths.
|
61
65
|
* The Pathname#cleanpath method works differently - it always returns
|
62
66
|
a canonical pathname. In addition, there is no special consideration
|
63
|
-
for symlinks (yet).
|
67
|
+
for symlinks (yet), though I'm not sure it warrants it.
|
64
68
|
* The Pathname#+ method auto cleans.
|
65
69
|
* It uses a facade for all File and Dir methods, as well as all ftools
|
66
70
|
methods and most FileUtils methods.
|
67
|
-
* Pathname#clean works slightly differently. In the
|
71
|
+
* Pathname#clean works slightly differently. In the stdlib version,
|
68
72
|
Pathname#clean("../a") returns "../a". In this version, it returns "a".
|
69
73
|
This affects other methods, such as Pathname#relative_path_from.
|
70
74
|
* Accepts file urls and converts them to paths automatically, e.g.
|
71
75
|
file:///foo%20bar/baz becomes '/foo bar/baz'.
|
76
|
+
* Adds a Kernel level +pn+ method as a shortcut.
|
77
|
+
* Allows you to add paths together with the '/' operator.
|
72
78
|
|
73
79
|
== Method Priority
|
74
80
|
Because there is some overlap in method names between File, Dir, ftools
|
data/lib/pathname2.rb
CHANGED
@@ -37,9 +37,9 @@
|
|
37
37
|
# Copyright (c) 2005-2006 Daniel J. Berger.
|
38
38
|
# Licensed under the same terms as Ruby itself.
|
39
39
|
#
|
40
|
-
require
|
41
|
-
require
|
42
|
-
require
|
40
|
+
require 'facade'
|
41
|
+
require 'ftools'
|
42
|
+
require 'fileutils'
|
43
43
|
|
44
44
|
class PathnameError < StandardError; end
|
45
45
|
|
@@ -51,35 +51,13 @@ class Pathname < String
|
|
51
51
|
alias :_plus_ :+ # Used to prevent infinite loops in some cases
|
52
52
|
|
53
53
|
if RUBY_PLATFORM.match('mswin')
|
54
|
-
require '
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
@@PathCanonicalize = Win32API.new('shlwapi', 'PathCanonicalize','PP','L')
|
59
|
-
@@PathAppend = Win32API.new('shlwapi', 'PathAppend', 'PP', 'L')
|
60
|
-
@@PathIsRoot = Win32API.new('shlwapi', 'PathIsRoot', 'P', 'L')
|
61
|
-
@@PathIsDirectory = Win32API.new('shlwapi', 'PathIsDirectory', 'P', 'L')
|
62
|
-
@@PathIsRelative = Win32API.new('shlwapi', 'PathIsRelative', 'P', 'L')
|
63
|
-
@@PathFileExists = Win32API.new('shlwapi', 'PathFileExists', 'P', 'L')
|
64
|
-
@@PathUndecorate = Win32API.new('shlwapi', 'PathUndecorate', 'P', 'L')
|
65
|
-
|
66
|
-
@@GetShortPathName =
|
67
|
-
Win32API.new('kernel32', 'GetShortPathName', 'PPL', 'L')
|
68
|
-
|
69
|
-
@@GetLongPathName =
|
70
|
-
Win32API.new('kernel32', 'GetLongPathName', 'PPL', 'L')
|
71
|
-
|
72
|
-
@@PathGetDriveNumber =
|
73
|
-
Win32API.new('shlwapi', 'PathGetDriveNumber', 'P', 'L')
|
74
|
-
|
75
|
-
@@PathCreateFromUrl =
|
76
|
-
Win32API.new('shlwapi', 'PathCreateFromUrl', 'PPPL', 'L')
|
77
|
-
|
78
|
-
@@PathRemoveBackslash =
|
79
|
-
Win32API.new('shlwapi', 'PathRemoveBackslash', 'P', 'P')
|
54
|
+
require 'windows/path'
|
55
|
+
require 'windows/file'
|
56
|
+
include Windows::Path
|
57
|
+
include Windows::File
|
80
58
|
end
|
81
59
|
|
82
|
-
VERSION = '1.5.
|
60
|
+
VERSION = '1.5.1'
|
83
61
|
MAX_PATH = 260
|
84
62
|
|
85
63
|
# Creates and returns a new Pathname object.
|
@@ -105,10 +83,10 @@ class Pathname < String
|
|
105
83
|
# because Ruby's URI class does not (currently) parse absolute file URL's
|
106
84
|
# properly when they include a drive letter.
|
107
85
|
if @win
|
108
|
-
if
|
86
|
+
if PathIsURL(path)
|
109
87
|
buf = 0.chr * MAX_PATH
|
110
88
|
len = [buf.length].pack("l")
|
111
|
-
if
|
89
|
+
if PathCreateFromUrl(path, buf, len, 0)
|
112
90
|
path = buf.strip
|
113
91
|
else
|
114
92
|
raise PathnameError, "invalid file url: #{path}"
|
@@ -132,12 +110,23 @@ class Pathname < String
|
|
132
110
|
# exists on your filesystem. If it doesn't, an error is raised.
|
133
111
|
#
|
134
112
|
def realpath
|
135
|
-
pwd = self.class.new(Dir.pwd)
|
136
113
|
File.stat(self) # Check to ensure that the path exists
|
137
114
|
if File.symlink?(self)
|
138
|
-
self.class.new(File.readlink(self))
|
139
|
-
|
140
|
-
|
115
|
+
path = self.class.new(File.readlink(self))
|
116
|
+
if File.symlink?(path)
|
117
|
+
while File.symlink?(path)
|
118
|
+
if path.relative?
|
119
|
+
path = path + File.dirname(path)
|
120
|
+
else
|
121
|
+
path = self.class.new(File.readlink(path))
|
122
|
+
end
|
123
|
+
end
|
124
|
+
else
|
125
|
+
path = self.class.new(File.dirname(self)) + path
|
126
|
+
end
|
127
|
+
path
|
128
|
+
else
|
129
|
+
self.class.new(Dir.pwd) + self
|
141
130
|
end
|
142
131
|
end
|
143
132
|
|
@@ -174,7 +163,7 @@ class Pathname < String
|
|
174
163
|
end
|
175
164
|
buf = 0.chr * MAX_PATH
|
176
165
|
buf[0..self.length-1] = self
|
177
|
-
|
166
|
+
PathUndecorate(buf)
|
178
167
|
self.class.new(buf.split(0.chr).first)
|
179
168
|
end
|
180
169
|
|
@@ -188,7 +177,7 @@ class Pathname < String
|
|
188
177
|
end
|
189
178
|
buf = 0.chr * MAX_PATH
|
190
179
|
buf[0..self.length-1] = self
|
191
|
-
|
180
|
+
PathUndecorate(buf)
|
192
181
|
replace(buf.split(0.chr).first)
|
193
182
|
self
|
194
183
|
end
|
@@ -204,7 +193,7 @@ class Pathname < String
|
|
204
193
|
end
|
205
194
|
buf = 0.chr * MAX_PATH
|
206
195
|
buf[0..self.length-1] = self
|
207
|
-
|
196
|
+
GetShortPathName(self, buf, buf.length)
|
208
197
|
self.class.new(buf.split(0.chr).first)
|
209
198
|
end
|
210
199
|
|
@@ -219,7 +208,7 @@ class Pathname < String
|
|
219
208
|
end
|
220
209
|
buf = 0.chr * MAX_PATH
|
221
210
|
buf[0..self.length-1] = self
|
222
|
-
|
211
|
+
GetLongPathName(self, buf, buf.length)
|
223
212
|
self.class.new(buf.split(0.chr).first)
|
224
213
|
end
|
225
214
|
|
@@ -228,7 +217,7 @@ class Pathname < String
|
|
228
217
|
def pstrip
|
229
218
|
str = self.dup
|
230
219
|
if @win
|
231
|
-
|
220
|
+
PathRemoveBackslash(str)
|
232
221
|
str.strip!
|
233
222
|
else
|
234
223
|
if str[-1].chr == @sep
|
@@ -243,7 +232,7 @@ class Pathname < String
|
|
243
232
|
#
|
244
233
|
def pstrip!
|
245
234
|
if @win
|
246
|
-
|
235
|
+
PathRemoveBackslash(self)
|
247
236
|
strip!
|
248
237
|
else
|
249
238
|
if self[-1].chr == @sep
|
@@ -357,7 +346,7 @@ class Pathname < String
|
|
357
346
|
buf = 0.chr * MAX_PATH
|
358
347
|
buf[0..self.length-1] = self
|
359
348
|
|
360
|
-
if
|
349
|
+
if PathStripToRoot(buf)
|
361
350
|
dir = buf.split(0.chr).first
|
362
351
|
end
|
363
352
|
else
|
@@ -370,7 +359,7 @@ class Pathname < String
|
|
370
359
|
#
|
371
360
|
def root?
|
372
361
|
if @win
|
373
|
-
|
362
|
+
PathIsRoot(self)
|
374
363
|
else
|
375
364
|
self == root
|
376
365
|
end
|
@@ -386,7 +375,7 @@ class Pathname < String
|
|
386
375
|
raise NotImplementedError, "not supported on this platform"
|
387
376
|
end
|
388
377
|
|
389
|
-
|
378
|
+
PathIsUNC(self)
|
390
379
|
end
|
391
380
|
|
392
381
|
# Windows only
|
@@ -401,7 +390,7 @@ class Pathname < String
|
|
401
390
|
raise NotImplementedError, "not supported on this platform"
|
402
391
|
end
|
403
392
|
|
404
|
-
num =
|
393
|
+
num = PathGetDriveNumber(self)
|
405
394
|
num >= 0 ? num : nil
|
406
395
|
end
|
407
396
|
|
@@ -497,7 +486,7 @@ class Pathname < String
|
|
497
486
|
if @win
|
498
487
|
buf = 0.chr * MAX_PATH
|
499
488
|
buf[0..self.length-1] = self
|
500
|
-
|
489
|
+
PathAppend(buf, string)
|
501
490
|
buf = buf.split("\0").first
|
502
491
|
return self.class.new(buf) # PathAppend cleans automatically
|
503
492
|
end
|
@@ -515,6 +504,7 @@ class Pathname < String
|
|
515
504
|
|
516
505
|
self.class.new(new_string).clean
|
517
506
|
end
|
507
|
+
alias :/ :+
|
518
508
|
|
519
509
|
# Returns whether or not the path is an absolute path.
|
520
510
|
#
|
@@ -526,7 +516,7 @@ class Pathname < String
|
|
526
516
|
#
|
527
517
|
def relative?
|
528
518
|
if @win
|
529
|
-
|
519
|
+
PathIsRelative(self)
|
530
520
|
else
|
531
521
|
root == "."
|
532
522
|
end
|
@@ -540,7 +530,7 @@ class Pathname < String
|
|
540
530
|
|
541
531
|
if @win
|
542
532
|
path = 0.chr * MAX_PATH
|
543
|
-
if
|
533
|
+
if PathCanonicalize(path, self)
|
544
534
|
return self.class.new(path.split(0.chr).first)
|
545
535
|
else
|
546
536
|
return self
|
@@ -570,7 +560,7 @@ class Pathname < String
|
|
570
560
|
|
571
561
|
if @win
|
572
562
|
path = 0.chr * MAX_PATH
|
573
|
-
if
|
563
|
+
if PathCanonicalize(path, self)
|
574
564
|
replace(path.split(0.chr).first)
|
575
565
|
end
|
576
566
|
return self
|
@@ -861,3 +851,13 @@ class Pathname < String
|
|
861
851
|
FileUtils.copy_entry(self, *args)
|
862
852
|
end
|
863
853
|
end
|
854
|
+
|
855
|
+
module Kernel
|
856
|
+
# Usage: pn{ path }
|
857
|
+
#
|
858
|
+
# A shortcut for Pathname.new
|
859
|
+
#
|
860
|
+
def pn
|
861
|
+
instance_eval{ Pathname.new(yield) }
|
862
|
+
end
|
863
|
+
end
|
data/test/tc_pathname.rb
CHANGED
@@ -38,7 +38,7 @@ class TC_Pathname < Test::Unit::TestCase
|
|
38
38
|
@abs_array = []
|
39
39
|
@rel_array = []
|
40
40
|
|
41
|
-
@mypath = MyPathname.new('/usr/
|
41
|
+
@mypath = MyPathname.new('/usr/bin')
|
42
42
|
end
|
43
43
|
|
44
44
|
# Convenience method to verify that the receiver was not modified
|
@@ -77,7 +77,7 @@ class TC_Pathname < Test::Unit::TestCase
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def test_version
|
80
|
-
assert_equal('1.5.
|
80
|
+
assert_equal('1.5.1', Pathname::VERSION)
|
81
81
|
end
|
82
82
|
|
83
83
|
def test_file_url_path
|
@@ -88,7 +88,21 @@ class TC_Pathname < Test::Unit::TestCase
|
|
88
88
|
assert_respond_to(@abs_path, :realpath)
|
89
89
|
assert_equal(@pwd, Pathname.new('.').realpath)
|
90
90
|
assert_raises(Errno::ENOENT){ Pathname.new('../bogus').realpath }
|
91
|
+
assert_kind_of(Pathname, Pathname.new('/dev/stdin').realpath)
|
92
|
+
assert(Pathname.new('/dev/stdin') != Pathname.new('/dev/stdin').realpath)
|
93
|
+
end
|
91
94
|
|
95
|
+
def test_realpath_platform
|
96
|
+
case RUBY_PLATFORM
|
97
|
+
when /linux/i
|
98
|
+
path1 = '/dev/stdin'
|
99
|
+
assert_equal('/dev/pts/0', Pathname.new(path1).realpath)
|
100
|
+
when /sunos|solaris/i
|
101
|
+
path1 = '/dev/null'
|
102
|
+
path2 = '/dev/stdin'
|
103
|
+
assert_equal('/devices/pseudo/mm@0:null', Pathname.new(path1).realpath)
|
104
|
+
assert_equal('/dev/fd/0', Pathname.new(path2).realpath)
|
105
|
+
end
|
92
106
|
end
|
93
107
|
|
94
108
|
# These tests taken directly from Tanaka's pathname.rb. The one failure
|
@@ -347,6 +361,9 @@ class TC_Pathname < Test::Unit::TestCase
|
|
347
361
|
assert_pathname_plus('/', '/', '..')
|
348
362
|
assert_pathname_plus('.', '..', '..')
|
349
363
|
assert_pathname_plus('.', 'foo', '..')
|
364
|
+
|
365
|
+
# Alias
|
366
|
+
assert_equal('/foo/bar', Pathname.new('/foo') / Pathname.new('bar'))
|
350
367
|
end
|
351
368
|
|
352
369
|
# Any tests marked with '***' mean that this behavior is different than
|
@@ -417,12 +434,22 @@ class TC_Pathname < Test::Unit::TestCase
|
|
417
434
|
|
418
435
|
# Ensures that subclasses return the subclass as the class, not a hard
|
419
436
|
# coded Pathname.
|
437
|
+
#
|
420
438
|
def test_subclasses
|
421
439
|
assert_kind_of(MyPathname, @mypath)
|
422
440
|
assert_kind_of(MyPathname, @mypath + MyPathname.new('foo'))
|
423
441
|
assert_kind_of(MyPathname, @mypath.realpath)
|
424
442
|
assert_kind_of(MyPathname, @mypath.children.first)
|
425
443
|
end
|
444
|
+
|
445
|
+
# Test to ensure that the pn{ } shortcut works
|
446
|
+
#
|
447
|
+
def test_kernel_method
|
448
|
+
assert_respond_to(Kernel, :pn)
|
449
|
+
assert_nothing_raised{ pn{'/foo'} }
|
450
|
+
assert_kind_of(Pathname, pn{'/foo'})
|
451
|
+
assert_equal('/foo', pn{'/foo'})
|
452
|
+
end
|
426
453
|
|
427
454
|
def teardown
|
428
455
|
@pwd = nil
|
data/test/tc_pathname_win.rb
CHANGED
@@ -16,13 +16,14 @@ else
|
|
16
16
|
$LOAD_PATH.unshift Dir.pwd + "/lib"
|
17
17
|
end
|
18
18
|
|
19
|
-
unless
|
19
|
+
unless RUBY_PLATFORM.match("mswin")
|
20
20
|
STDERR.puts("Please run 'tc_pathname.rb' instead.")
|
21
21
|
exit
|
22
22
|
end
|
23
23
|
|
24
|
-
require
|
25
|
-
require
|
24
|
+
require 'facade' # Avoids annoying gems issue
|
25
|
+
require 'pathname2'
|
26
|
+
require 'test/unit'
|
26
27
|
|
27
28
|
class MyPathname < Pathname; end
|
28
29
|
|
@@ -55,7 +56,7 @@ class TC_Pathname_MSWin < Test::Unit::TestCase
|
|
55
56
|
end
|
56
57
|
|
57
58
|
def test_version
|
58
|
-
assert_equal("1.5.
|
59
|
+
assert_equal("1.5.1", Pathname::VERSION)
|
59
60
|
end
|
60
61
|
|
61
62
|
# Convenience method for test_plus
|
@@ -624,6 +625,15 @@ class TC_Pathname_MSWin < Test::Unit::TestCase
|
|
624
625
|
assert_kind_of(MyPathname, @mypath.realpath)
|
625
626
|
assert_kind_of(MyPathname, @mypath.children.first)
|
626
627
|
end
|
628
|
+
|
629
|
+
# Test to ensure that the pn{ } shortcut works
|
630
|
+
#
|
631
|
+
def test_kernel_method
|
632
|
+
assert_respond_to(Kernel, :pn)
|
633
|
+
assert_nothing_raised{ pn{'c:\foo'} }
|
634
|
+
assert_kind_of(Pathname, pn{'c:\foo'})
|
635
|
+
assert_equal('c:\foo', pn{'c:\foo'})
|
636
|
+
end
|
627
637
|
|
628
638
|
def teardown
|
629
639
|
@fpath = nil
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.
|
2
|
+
rubygems_version: 0.9.0
|
3
3
|
specification_version: 1
|
4
4
|
name: pathname2
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.5.
|
7
|
-
date: 2006-
|
6
|
+
version: 1.5.1
|
7
|
+
date: 2006-08-28 00:00:00 -06:00
|
8
8
|
summary: An alternate implementation of the Pathname class
|
9
9
|
require_paths:
|
10
|
-
|
10
|
+
- lib
|
11
11
|
email: djberg96@gmail.com
|
12
12
|
homepage: http://www.rubyforge.org/projects/shards
|
13
13
|
rubyforge_project:
|
@@ -18,40 +18,43 @@ bindir: bin
|
|
18
18
|
has_rdoc: true
|
19
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
20
|
requirements:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
version: 0.0.0
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
25
24
|
version:
|
26
25
|
platform: ruby
|
27
26
|
signing_key:
|
28
27
|
cert_chain:
|
28
|
+
post_install_message:
|
29
29
|
authors:
|
30
|
-
|
30
|
+
- Daniel J. Berger
|
31
31
|
files:
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
32
|
+
- lib/pathname2.rb
|
33
|
+
- CHANGES
|
34
|
+
- MANIFEST
|
35
|
+
- README
|
36
|
+
- test/tc_pathname.rb
|
37
|
+
- test/tc_pathname_win.rb
|
38
38
|
test_files:
|
39
|
-
|
39
|
+
- test/tc_pathname.rb
|
40
40
|
rdoc_options: []
|
41
|
+
|
41
42
|
extra_rdoc_files:
|
42
|
-
|
43
|
-
|
43
|
+
- README
|
44
|
+
- CHANGES
|
44
45
|
executables: []
|
46
|
+
|
45
47
|
extensions: []
|
48
|
+
|
46
49
|
requirements: []
|
50
|
+
|
47
51
|
dependencies:
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
version:
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: facade
|
54
|
+
version_requirement:
|
55
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: 1.0.0
|
60
|
+
version:
|