pathname2 1.4.0 → 1.4.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 +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
|