pathname2 1.5.0 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
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
- == Win32 Notes
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 old version and this version
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 old version,
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 "facade"
41
- require "ftools"
42
- require "fileutils"
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 'Win32API'
55
- @@PathStripToRoot = Win32API.new('shlwapi', 'PathStripToRoot', 'P', 'L')
56
- @@PathIsUNC = Win32API.new('shlwapi', 'PathIsUNC', 'P', 'L')
57
- @@PathIsURL = Win32API.new('shlwapi', 'PathIsURL', 'P', 'L')
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.0'
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 @@PathIsURL.call(path) > 0
86
+ if PathIsURL(path)
109
87
  buf = 0.chr * MAX_PATH
110
88
  len = [buf.length].pack("l")
111
- if @@PathCreateFromUrl.call(path, buf, len, 0) >= 0
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
- else
140
- pwd + self
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
- @@PathUndecorate.call(buf)
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
- @@PathUndecorate.call(buf)
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
- @@GetShortPathName.call(self, buf, buf.length)
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
- @@GetLongPathName.call(self, buf, buf.length)
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
- @@PathRemoveBackslash.call(str)
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
- @@PathRemoveBackslash.call(self)
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 @@PathStripToRoot.call(buf) > 0
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
- @@PathIsRoot.call(self) > 0
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
- @@PathIsUNC.call(self) > 0
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 = @@PathGetDriveNumber.call(self)
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
- @@PathAppend.call(buf, string)
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
- @@PathIsRelative.call(self) > 0
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 @@PathCanonicalize.call(path, self) > 0
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 @@PathCanonicalize.call(path, self) > 0
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/local/bin')
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.0', Pathname::VERSION)
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
@@ -16,13 +16,14 @@ else
16
16
  $LOAD_PATH.unshift Dir.pwd + "/lib"
17
17
  end
18
18
 
19
- unless PLATFORM.match("mswin")
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 "pathname2"
25
- require "test/unit"
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.0", Pathname::VERSION)
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.8.11
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.0
7
- date: 2006-04-17 00:00:00 -06:00
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
- - lib
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
- - !ruby/object:Gem::Version
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
- - Daniel J. Berger
30
+ - Daniel J. Berger
31
31
  files:
32
- - lib/pathname2.rb
33
- - CHANGES
34
- - MANIFEST
35
- - README
36
- - test/tc_pathname.rb
37
- - test/tc_pathname_win.rb
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
- - test/tc_pathname.rb
39
+ - test/tc_pathname.rb
40
40
  rdoc_options: []
41
+
41
42
  extra_rdoc_files:
42
- - README
43
- - CHANGES
43
+ - README
44
+ - CHANGES
44
45
  executables: []
46
+
45
47
  extensions: []
48
+
46
49
  requirements: []
50
+
47
51
  dependencies:
48
- - !ruby/object:Gem::Dependency
49
- name: facade
50
- version_requirement:
51
- version_requirements: !ruby/object:Gem::Version::Requirement
52
- requirements:
53
- -
54
- - ">="
55
- - !ruby/object:Gem::Version
56
- version: 1.0.0
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: