pathname2 1.6.1 → 1.6.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,13 @@
1
+ == 1.6.2 - 4-Aug-2009
2
+ * Now compatible with Ruby 1.9.x.
3
+ * License changed to Artistic 2.0.
4
+ * Added the Pathname.pwd method as a synonym for Pathname.new(Dir.pwd).
5
+ * Modified Pathname#dirname so that you can specify a level that indicates
6
+ how many levels up you want to retrieve. For example, if your path was
7
+ '/usr/local/bin', then path.dirname(2) would return '/usr'.
8
+ * Now compatible with Ruby 1.9.x.
9
+ * Bumped required version of the facade library to 1.0.4.
10
+
1
11
  == 1.6.1 - 8-Nov-2008
2
12
  * Added the Pathname#[] method, which accepts an index, an index plus a
3
13
  length, or a range, and returns appropriate the path element(s).
data/MANIFEST CHANGED
@@ -3,8 +3,8 @@
3
3
  * Rakefile
4
4
  * README
5
5
  * pathname2.gempsec
6
- * examples/bench_all.rb
7
- * examples/bench_plus.rb
6
+ * benchmarks/bench_all.rb
7
+ * benchmarks/bench_plus.rb
8
8
  * examples/example_pathname.rb
9
9
  * lib/pathname2.rb
10
10
  * test/test_pathname.rb
data/README CHANGED
@@ -94,7 +94,11 @@
94
94
  Suggestions welcome.
95
95
 
96
96
  == License
97
- Ruby's
97
+ Artistic 2.0
98
+
99
+ == Copyright
100
+ (C) 2003-2009 Daniel J. Berger
101
+ All rights reserved.
98
102
 
99
103
  == Warranty
100
104
  This library is provided "as is" and without any express or
@@ -103,4 +107,3 @@
103
107
 
104
108
  == Author
105
109
  Daniel J. Berger
