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 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: