~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to lib/pathname.rb

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2010-07-31 17:08:39 UTC
  • mfrom: (1.1.4 upstream) (8.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20100731170839-j034dmpdqt1cc4p6
Tags: 1.9.2~svn28788-1
* New release based on upstream snapshot from the 1.9.2 branch,
  after 1.9.2 RC2. That branch is (supposed to be) binary-compatible
  with the 1.9.1 branch.
  + Builds fine on i386. Closes: #580852.
* Upgrade to Standards-Version: 3.9.1. No changes needed.
* Updated generated incs.
* Patches that still need work:
  + Unclear status, need more investigation:
   090729_fix_Makefile_deps.dpatch
   090803_exclude_rdoc.dpatch
   203_adjust_base_of_search_path.dpatch
   902_define_YAML_in_yaml_stringio.rb.dpatch
   919_common.mk_tweaks.dpatch
   931_libruby_suffix.dpatch
   940_test_thread_mutex_sync_shorter.dpatch
  + Maybe not needed anymore, keeping but not applying.
   102_skip_test_copy_stream.dpatch (test doesn't block anymore?)
   104_skip_btest_io.dpatch (test doesn't block anymore?)
   201_gem_prelude.dpatch (we don't use that rubygems anyway?)
   202_gem_default_dir.dpatch (we don't use that rubygems anyway?)
   940_test_file_exhaustive_fails_as_root.dpatch
   940_test_priority_fails.dpatch
   100518_load_libc_libm.dpatch
* Add disable-tests.diff: disable some tests that cause failures on FreeBSD.
  Closes: #590002, #543805, #542927.
* However, many new failures on FreeBSD. Since that version is still an
  improvement, add the check that makes test suite failures non-fatal on
  FreeBSD again. That still needs to be investigated.
* Re-add 903_skip_base_ruby_check.dpatch
* Add build-dependency on ruby1.8 and drop all pre-generated files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
# === Example 1: Using Pathname
37
37
#
38
38
#   require 'pathname'
39
 
#   p = Pathname.new("/usr/bin/ruby")
40
 
#   size = p.size              # 27662
41
 
#   isdir = p.directory?       # false
42
 
#   dir  = p.dirname           # Pathname:/usr/bin
43
 
#   base = p.basename          # Pathname:ruby
44
 
#   dir, base = p.split        # [Pathname:/usr/bin, Pathname:ruby]
45
 
#   data = p.read
46
 
#   p.open { |f| _ }
47
 
#   p.each_line { |line| _ }
 
39
#   pn = Pathname.new("/usr/bin/ruby")
 
40
#   size = pn.size              # 27662
 
41
#   isdir = pn.directory?       # false
 
42
#   dir  = pn.dirname           # Pathname:/usr/bin
 
43
#   base = pn.basename          # Pathname:ruby
 
44
#   dir, base = pn.split        # [Pathname:/usr/bin, Pathname:ruby]
 
45
#   data = pn.read
 
46
#   pn.open { |f| _ }
 
47
#   pn.each_line { |line| _ }
48
48
#
49
49
# === Example 2: Using standard Ruby
50
50
#
51
 
#   p = "/usr/bin/ruby"
52
 
#   size = File.size(p)        # 27662
53
 
#   isdir = File.directory?(p) # false
54
 
#   dir  = File.dirname(p)     # "/usr/bin"
55
 
#   base = File.basename(p)    # "ruby"
56
 
#   dir, base = File.split(p)  # ["/usr/bin", "ruby"]
57
 
#   data = File.read(p)
58
 
#   File.open(p) { |f| _ }
59
 
#   File.foreach(p) { |line| _ }
 
51
#   pn = "/usr/bin/ruby"
 
52
#   size = File.size(pn)        # 27662
 
53
#   isdir = File.directory?(pn) # false
 
54
#   dir  = File.dirname(pn)     # "/usr/bin"
 
55
#   base = File.basename(pn)    # "ruby"
 
56
#   dir, base = File.split(pn)  # ["/usr/bin", "ruby"]
 
57
#   data = File.read(pn)
 
58
#   File.open(pn) { |f| _ }
 
59
#   File.foreach(pn) { |line| _ }
60
60
#
61
61
# === Example 3: Special features
62
62
#
76
76
#
77
77
# === Core methods
78
78
#
79
 
# These methods are effectively manipulating a String, because that's all a path
80
 
# is.  Except for #mountpoint?, #children, and #realpath, they don't access the
81
 
# filesystem.
 
79
# These methods are effectively manipulating a String, because that's
 
80
# all a path is.  Except for #mountpoint?, #children, #each_child,
 
81
# #realdirpath and #realpath, they don't access the filesystem.
82
82
#
83
83
# - +
84
84
# - #join
90
90
# - #each_filename
91
91
# - #cleanpath
92
92
# - #realpath
 
93
# - #realdirpath
93
94
# - #children
 
95
# - #each_child
94
96
# - #mountpoint?
95
97
#
96
98
# === File status predicate methods
165
167
# These methods are a facade for IO:
166
168
# - #each_line(*args, &block)
167
169
# - #read(*args)
 
170
# - #binread(*args)
168
171
# - #readlines(*args)
169
172
# - #sysopen(*args)
170
173
#
295
298
  # chop_basename(path) -> [pre-basename, basename] or nil
296
299
  def chop_basename(path)
297
300
    base = File.basename(path)
298
 
    if /\A#{SEPARATOR_PAT}?\z/ =~ base
 
301
    if /\A#{SEPARATOR_PAT}?\z/o =~ base
299
302
      return nil
300
303
    else
301
304
      return path[0, path.rindex(base)], base
317
320
  def prepend_prefix(prefix, relpath)
318
321
    if relpath.empty?
319
322
      File.dirname(prefix)
320
 
    elsif /#{SEPARATOR_PAT}/ =~ prefix
 
323
    elsif /#{SEPARATOR_PAT}/o =~ prefix
321
324
      prefix = File.dirname(prefix)
322
325
      prefix = File.join(prefix, "") if File.basename(prefix + 'a') != 'a'
323
326
      prefix + relpath
432
435
  end
433
436
  private :cleanpath_conservative
434
437
 
435
 
  def realpath_rec(prefix, unresolved, h)
436
 
    resolved = []
437
 
    until unresolved.empty?
438
 
      n = unresolved.shift
439
 
      if n == '.'
440
 
        next
441
 
      elsif n == '..'
442
 
        resolved.pop
443
 
      else
444
 
        path = prepend_prefix(prefix, File.join(*(resolved + [n])))
445
 
        if h.include? path
446
 
          if h[path] == :resolving
447
 
            raise Errno::ELOOP.new(path)
448
 
          else
449
 
            prefix, *resolved = h[path]
450
 
          end
451
 
        else
452
 
          s = File.lstat(path)
453
 
          if s.symlink?
454
 
            h[path] = :resolving
455
 
            link_prefix, link_names = split_names(File.readlink(path))
456
 
            if link_prefix == ''
457
 
              prefix, *resolved = h[path] = realpath_rec(prefix, resolved + link_names, h)
458
 
            else
459
 
              prefix, *resolved = h[path] = realpath_rec(link_prefix, link_names, h)
460
 
            end
461
 
          else
462
 
            resolved << n
463
 
            h[path] = [prefix, *resolved]
464
 
          end
465
 
        end
466
 
      end
467
 
    end
468
 
    return prefix, *resolved
 
438
  #
 
439
  # Returns the real (absolute) pathname of +self+ in the actual
 
440
  # filesystem not containing symlinks or useless dots.
 
441
  #
 
442
  # All components of the pathname must exist when this method is
 
443
  # called.
 
444
  #
 
445
  def realpath(basedir=nil)
 
446
    self.class.new(File.realpath(@path, basedir))
469
447
  end
470
 
  private :realpath_rec
471
448
 
472
449
  #
473
 
  # Returns a real (absolute) pathname of +self+ in the actual filesystem.
 
450
  # Returns the real (absolute) pathname of +self+ in the actual filesystem.
474
451
  # The real pathname doesn't contain symlinks or useless dots.
475
452
  #
476
 
  # No arguments should be given; the old behaviour is *obsoleted*.
 
453
  # The last component of the real pathname can be nonexistent.
477
454
  #
478
 
  def realpath
479
 
    path = @path
480
 
    prefix, names = split_names(path)
481
 
    if prefix == ''
482
 
      prefix, names2 = split_names(Dir.pwd)
483
 
      names = names2 + names
484
 
    end
485
 
    prefix, *names = realpath_rec(prefix, names, {})
486
 
    self.class.new(prepend_prefix(prefix, File.join(*names)))
 
455
  def realdirpath(basedir=nil)
 
456
    self.class.new(File.realdirpath(@path, basedir))
487
457
  end
488
458
 
489
459
  # #parent returns the parent directory.
685
655
  # filename only.
686
656
  #
687
657
  # For example:
688
 
  #   p = Pathname("/usr/lib/ruby/1.8")
689
 
  #   p.children
 
658
  #   pn = Pathname("/usr/lib/ruby/1.8")
 
659
  #   pn.children
690
660
  #       # -> [ Pathname:/usr/lib/ruby/1.8/English.rb,
691
661
  #              Pathname:/usr/lib/ruby/1.8/Env.rb,
692
662
  #              Pathname:/usr/lib/ruby/1.8/abbrev.rb, ... ]
693
 
  #   p.children(false)
 
663
  #   pn.children(false)
694
664
  #       # -> [ Pathname:English.rb, Pathname:Env.rb, Pathname:abbrev.rb, ... ]
695
665
  #
696
666
  # Note that the result never contain the entries <tt>.</tt> and <tt>..</tt> in
712
682
    result
713
683
  end
714
684
 
 
685
  # Iterates over the children of the directory
 
686
  # (files and subdirectories, not recursive).
 
687
  # It yields Pathname object for each child.
 
688
  # By default, the yielded pathnames will have enough information to access the files.
 
689
  # If you set +with_directory+ to +false+, then the returned pathnames will contain the filename only.
 
690
  #
 
691
  #   Pathname("/usr/local").each_child {|f| p f }
 
692
  #   #=> #<Pathname:/usr/local/share>
 
693
  #   #   #<Pathname:/usr/local/bin>
 
694
  #   #   #<Pathname:/usr/local/games>
 
695
  #   #   #<Pathname:/usr/local/lib>
 
696
  #   #   #<Pathname:/usr/local/include>
 
697
  #   #   #<Pathname:/usr/local/sbin>
 
698
  #   #   #<Pathname:/usr/local/src>
 
699
  #   #   #<Pathname:/usr/local/man>
 
700
  #
 
701
  #   Pathname("/usr/local").each_child(false) {|f| p f }
 
702
  #   #=> #<Pathname:share>
 
703
  #   #   #<Pathname:bin>
 
704
  #   #   #<Pathname:games>
 
705
  #   #   #<Pathname:lib>
 
706
  #   #   #<Pathname:include>
 
707
  #   #   #<Pathname:sbin>
 
708
  #   #   #<Pathname:src>
 
709
  #   #   #<Pathname:man>
 
710
  #
 
711
  def each_child(with_directory=true, &b)
 
712
    children(with_directory).each(&b)
 
713
  end
 
714
 
715
715
  #
716
716
  # #relative_path_from returns a relative path from the argument to the
717
717
  # receiver.  If +self+ is absolute, the argument must be absolute too.  If
771
771
    IO.foreach(@path, *args, &block)
772
772
  end
773
773
 
774
 
  # Pathname#foreachline is *obsoleted* at 1.8.1.  Use #each_line.
775
 
  def foreachline(*args, &block)
776
 
    warn "Pathname#foreachline is obsoleted.  Use Pathname#each_line."
777
 
    each_line(*args, &block)
778
 
  end
779
 
 
780
 
  # See <tt>IO.read</tt>.  Returns all the bytes from the file, or the first +N+
 
774
  # See <tt>IO.read</tt>.  Returns all data from the file, or the first +N+ bytes
781
775
  # if specified.
782
776
  def read(*args) IO.read(@path, *args) end
783
777
 
 
778
  # See <tt>IO.binread</tt>.  Returns all the bytes from the file, or the first +N+
 
779
  # if specified.
 
780
  def binread(*args) IO.binread(@path, *args) end
 
781
 
784
782
  # See <tt>IO.readlines</tt>.  Returns all the lines from the file.
785
783
  def readlines(*args) IO.readlines(@path, *args) end
786
784
 
867
865
  # See <tt>File.split</tt>.  Returns the #dirname and the #basename in an
868
866
  # Array.
869
867
  def split() File.split(@path).map {|f| self.class.new(f) } end
870
 
 
871
 
  # Pathname#link is confusing and *obsoleted* because the receiver/argument
872
 
  # order is inverted to corresponding system call.
873
 
  def link(old)
874
 
    warn 'Pathname#link is obsoleted.  Use Pathname#make_link.'
875
 
    File.link(old, @path)
876
 
  end
877
 
 
878
 
  # Pathname#symlink is confusing and *obsoleted* because the receiver/argument
879
 
  # order is inverted to corresponding system call.
880
 
  def symlink(old)
881
 
    warn 'Pathname#symlink is obsoleted.  Use Pathname#make_symlink.'
882
 
    File.symlink(old, @path)
883
 
  end
884
868
end
885
869
 
886
870
 
962
946
 
963
947
class Pathname    # * Dir *
964
948
  # See <tt>Dir.glob</tt>.  Returns or yields Pathname objects.
965
 
  def Pathname.glob(*args) # :yield: p
 
949
  def Pathname.glob(*args) # :yield: pathname
966
950
    if block_given?
967
951
      Dir.glob(*args) {|f| yield self.new(f) }
968
952
    else
974
958
  def Pathname.getwd() self.new(Dir.getwd) end
975
959
  class << self; alias pwd getwd end
976
960
 
977
 
  # Pathname#chdir is *obsoleted* at 1.8.1.
978
 
  def chdir(&block)
979
 
    warn "Pathname#chdir is obsoleted.  Use Dir.chdir."
980
 
    Dir.chdir(@path, &block)
981
 
  end
982
 
 
983
 
  # Pathname#chroot is *obsoleted* at 1.8.1.
984
 
  def chroot
985
 
    warn "Pathname#chroot is obsoleted.  Use Dir.chroot."
986
 
    Dir.chroot(@path)
987
 
  end
988
 
 
989
961
  # Return the entries (files and subdirectories) in the directory, each as a
990
962
  # Pathname object.
991
963
  def entries() Dir.entries(@path).map {|f| self.class.new(f) } end
994
966
  # yields a Pathname object for each entry.
995
967
  #
996
968
  # This method has existed since 1.8.1.
997
 
  def each_entry(&block) # :yield: p
 
969
  def each_entry(&block) # :yield: pathname
998
970
    Dir.foreach(@path) {|f| yield self.class.new(f) }
999
971
  end
1000
972
 
1001
 
  # Pathname#dir_foreach is *obsoleted* at 1.8.1.
1002
 
  def dir_foreach(*args, &block)
1003
 
    warn "Pathname#dir_foreach is obsoleted.  Use Pathname#each_entry."
1004
 
    each_entry(*args, &block)
1005
 
  end
1006
 
 
1007
973
  # See <tt>Dir.mkdir</tt>.  Create the referenced directory.
1008
974
  def mkdir(*args) Dir.mkdir(@path, *args) end
1009
975
 
1028
994
  # If +self+ is <tt>.</tt>, yielded pathnames begin with a filename in the
1029
995
  # current directory, not <tt>./</tt>.
1030
996
  #
1031
 
  def find(&block) # :yield: p
 
997
  def find(&block) # :yield: pathname
1032
998
    require 'find'
1033
999
    if @path == '.'
1034
1000
      Find.find(@path) {|f| yield self.class.new(f.sub(%r{\A\./}, '')) }
1070
1036
    end
1071
1037
  end
1072
1038
  alias delete unlink
1073
 
 
1074
 
  # This method is *obsoleted* at 1.8.1.  Use #each_line or #each_entry.
1075
 
  def foreach(*args, &block)
1076
 
    warn "Pathname#foreach is obsoleted.  Use each_line or each_entry."
1077
 
    if FileTest.directory? @path
1078
 
      # For polymorphism between Dir.foreach and IO.foreach,
1079
 
      # Pathname#foreach doesn't yield Pathname object.
1080
 
      Dir.foreach(@path, *args, &block)
1081
 
    else
1082
 
      IO.foreach(@path, *args, &block)
1083
 
    end
1084
 
  end
1085
1039
end
1086
1040
 
1087
1041
class Pathname