106
- djberg96 at gmail dot com
@@ -0,0 +1,127 @@
1
+ #####################################################################
2
+ # bench_pathname.rb
3
+ #
4
+ # Benchmark suite for all methods of the Pathname class, excluding
5
+ # the facade methods.
6
+ #
7
+ # Use the Rake tasks to run this benchmark:
8
+ #
9
+ # => rake benchmark to run the pure Ruby benchmark.
10
+ #####################################################################
11
+ require 'benchmark'
12
+ require 'pathname2'
13
+ require 'rbconfig'
14
+
15
+ if Config::CONFIG['host_os'].match("mswin")
16
+ path1 = Pathname.new("C:\\Program Files\\Windows NT")
17
+ path2 = Pathname.new("Accessories")
18
+ path3 = Pathname.new("C:\\Program Files\\..\\.\\Windows NT")
19
+ else
20
+ path1 = Pathname.new("/usr/local")
21
+ path2 = Pathname.new("bin")
22
+ path3 = Pathname.new("/usr/../local/./bin")
23
+ path4 = Pathname.new("/dev/stdin")
24
+ end
25
+
26
+ MAX = 10000
27
+
28
+ Benchmark.bm(25) do |bench|
29
+ bench.report("Pathname.new(path)"){
30
+ MAX.times{ Pathname.new("/usr/local/bin") }
31
+ }
32
+
33
+ bench.report("Pathname#+(Pathname)"){
34
+ MAX.times{ path1 + path2 }
35
+ }
36
+
37
+ bench.report("Pathname#+(String)"){
38
+ MAX.times{ path1 + path2 }
39
+ }
40
+
41
+ bench.report("Pathname#children"){
42
+ MAX.times{ path1.children }
43
+ }
44
+
45
+ bench.report("Pathname#pstrip"){
46
+ MAX.times{ path1.pstrip }
47
+ }
48
+
49
+ bench.report("Pathname#pstrip!"){
50
+ MAX.times{ path1.pstrip! }
51
+ }
52
+
53
+ bench.report("Pathname#to_a"){
54
+ MAX.times{ path1.to_a }
55
+ }
56
+
57
+ bench.report("Pathname#descend"){
58
+ MAX.times{ path1.descend{} }
59
+ }
60
+
61
+ bench.report("Pathname#ascend"){
62
+ MAX.times{ path1.ascend{} }
63
+ }
64
+
65
+ bench.report("Pathname#root"){
66
+ MAX.times{ path1.root }
67
+ }
68
+
69
+ bench.report("Pathname#root?"){
70
+ MAX.times{ path1.root? }
71
+ }
72
+
73
+ bench.report("Pathname#<=>"){
74
+ MAX.times{ path1 <=> path2 }
75
+ }
76
+
77
+ bench.report("Pathname#absolute?"){
78
+ MAX.times{ path1.absolute? }
79
+ }
80
+
81
+ bench.report("Pathname#relative?"){
82
+ MAX.times{ path1.relative? }
83
+ }
84
+
85
+ bench.report("Pathname#clean"){
86
+ MAX.times{ path3.clean }
87
+ }
88
+
89
+ bench.report("Pathname#clean!"){
90
+ MAX.times{ path3.clean! }
91
+ }
92
+
93
+ # Platform specific tests
94
+ if Config::CONFIG['host_os'].match("mswin")
95
+ bench.report("Pathname.new(file_url)"){
96
+ MAX.times{ Pathname.new("file:///C:/usr/local/bin") }
97
+ }
98
+
99
+ bench.report("Pathname#drive_number"){
100
+ MAX.times{ path1.drive_number }
101
+ }
102
+
103
+ bench.report("Pathname#unc?"){
104
+ MAX.times{ path1.unc? }
105
+ }
106
+
107
+ bench.report("Pathname#undecorate"){
108
+ MAX.times{ path1.undecorate }
109
+ }
110
+
111
+ bench.report("Pathname#undecorate!"){
112
+ MAX.times{ path1.undecorate! }
113
+ }
114
+
115
+ bench.report("Pathname#short_path"){
116
+ MAX.times{ path1.short_path }
117
+ }
118
+
119
+ bench.report("Pathname#long_path"){
120
+ MAX.times{ path1.long_path }
121
+ }
122
+ else
123
+ bench.report("Pathname#realpath"){
124
+ MAX.times{ path4.realpath }
125
+ }
126
+ end
127
+ end
@@ -0,0 +1,34 @@
1
+ ##############################################################################
2
+ # Compare File.join vs. Pathname#+
3
+ #
4
+ # This benchmark was inspired by a post by Thomas Sawyer. Note that
5
+ # Pathname#+ will never be as fast as File.join, but this provides a
6
+ # good base for further optimizations.
7
+ #
8
+ # Also keep in mind that File.join does no path normalization whatsoever,
9
+ # e.g. File.join("foo", "/bar") behaves differently than Pathname.new("foo")
10
+ # + Pathname.new("/bar"). This is true of both the pathname and pathname2
11
+ # packages.
12
+ #
13
+ # You can run this via the 'rake benchmark_plus' task.
14
+ ##############################################################################
15
+ require 'benchmark'
16
+ require 'pathname2'
17
+
18
+ MAX = 10000
19
+
20
+ s1 = "a/b/c"
21
+ s2 = "d/e/f"
22
+
23
+ path1 = Pathname.new(s1)
24
+ path2 = Pathname.new(s2)
25
+
26
+ Benchmark.bm(10) do |bench|
27
+ bench.report("File.join"){
28
+ MAX.times{ File.join(s1, s2) }
29
+ }
30
+
31
+ bench.report("Pathname#+"){
32
+ MAX.times{ path1 + path2 }
33
+ }
34
+ end
@@ -0,0 +1,25 @@
1
+ ########################################################################
2
+ # example_pathname.rb
3
+ #
4
+ # Some examples to demonstrate the behavior of the pathname2 library.
5
+ ########################################################################
6
+ require 'pathname2'
7
+
8
+ puts "VERSION: " + Pathname::VERSION
9
+
10
+ path1 = Pathname.new("foo/bar")
11
+ path2 = Pathname.new("baz/blah")
12
+
13
+ path3 = Pathname.new("foo/../bar")
14
+ path4 = Pathname.new("../baz")
15
+
16
+ p path1 + path2 # foo/bar/baz/blah
17
+ p path3 + path4 # baz
18
+
19
+ # Shortcut syntax
20
+ path = pn{ "C:\\Documents and Settings\\snoopy\\My Documents" }
21
+
22
+ p path[0] # C:
23
+ p path[1] # Documents and Settings
24
+ p path[0,2] # C:\\Documents and Settings
25
+ p path[0..2] # C:\\Documents and Settings\\snoopy
data/lib/pathname2.rb CHANGED
@@ -52,13 +52,19 @@ class Pathname < String
52
52
  class Error < StandardError; end
