/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

  • Committer: Daniel Watkins
  • Date: 2007-11-06 09:33:05 UTC
  • mfrom: (2967 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2993.
  • Revision ID: d.m.watkins@warwick.ac.uk-20071106093305-zfef3c0jbcvunnuz
Merged bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
68
68
# OR with 0 on those platforms
69
69
O_BINARY = getattr(os, 'O_BINARY', 0)
70
70
 
71
 
# On posix, use lstat instead of stat so that we can
72
 
# operate on broken symlinks. On Windows revert to stat.
73
 
lstat = getattr(os, 'lstat', os.stat)
74
71
 
75
72
def make_readonly(filename):
76
73
    """Make a filename read-only."""
77
 
    mod = lstat(filename).st_mode
 
74
    mod = os.lstat(filename).st_mode
78
75
    if not stat.S_ISLNK(mod):
79
76
        mod = mod & 0777555
80
77
        os.chmod(filename, mod)
81
78
 
82
79
 
83
80
def make_writable(filename):
84
 
    mod = lstat(filename).st_mode
 
81
    mod = os.lstat(filename).st_mode
85
82
    if not stat.S_ISLNK(mod):
86
83
        mod = mod | 0200
87
84
        os.chmod(filename, mod)
88
85
 
89
86
 
 
87
def minimum_path_selection(paths):
 
88
    """Return the smallset subset of paths which are outside paths.
 
89
 
 
90
    :param paths: A container (and hence not None) of paths.
 
91
    :return: A set of paths sufficient to include everything in paths via
 
92
        is_inside_any, drawn from the paths parameter.
 
93
    """
 
94
    search_paths = set()
 
95
    paths = set(paths)
 
96
    for path in paths:
 
97
        other_paths = paths.difference([path])
 
98
        if not is_inside_any(other_paths, path):
 
99
            # this is a top level path, we must check it.
 
100
            search_paths.add(path)
 
101
    return search_paths
 
102
 
 
103
 
90
104
_QUOTE_RE = None
91
105
 
92
106
 
537
551
 
538
552
 
539
553
def pumpfile(fromfile, tofile):
540
 
    """Copy contents of one file to another."""
 
554
    """Copy contents of one file to another.
 
555
    
 
556
    :return: The number of bytes copied.
 
557
    """
541
558
    BUFSIZE = 32768
 
559
    length = 0
542
560
    while True:
543
561
        b = fromfile.read(BUFSIZE)
544
562
        if not b:
545
563
            break
546
564
        tofile.write(b)
 
565
        length += len(b)
 
566
    return length
547
567
 
548
568
 
549
569
def file_iterator(input_file, readsize=32768):
567
587
    return s.hexdigest()
568
588
 
569
589
 
570
 
 
571
 
def sha_strings(strings):
 
590
def sha_file_by_name(fname):
 
591
    """Calculate the SHA1 of a file by reading the full text"""
 
592
    s = sha.new()
 
593
    f = os.open(fname, os.O_RDONLY | O_BINARY)
 
594
    try:
 
595
        while True:
 
596
            b = os.read(f, 1<<16)
 
597
            if not b:
 
598
                return s.hexdigest()
 
599
            s.update(b)
 
600
    finally:
 
601
        os.close(f)
 
602
 
 
603
 
 
604
def sha_strings(strings, _factory=sha.new):
572
605
    """Return the sha-1 of concatenation of strings"""
573
 
    s = sha.new()
 
606
    s = _factory()
574
607
    map(s.update, strings)
575
608
    return s.hexdigest()
576
609
 
577
610
 
578
 
def sha_string(f):
579
 
    s = sha.new()
580
 
    s.update(f)
581
 
    return s.hexdigest()
 
611
def sha_string(f, _factory=sha.new):
 
612
    return _factory(f).hexdigest()
582
613
 
583
614
 
584
615
def fingerprint_file(f):
585
 
    s = sha.new()
586
616
    b = f.read()
587
 
    s.update(b)
588
 
    size = len(b)
589
 
    return {'size': size,
590
 
            'sha1': s.hexdigest()}
 
617
    return {'size': len(b),
 
618
            'sha1': sha.new(b).hexdigest()}
591
619
 
592
620
 
593
621
def compare_files(a, b):
792
820
            raise
793
821
        shutil.copyfile(src, dest)
794
822
 
795
 
def delete_any(full_path):
 
823
 
 
824
# Look Before You Leap (LBYL) is appropriate here instead of Easier to Ask for
 
825
# Forgiveness than Permission (EAFP) because:
 
826
# - root can damage a solaris file system by using unlink,
 
827
# - unlink raises different exceptions on different OSes (linux: EISDIR, win32:
 
828
#   EACCES, OSX: EPERM) when invoked on a directory.
 
829
def delete_any(path):
796
830
    """Delete a file or directory."""
797
 
    try:
798
 
        os.unlink(full_path)
799
 
    except OSError, e:
800
 
    # We may be renaming a dangling inventory id
801
 
        if e.errno not in (errno.EISDIR, errno.EACCES, errno.EPERM):
802
 
            raise
803
 
        os.rmdir(full_path)
 
831
    if isdir(path): # Takes care of symlinks
 
832
        os.rmdir(path)
 
833
    else:
 
834
        os.unlink(path)
804
835
 
805
836
 
806
837
def has_symlinks():
808
839
        return True
809
840
    else:
810
841
        return False
811
 
        
 
842
 
812
843
 
813
844
def contains_whitespace(s):
814
845
    """True if there are any whitespace characters in s."""