pathname2 1.4.0 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +7 -1
- data/README +7 -0
- data/lib/pathname2.rb +53 -5
- data/test/tc_pathname.rb +84 -1
- data/test/tc_pathname_win.rb +9 -1
- metadata +2 -2
data/CHANGES
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
-
== 1.4.
|
1
|
+
== 1.4.1 - 18-Feb-2005
|
2
|
+
* Added the Pathname#parent method.
|
3
|
+
* Added the Pathname#relative_path_from method.
|
4
|
+
* Bug fix for Pathname#pstrip on *nix.
|
5
|
+
* Corresponding test suite additions.
|
6
|
+
|
7
|
+
== 1.4.0 - 19-Dec-2005
|
2
8
|
* Added destructive and non-destructive methods for some methods - pstrip,
|
3
9
|
pstrip!, undecorate, undecorate!, clean and clean!.
|
4
10
|
* Added a C extension version of this package. You can use the C version
|
data/README
CHANGED
@@ -64,6 +64,9 @@
|
|
64
64
|
* The Pathname#+ method auto cleans.
|
65
65
|
* It uses a facade for all File and Dir methods, as well as all ftools
|
66
66
|
methods and most FileUtils methods.
|
67
|
+
* Pathname#clean works slightly differently. In the old version,
|
68
|
+
Pathname#clean("../a") returns "../a". In this version, it returns "a".
|
69
|
+
This affects other methods, such as Pathname#relative_path_from.
|
67
70
|
|
68
71
|
== Method Priority
|
69
72
|
Because there is some overlap in method names between File, Dir, ftools
|
@@ -87,6 +90,10 @@
|
|
87
90
|
Pathname#glob is not yet implemented in the C version.
|
88
91
|
Pathname#find is not implemented properly in the C version.
|
89
92
|
|
93
|
+
In Ruby 1.8.3 and later you will see a failure in the test suite regarding
|
94
|
+
'fu_world_writable?' from FileUtils. You can ignore this. That method is
|
95
|
+
supposed to be private. See ruby-core:7383.
|
96
|
+
|
90
97
|
== License
|
91
98
|
Ruby's
|
92
99
|
|
data/lib/pathname2.rb
CHANGED
@@ -77,7 +77,7 @@ class Pathname < String
|
|
77
77
|
Win32API.new("shlwapi", "PathRemoveBackslash", "P", "P")
|
78
78
|
end
|
79
79
|
|
80
|
-
VERSION = "1.4.
|
80
|
+
VERSION = "1.4.1"
|
81
81
|
MAX_PATH = 260
|
82
82
|
|
83
83
|
# Creates and returns a new Pathname object.
|
@@ -109,7 +109,7 @@ class Pathname < String
|
|
109
109
|
path = path.tr("/", @sep) if @win
|
110
110
|
super(path)
|
111
111
|
end
|
112
|
-
|
112
|
+
|
113
113
|
# Returns the children of the directory, files and subdirectories, as an
|
114
114
|
# array of Pathname objects. If you set +with_directory+ to +false+, then
|
115
115
|
# the returned pathnames will contain the filename only.
|
@@ -195,7 +195,7 @@ class Pathname < String
|
|
195
195
|
@@PathRemoveBackslash.call(str)
|
196
196
|
str.strip!
|
197
197
|
else
|
198
|
-
if str[-1] == @sep
|
198
|
+
if str[-1].chr == @sep
|
199
199
|
str.strip!
|
200
200
|
str.chop!
|
201
201
|
end
|
@@ -209,7 +209,7 @@ class Pathname < String
|
|
209
209
|
@@PathRemoveBackslash.call(self)
|
210
210
|
strip!
|
211
211
|
else
|
212
|
-
if self[-1] == @sep
|
212
|
+
if self[-1].chr == @sep
|
213
213
|
strip!
|
214
214
|
chop!
|
215
215
|
end
|
@@ -366,6 +366,54 @@ class Pathname < String
|
|
366
366
|
super
|
367
367
|
end
|
368
368
|
|
369
|
+
# Returns the parent directory of the given path.
|
370
|
+
def parent
|
371
|
+
self + ".."
|
372
|
+
end
|
373
|
+
|
374
|
+
# Returns a relative path from the argument to the receiver. If +self+
|
375
|
+
# is absolute, the argument must be absolute too. If +self+ is relative,
|
376
|
+
# the argument must be relative too.
|
377
|
+
#
|
378
|
+
# This method does not access the filesystem. It assumes no symlinks.
|
379
|
+
#
|
380
|
+
# Raises an ArgumentError if it cannot find a relative path.
|
381
|
+
def relative_path_from(base)
|
382
|
+
base = Pathname.new(base) unless base.kind_of?(Pathname)
|
383
|
+
|
384
|
+
if self.absolute? != base.absolute?
|
385
|
+
raise ArgumentError, "relative path between absolute and relative path"
|
386
|
+
end
|
387
|
+
|
388
|
+
return Pathname.new(".") if self == base
|
389
|
+
return self if base == "."
|
390
|
+
|
391
|
+
dest_arr = self.clean.to_a
|
392
|
+
base_arr = base.clean.to_a
|
393
|
+
dest_arr.delete('.')
|
394
|
+
base_arr.delete('.')
|
395
|
+
|
396
|
+
diff_arr = dest_arr - base_arr
|
397
|
+
|
398
|
+
while !base_arr.empty? && !dest_arr.empty? && base_arr[0] == dest_arr[0]
|
399
|
+
base_arr.shift
|
400
|
+
dest_arr.shift
|
401
|
+
end
|
402
|
+
|
403
|
+
if base_arr.include?("..")
|
404
|
+
raise ArgumentError, "base directory may not contain '..'"
|
405
|
+
end
|
406
|
+
|
407
|
+
base_arr.fill("..")
|
408
|
+
rel_path = base_arr + dest_arr
|
409
|
+
|
410
|
+
if rel_path.empty?
|
411
|
+
Pathname.new(".")
|
412
|
+
else
|
413
|
+
Pathname.new(rel_path.join(@sep))
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
369
417
|
# Adds two Pathname objects together, or a Pathname and a String. It
|
370
418
|
# also automatically cleans the Pathname.
|
371
419
|
#
|
@@ -390,7 +438,7 @@ class Pathname < String
|
|
390
438
|
buf = 0.chr * MAX_PATH
|
391
439
|
buf[0..self.length-1] = self
|
392
440
|
@@PathAppend.call(buf, string)
|
393
|
-
buf.
|
441
|
+
buf = buf.split("\0").first
|
394
442
|
return Pathname.new(buf) # PathAppend cleans automatically
|
395
443
|
end
|
396
444
|
|
data/test/tc_pathname.rb
CHANGED
@@ -26,6 +26,9 @@ class TC_Pathname < Test::Unit::TestCase
|
|
26
26
|
def setup
|
27
27
|
@abs_path = Pathname.new("/usr/local/bin")
|
28
28
|
@rel_path = Pathname.new("usr/local/bin")
|
29
|
+
@trl_path = Pathname.new("/usr/local/bin/")
|
30
|
+
@mul_path = Pathname.new("/usr/local/lib/local/lib")
|
31
|
+
@rul_path = Pathname.new("usr/local/lib/local/lib")
|
29
32
|
@cur_path = Pathname.new(Dir.pwd)
|
30
33
|
|
31
34
|
@abs_array = []
|
@@ -55,8 +58,88 @@ class TC_Pathname < Test::Unit::TestCase
|
|
55
58
|
assert_equal(int, result)
|
56
59
|
end
|
57
60
|
|
61
|
+
# Convenience method for test_relative_path_from
|
62
|
+
def assert_relpath(result, dest, base)
|
63
|
+
assert_equal(result, Pathname.new(dest).relative_path_from(base))
|
64
|
+
end
|
65
|
+
|
66
|
+
# Convenience method for test_relative_path_from_expected_errors
|
67
|
+
def assert_relpath_err(to, from)
|
68
|
+
assert_raise(ArgumentError) {
|
69
|
+
Pathname.new(to).relative_path_from(from)
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
58
73
|
def test_version
|
59
|
-
assert_equal("1.4.
|
74
|
+
assert_equal("1.4.1", Pathname::VERSION)
|
75
|
+
end
|
76
|
+
|
77
|
+
# These tests taken directly from Tanaka's pathname.rb. The one failure
|
78
|
+
# (commented out) is due to the fact that Tanaka's cleanpath method returns
|
79
|
+
# the cleanpath for "../a" as "../a" (i.e. it does nothing) whereas mine
|
80
|
+
# converts "../a" into just "a". Which is correct? I vote mine, because
|
81
|
+
# I don't see how you can get "more relative" from a relative path not
|
82
|
+
# already in the pathname.
|
83
|
+
#
|
84
|
+
def test_relative_path_from
|
85
|
+
assert_relpath("../a", "a", "b")
|
86
|
+
assert_relpath("../a", "a", "b/")
|
87
|
+
assert_relpath("../a", "a/", "b")
|
88
|
+
assert_relpath("../a", "a/", "b/")
|
89
|
+
assert_relpath("../a", "/a", "/b")
|
90
|
+
assert_relpath("../a", "/a", "/b/")
|
91
|
+
assert_relpath("../a", "/a/", "/b")
|
92
|
+
assert_relpath("../a", "/a/", "/b/")
|
93
|
+
|
94
|
+
assert_relpath("../b", "a/b", "a/c")
|
95
|
+
assert_relpath("../a", "../a", "../b")
|
96
|
+
|
97
|
+
assert_relpath("a", "a", ".")
|
98
|
+
assert_relpath("..", ".", "a")
|
99
|
+
|
100
|
+
assert_relpath(".", ".", ".")
|
101
|
+
assert_relpath(".", "..", "..")
|
102
|
+
assert_relpath("..", "..", ".")
|
103
|
+
|
104
|
+
assert_relpath("c/d", "/a/b/c/d", "/a/b")
|
105
|
+
assert_relpath("../..", "/a/b", "/a/b/c/d")
|
106
|
+
assert_relpath("../../../../e", "/e", "/a/b/c/d")
|
107
|
+
assert_relpath("../b/c", "a/b/c", "a/d")
|
108
|
+
|
109
|
+
assert_relpath("../a", "/../a", "/b")
|
110
|
+
#assert_relpath("../../a", "../a", "b") # fails
|
111
|
+
assert_relpath(".", "/a/../../b", "/b")
|
112
|
+
assert_relpath("..", "a/..", "a")
|
113
|
+
assert_relpath(".", "a/../b", "b")
|
114
|
+
|
115
|
+
assert_relpath("a", "a", "b/..")
|
116
|
+
assert_relpath("b/c", "b/c", "b/..")
|
117
|
+
|
118
|
+
assert_relpath_err("/", ".")
|
119
|
+
assert_relpath_err(".", "/")
|
120
|
+
assert_relpath_err("a", "..")
|
121
|
+
assert_relpath_err(".", "..")
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_parent
|
125
|
+
assert_respond_to(@abs_path, :parent)
|
126
|
+
assert_equal("/usr/local", @abs_path.parent)
|
127
|
+
assert_equal("usr/local", @rel_path.parent)
|
128
|
+
assert_equal("/", Pathname.new("/").parent)
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_pstrip
|
132
|
+
assert_respond_to(@trl_path, :pstrip)
|
133
|
+
assert_nothing_raised{ @trl_path.pstrip }
|
134
|
+
assert_equal("/usr/local/bin", @trl_path.pstrip)
|
135
|
+
assert_equal("/usr/local/bin/", @trl_path)
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_pstrip_bang
|
139
|
+
assert_respond_to(@trl_path, :pstrip!)
|
140
|
+
assert_nothing_raised{ @trl_path.pstrip! }
|
141
|
+
assert_equal("/usr/local/bin", @trl_path.pstrip!)
|
142
|
+
assert_equal("/usr/local/bin", @trl_path)
|
60
143
|
end
|
61
144
|
|
62
145
|
def test_ascend
|
data/test/tc_pathname_win.rb
CHANGED
@@ -25,6 +25,7 @@ require "pathname2"
|
|
25
25
|
require "test/unit"
|
26
26
|
|
27
27
|
class TC_Pathname_MSWin < Test::Unit::TestCase
|
28
|
+
|
28
29
|
def setup
|
29
30
|
@fpath = Pathname.new("C:/Program Files/Windows NT/Accessories")
|
30
31
|
@bpath = Pathname.new("C:\\Program Files\\Windows NT\\Accessories")
|
@@ -51,7 +52,7 @@ class TC_Pathname_MSWin < Test::Unit::TestCase
|
|
51
52
|
def test_version
|
52
53
|
assert_equal("1.4.0", Pathname::VERSION)
|
53
54
|
end
|
54
|
-
|
55
|
+
|
55
56
|
# Convenience method for test_plus
|
56
57
|
def assert_pathname_plus(a, b, c)
|
57
58
|
a = Pathname.new(a)
|
@@ -85,6 +86,13 @@ class TC_Pathname_MSWin < Test::Unit::TestCase
|
|
85
86
|
assert_equal("C:\\foo\\bar\\", @ppath)
|
86
87
|
assert_equal("C:\\foo\\..\\bar\\.\\baz", @cpath)
|
87
88
|
end
|
89
|
+
|
90
|
+
def test_parent
|
91
|
+
assert_respond_to(@bpath, :parent)
|
92
|
+
assert_equal("C:\\Program Files\\Windows NT", @bpath.parent)
|
93
|
+
assert_equal("foo\\bar", @npath.parent)
|
94
|
+
assert_equal("Z:\\", @rpath.parent)
|
95
|
+
end
|
88
96
|
|
89
97
|
def test_short_path
|
90
98
|
assert_respond_to(@bpath, :short_path)
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.10
|
|
3
3
|
specification_version: 1
|
4
4
|
name: pathname2
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.4.
|
7
|
-
date:
|
6
|
+
version: 1.4.1
|
7
|
+
date: 2006-02-18
|
8
8
|
summary: An alternate implementation of the Pathname class
|
9
9
|
require_paths:
|
10
10
|
- lib
|