53
53
  extend Facade
54
54
 
55
- facade File, File.methods(false) - [
56
- 'chmod', 'lchmod', 'chown', 'lchown', 'fnmatch', 'fnmatch?', 'link',
57
- 'open', 'rename', 'symlink', 'truncate', 'utime', 'basename',
58
- 'expand_path', 'join'
55
+ facade File, File.methods(false).map{ |m| m.to_sym } - [
56
+ :chmod, :lchmod, :chown, :lchown, :dirname, :fnmatch, :fnmatch?,
57
+ :link, :open, :rename, :symlink, :truncate, :utime, :basename,
58
+ :expand_path, :join
59
59
  ]
60
60
 
61
- facade Dir, Dir.methods(false) - ['chdir','glob','foreach','mkdir','open']
61
+ facade Dir, Dir.methods(false).map{ |m| m.to_sym } - [
62
+ :chdir,
63
+ :glob,
64
+ :foreach,
65
+ :mkdir,
66
+ :open
67
+ ]
62
68
 
63
69
  private
64
70
 
@@ -73,12 +79,24 @@ class Pathname < String
73
79
 
74
80
  public
75
81
 
76
- VERSION = '1.6.1'
82
+ # The version of this library
83
+ VERSION = '1.6.2'
77
84
 
78
- if !defined? MAXPATH
79
- MAXPATH = 1024
85
+ # The maximum length of a path
86
+ MAXPATH = 1024 unless defined? MAXPATH # Yes, I willfully violate POSIX
87
+
88
+ # Returns the expanded path of the current working directory.
89
+ #
90
+ # Synonym for Pathname.new(Dir.pwd).
91
+ #
92
+ def self.pwd
93
+ new(Dir.pwd)
80
94
  end
81
95
 
96
+ class << self
97
+ alias getwd pwd
98
+ end
99
+
82
100
  # Creates and returns a new Pathname object.
83
101
  #
84
102
  # On platforms that define File::ALT_SEPARATOR, all forward slashes are
@@ -468,7 +486,7 @@ class Pathname < String
468
486
  # Examples:
469
487
  #
470
488
  # Pathname.new('/usr/local').root # => '/'
471
- # Pathname.new('lib') # => '.'
489
+ # Pathname.new('lib').root # => '.'
472
490
  #
473
491
  # On MS Windows:
474
492
  #
@@ -476,7 +494,8 @@ class Pathname < String
476
494
  # Pathname.new('\\some\share\foo').root # => '\\some\share'
477
495
  #
478
496
  def root
479
- dir = "."
497
+ dir = "."
498
+
480
499
  if @win
481
500
  buf = 0.chr * MAXPATH
482
501
  buf[0..self.length-1] = self
@@ -487,6 +506,7 @@ class Pathname < String
487
506
  else
488
507
  dir = "/" if self =~ /^\//
489
508
  end
509
+
490
510
  self.class.new(dir)
491
511
  end
492
512
 
@@ -565,15 +585,15 @@ class Pathname < String
565
585
  # Pathname.new('/usr/local/bin').parent # => '/usr/local'
566
586
  #
567
587
  def parent
568
- self + ".."
588
+ self + ".." # Use our custom '+' method
569
589
  end
570
590
 
571
- # Returns a relative path from the argument to the receiver. If +self+
572
- # is absolute, the argument must be absolute too. If +self+ is relative,
573
- # the argument must be relative too. For relative paths, this method
591
+ # Returns a relative path from the argument to the receiver. If +self+
592
+ # is absolute, the argument must be absolute too. If +self+ is relative,
593
+ # the argument must be relative too. For relative paths, this method uses
574
594
  # an imaginary, common parent path.
575
595
  #
576
- # This method does not access the filesystem. It assumes no symlinks.
596
+ # This method does not access the filesystem. It assumes no symlinks.
577
597
  # You should only compare directories against directories, or files against
578
598
  # files, or you may get unexpected results.
579
599
  #
@@ -780,6 +800,32 @@ class Pathname < String
780
800
 
781
801
  alias cleanpath! clean!
782
802
 
803
+ # Similar to File.dirname, but this method allows you to specify the number
804
+ # of levels up you wish to refer to.
805
+ #
806
+ # The default level is 1, i.e. it works the same as File.dirname. A level of
807
+ # 0 will return the original path. A level equal to or greater than the
808
+ # number of path elements will return the root path.
809
+ #
810
+ # A number less than 0 will raise an ArgumentError.
811
+ #
812
+ # Example:
813
+ #
814
+ # path = Pathname.new('/usr/local/bin/ruby')
815
+ #
816
+ # puts path.dirname # => /usr/local/bin
817
+ # puts path.dirname(2) # => /usr/local
818
+ # puts path.dirname(3) # => /usr
819
+ # puts path.dirname(9) # => /
820
+ #
821
+ def dirname(level = 1)
822
+ raise ArgumentError if level < 0
823
+ local_path = self.dup
824
+
825
+ level.times{ |n| local_path = File.dirname(local_path) }
826
+ local_path
827
+ end
828
+
783
829
  #-- Find facade
784
830
 
785
831
  # Pathname#find is an iterator to traverse a directory tree in a depth first
@@ -5,23 +5,30 @@
5
5
  # via the Rake tasks, i.e. 'rake test_pr' to test the pure Ruby version, or
6
6
  # 'rake test_c' to test the C version.
7
7
  ##############################################################################
8
- require 'pathname2'
8
+ require 'rubygems'
9
+ gem 'test-unit'
10
+
9
11
  require 'test/unit'
12
+ require 'pathname2'
10
13
  require 'rbconfig'
11
14
  include Config
12
15
 
13
16
  class MyPathname < Pathname; end
14
17
 
15
18
  class TC_Pathname < Test::Unit::TestCase
19
+ def self.startup
20
+ Dir.chdir(File.expand_path(File.dirname(__FILE__)))
21
+ @@pwd = Dir.pwd
22
+ end
23
+
16
24
  def setup
17
- @pwd = Dir.pwd
18
25
  @abs_path = Pathname.new('/usr/local/bin')
19
26
  @rel_path = Pathname.new('usr/local/bin')
20
27
  @trl_path = Pathname.new('/usr/local/bin/')
21
28
  @mul_path = Pathname.new('/usr/local/lib/local/lib')
22
29
  @rul_path = Pathname.new('usr/local/lib/local/lib')
23
30
  @url_path = Pathname.new('file:///foo%20bar/baz')
24
- @cur_path = Pathname.new(Dir.pwd)
31
+ @cur_path = Pathname.new(@@pwd)
25
32
 
26
33
  @abs_array = []
27
34
  @rel_array = []
@@ -65,7 +72,7 @@ class TC_Pathname < Test::Unit::TestCase
65
72
  end
66
73
 
67
74
  def test_version
68
- assert_equal('1.6.1', Pathname::VERSION)
75
+ assert_equal('1.6.2', Pathname::VERSION)
69
76
  end
70
77
 
71
78
  def test_file_url_path
@@ -74,7 +81,7 @@ class TC_Pathname < Test::Unit::TestCase
74
81
 
75
82
  def test_realpath
76
83
  assert_respond_to(@abs_path, :realpath)
77
- assert_equal(@pwd, Pathname.new('.').realpath)
84
+ assert_equal(@@pwd, Pathname.new('.').realpath)
78
85
  assert_kind_of(Pathname, Pathname.new('/dev/stdin').realpath)
79
86
  assert(Pathname.new('/dev/stdin') != Pathname.new('/dev/stdin').realpath)
80
87
  if CONFIG['host_os'] =~ /bsd|darwin|mac/i
@@ -212,46 +219,27 @@ class TC_Pathname < Test::Unit::TestCase
212
219
  assert_non_destructive
213
220
  end
214
221
 
215
- def test_children
222
+ def test_children_with_directory
216
223
  assert_respond_to(@cur_path, :children)
217
224
  assert_nothing_raised{ @cur_path.children }
218
225
  assert_kind_of(Array, @cur_path.children)
219
-
220
- # Delete Eclipse related files
221
- children = @cur_path.children
222
- children.delete_if{ |e| File.basename(e) == 'CVS' }
223
- children.delete_if{ |e| File.basename(e) == '.cvsignore' }
224
- children.delete_if{ |e| File.basename(e) == '.project' }
225
-
226
- assert_equal(
227
- [
228
- Dir.pwd + '/CHANGES',
229
- Dir.pwd + '/MANIFEST',
230
- Dir.pwd + '/README',
231
- Dir.pwd + '/Rakefile',
232
- Dir.pwd + '/examples',
233
- Dir.pwd + '/ext',
234
- Dir.pwd + '/lib',
235
- Dir.pwd + '/pathname2.gemspec',
236
- Dir.pwd + '/test'
237
- ],
238
- children.sort
239
- )
240
-
241
- # Delete Eclipse related files
242
- children = @cur_path.children(false)
243
- children.delete('CVS')
244
- children.delete('.cvsignore')
245
- children.delete('.project')
246
-
226
+
227
+ children = @cur_path.children.sort.reject{ |f| f.include?('CVS') }
247
228
  assert_equal(
248
229
  [
249
- 'CHANGES', 'MANIFEST', 'README', 'Rakefile', 'examples', 'ext',
250
- 'lib', 'pathname2.gemspec', 'test'
230
+ Dir.pwd + '/test_pathname.rb',
231
+ Dir.pwd + '/test_pathname_windows.rb'
251
232
  ],
252
233
  children.sort
253
234
  )
254
235
  end
236
+
237
+ def test_children_without_directory
238
+ assert_nothing_raised{ @cur_path.children(false) }
239
+
240
+ children = @cur_path.children(false).reject{ |f| f.include?('CVS') }
241
+ assert_equal(['test_pathname.rb', 'test_pathname_windows.rb'], children.sort)
242
+ end
255
243
 
256
244
  def test_unc
257
245
  assert_raises(NotImplementedError){ @abs_path.unc? }
@@ -388,6 +376,25 @@ class TC_Pathname < Test::Unit::TestCase
388
376
  assert_non_destructive
389
377
  end
390
378
 
379
+ def test_dirname_basic
380
+ assert_respond_to(@abs_path, :dirname)
381
+ assert_nothing_raised{ @abs_path.dirname }
382
+ assert_kind_of(String, @abs_path.dirname)
383
+ end
384
+
385
+ def test_dirname
386
+ assert_equal('/usr/local', @abs_path.dirname)
387
+ assert_equal('/usr/local/bin', @abs_path.dirname(0))
388
+ assert_equal('/usr/local', @abs_path.dirname(1))
389
+ assert_equal('/usr', @abs_path.dirname(2))
390
+ assert_equal('/', @abs_path.dirname(3))
391
+ assert_equal('/', @abs_path.dirname(9))
392
+ end
393
+
394
+ def test_dirname_expected_errors
395
+ assert_raise(ArgumentError){ @abs_path.dirname(-1) }
396
+ end
397
+
391
398
  def test_facade_io
392
399
  assert_respond_to(@abs_path, :foreach)
393
400
  assert_respond_to(@abs_path, :read)
@@ -448,8 +455,13 @@ class TC_Pathname < Test::Unit::TestCase
448
455
  assert_equal('/foo', pn{'/foo'})
449
456
  end
450
457
 
458
+ def test_pwd_singleton_method
459
+ assert_respond_to(Pathname, :pwd)
460
+ assert_kind_of(String, Pathname.pwd)
461
+ assert_equal(@@pwd, Pathname.pwd)
462
+ end
463
+
451
464
  def teardown
452
- @pwd = nil
453
465
  @abs_path = nil
454
466
  @rel_path = nil
455
467
  @trl_path = nil
@@ -465,4 +477,8 @@ class TC_Pathname < Test::Unit::TestCase
465
477
  @abs_array.clear
466
478
  @rel_array.clear
467
479
  end
480
+
481
+ def self.shutdown
482
+ @@pwd = nil
483
+ end
468
484
  end
@@ -60,7 +60,7 @@ class TC_Pathname_MSWin < Test::Unit::TestCase
60
60
  end
61
61
 
62
62
  def test_version
63
- assert_equal("1.6.1", Pathname::VERSION)
63
+ assert_equal('1.6.2', Pathname::VERSION)
64
64
  end
65
65
 
66
66
  # Convenience method for test_plus
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pathname2
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.1
4
+ version: 1.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel J. Berger
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-08 00:00:00 -07:00
12
+ date: 2009-08-04 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,9 +20,19 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 1.0.0
23
+ version: 1.0.4
24
24
  version:
25
- description: An alternate implementation of the Pathname class
25
+ - !ruby/object:Gem::Dependency
26
+ name: test-unit
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.0.3
34
+ version:
35
+ description: " The pathname2 library provides an implementation of the Pathname\n class different from the one that ships as part of the Ruby standard\n library. It is a subclass of String, though several methods have been\n overridden to better fit a path context. In addition, it supports file\n URL's as paths, provides additional methods for Windows paths, and\n handles UNC paths on Windows properly. See the README file for more\n details.\n"
26
36
  email: djberg96@gmail.com
27
37
  executables: []
28
38
 
@@ -33,15 +43,19 @@ extra_rdoc_files:
33
43
  - CHANGES
34
44
  - MANIFEST
35
45
  files:
46
+ - benchmarks/bench_pathname.rb
47
+ - benchmarks/bench_plus.rb
48
+ - examples/example_pathname.rb
36
49
  - lib/pathname2.rb
37
- - CHANGES
38
- - MANIFEST
39
- - Rakefile
40
- - README
41
50
  - test/test_pathname.rb
42
51
  - test/test_pathname_windows.rb
52
+ - README
53
+ - CHANGES
54
+ - MANIFEST
43
55
  has_rdoc: true
44
56
  homepage: http://www.rubyforge.org/projects/shards
57
+ licenses:
58
+ - Artistic 2.0
45
59
  post_install_message:
46
60
  rdoc_options: []
47
61
 
@@ -62,9 +76,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
62
76
  requirements: []
63
77
 
64
78
  rubyforge_project: shards
65
- rubygems_version: 1.2.0
79
+ rubygems_version: 1.3.5
66
80
  signing_key:
67
- specification_version: 2
81
+ specification_version: 3
68
82
  summary: An alternate implementation of the Pathname class
69
83
  test_files:
70
84
  - test/test_pathname.rb
data/Rakefile DELETED
@@ -1,32 +0,0 @@
1
- require 'rake'
2
- require 'rake/clean'
3
- require 'rake/testtask'
4
-
5
- desc "Install pathname2 library (non-gem)"
6
- task :install do
7
- cp 'lib/pathname2.rb', Config::CONFIG['sitelibdir']
8
- end
9
-
10
- desc "Install the pathname2 libarary as a gem"
11
- task :install_gem do
12
- ruby 'pathname2.gemspec'
13
- file = Dir["*.gem"].first
14
- sh "gem install #{file}"
15
- end
16
-
17
- desc "Run the test suite for the pure Ruby version"
18
- Rake::TestTask.new('test') do |t|
19
- t.warning = true
20
- t.verbose = true
21
-
22
- if Config::CONFIG['host_os'] =~ /mswin/i
23
- t.test_files = FileList['test/test_pathname_windows.rb']
24
- else
25
- t.test_files = FileList['test/test_pathname.rb']
26
- end
27
- end
28
-
29
- desc "Run the benchmark suite"
30
- task :benchmark do
31
- sh 'ruby -Ilib examples/bench_pathname.rb'
32
- end