/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

Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Bazaar -- distributed version control
2
2
#
3
 
# Copyright (C) 2005 by Canonical Ltd
 
3
# Copyright (C) 2005 Canonical Ltd
4
4
#
5
5
# This program is free software; you can redistribute it and/or modify
6
6
# it under the terms of the GNU General Public License as published by
17
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
18
 
19
19
from cStringIO import StringIO
 
20
import os
 
21
import re
 
22
import stat
 
23
from stat import (S_ISREG, S_ISDIR, S_ISLNK, ST_MODE, ST_SIZE,
 
24
                  S_ISCHR, S_ISBLK, S_ISFIFO, S_ISSOCK)
 
25
import sys
 
26
import time
 
27
 
 
28
from bzrlib.lazy_import import lazy_import
 
29
lazy_import(globals(), """
20
30
import errno
21
31
from ntpath import (abspath as _nt_abspath,
22
32
                    join as _nt_join,
24
34
                    realpath as _nt_realpath,
25
35
                    splitdrive as _nt_splitdrive,
26
36
                    )
27
 
import os
28
 
from os import listdir
29
37
import posixpath
30
 
import re
31
38
import sha
32
39
import shutil
33
 
from shutil import copyfile
34
 
import stat
35
 
from stat import (S_ISREG, S_ISDIR, S_ISLNK, ST_MODE, ST_SIZE,
36
 
                  S_ISCHR, S_ISBLK, S_ISFIFO, S_ISSOCK)
 
40
from shutil import (
 
41
    rmtree,
 
42
    )
37
43
import string
38
 
import sys
39
 
import time
40
 
import types
41
44
import tempfile
 
45
from tempfile import (
 
46
    mkdtemp,
 
47
    )
42
48
import unicodedata
43
49
 
 
50
from bzrlib import (
 
51
    errors,
 
52
    )
 
53
""")
 
54
 
44
55
import bzrlib
45
 
from bzrlib.errors import (BzrError,
46
 
                           BzrBadParameterNotUnicode,
47
 
                           NoSuchFile,
48
 
                           PathNotChild,
49
 
                           IllegalPath,
50
 
                           )
51
 
from bzrlib.symbol_versioning import (deprecated_function, 
52
 
        zero_nine)
 
56
from bzrlib.symbol_versioning import (
 
57
    deprecated_function,
 
58
    zero_nine,
 
59
    )
53
60
from bzrlib.trace import mutter
54
61
 
55
62
 
122
129
        return _mapper(_lstat(f).st_mode)
123
130
    except OSError, e:
124
131
        if getattr(e, 'errno', None) == errno.ENOENT:
125
 
            raise bzrlib.errors.NoSuchFile(f)
 
132
            raise errors.NoSuchFile(f)
126
133
        raise
127
134
 
128
135
 
144
151
    elif kind == 'symlink':
145
152
        return '@'
146
153
    else:
147
 
        raise BzrError('invalid file kind %r' % kind)
 
154
        raise errors.BzrError('invalid file kind %r' % kind)
148
155
 
149
156
lexists = getattr(os.path, 'lexists', None)
150
157
if lexists is None:
159
166
            if e.errno == errno.ENOENT:
160
167
                return False;
161
168
            else:
162
 
                raise BzrError("lstat/stat of (%r): %r" % (f, e))
 
169
                raise errors.BzrError("lstat/stat of (%r): %r" % (f, e))
163
170
 
164
171
 
165
172
def fancy_rename(old, new, rename_func, unlink_func):
186
193
    file_existed = False
187
194
    try:
188
195
        rename_func(new, tmp_name)
189
 
    except (NoSuchFile,), e:
 
196
    except (errors.NoSuchFile,), e:
190
197
        pass
191
198
    except IOError, e:
192
199
        # RBC 20060103 abstraction leakage: the paramiko SFTP clients rename
302
309
pathjoin = os.path.join
303
310
normpath = os.path.normpath
304
311
getcwd = os.getcwdu
305
 
mkdtemp = tempfile.mkdtemp
306
312
rename = os.rename
307
313
dirname = os.path.dirname
308
314
basename = os.path.basename
309
 
rmtree = shutil.rmtree
 
315
# These were already imported into local scope
 
316
# mkdtemp = tempfile.mkdtemp
 
317
# rmtree = shutil.rmtree
310
318
 
311
319
MIN_ABS_PATHLENGTH = 1
312
320
 
330
338
        if function in (os.remove, os.rmdir) \
331
339
            and type_ == OSError \
332
340
            and value.errno == errno.EACCES:
333
 
            bzrlib.osutils.make_writable(path)
 
341
            make_writable(path)
334
342
            function(path)
335
343
        else:
336
344
            raise
440
448
    
441
449
    The empty string as a dir name is taken as top-of-tree and matches 
442
450
    everything.
443
 
    
444
 
    >>> is_inside('src', pathjoin('src', 'foo.c'))
445
 
    True
446
 
    >>> is_inside('src', 'srccontrol')
447
 
    False
448
 
    >>> is_inside('src', pathjoin('src', 'a', 'a', 'a', 'foo.c'))
449
 
    True
450
 
    >>> is_inside('foo.c', 'foo.c')
451
 
    True
452
 
    >>> is_inside('foo.c', '')
453
 
    False
454
 
    >>> is_inside('', 'foo.c')
455
 
    True
456
451
    """
457
452
    # XXX: Most callers of this can actually do something smarter by 
458
453
    # looking at the inventory
581
576
        tt = time.localtime(t)
582
577
        offset = local_time_offset(t)
583
578
    else:
584
 
        raise BzrError("unsupported timezone format %r" % timezone,
585
 
                       ['options are "utc", "original", "local"'])
 
579
        raise errors.BzrError("unsupported timezone format %r" % timezone,
 
580
                              ['options are "utc", "original", "local"'])
586
581
    if date_fmt is None:
587
582
        date_fmt = "%a %Y-%m-%d %H:%M:%S"
588
583
    if show_offset:
596
591
    return time.strftime('%Y%m%d%H%M%S', time.gmtime(when))
597
592
    
598
593
 
 
594
def format_delta(delta):
 
595
    """Get a nice looking string for a time delta.
 
596
 
 
597
    :param delta: The time difference in seconds, can be positive or negative.
 
598
        positive indicates time in the past, negative indicates time in the
 
599
        future. (usually time.time() - stored_time)
 
600
    :return: String formatted to show approximate resolution
 
601
    """
 
602
    delta = int(delta)
 
603
    if delta >= 0:
 
604
        direction = 'ago'
 
605
    else:
 
606
        direction = 'in the future'
 
607
        delta = -delta
 
608
 
 
609
    seconds = delta
 
610
    if seconds < 90: # print seconds up to 90 seconds
 
611
        if seconds == 1:
 
612
            return '%d second %s' % (seconds, direction,)
 
613
        else:
 
614
            return '%d seconds %s' % (seconds, direction)
 
615
 
 
616
    minutes = int(seconds / 60)
 
617
    seconds -= 60 * minutes
 
618
    if seconds == 1:
 
619
        plural_seconds = ''
 
620
    else:
 
621
        plural_seconds = 's'
 
622
    if minutes < 90: # print minutes, seconds up to 90 minutes
 
623
        if minutes == 1:
 
624
            return '%d minute, %d second%s %s' % (
 
625
                    minutes, seconds, plural_seconds, direction)
 
626
        else:
 
627
            return '%d minutes, %d second%s %s' % (
 
628
                    minutes, seconds, plural_seconds, direction)
 
629
 
 
630
    hours = int(minutes / 60)
 
631
    minutes -= 60 * hours
 
632
    if minutes == 1:
 
633
        plural_minutes = ''
 
634
    else:
 
635
        plural_minutes = 's'
 
636
 
 
637
    if hours == 1:
 
638
        return '%d hour, %d minute%s %s' % (hours, minutes,
 
639
                                            plural_minutes, direction)
 
640
    return '%d hours, %d minute%s %s' % (hours, minutes,
 
641
                                         plural_minutes, direction)
599
642
 
600
643
def filesize(f):
601
644
    """Return size of given open file."""
611
654
except (NotImplementedError, AttributeError):
612
655
    # If python doesn't have os.urandom, or it doesn't work,
613
656
    # then try to first pull random data from /dev/urandom
614
 
    if os.path.exists("/dev/urandom"):
 
657
    try:
615
658
        rand_bytes = file('/dev/urandom', 'rb').read
616
659
    # Otherwise, use this hack as a last resort
617
 
    else:
 
660
    except (IOError, OSError):
618
661
        # not well seeded, but better than nothing
619
662
        def rand_bytes(n):
620
663
            import random
642
685
## decomposition (might be too tricksy though.)
643
686
 
644
687
def splitpath(p):
645
 
    """Turn string into list of parts.
646
 
 
647
 
    >>> splitpath('a')
648
 
    ['a']
649
 
    >>> splitpath('a/b')
650
 
    ['a', 'b']
651
 
    >>> splitpath('a/./b')
652
 
    ['a', 'b']
653
 
    >>> splitpath('a/.b')
654
 
    ['a', '.b']
655
 
    >>> splitpath('a/../b')
656
 
    Traceback (most recent call last):
657
 
    ...
658
 
    BzrError: sorry, '..' not allowed in path
659
 
    """
660
 
    assert isinstance(p, types.StringTypes)
 
688
    """Turn string into list of parts."""
 
689
    assert isinstance(p, basestring)
661
690
 
662
691
    # split on either delimiter because people might use either on
663
692
    # Windows
666
695
    rps = []
667
696
    for f in ps:
668
697
        if f == '..':
669
 
            raise BzrError("sorry, %r not allowed in path" % f)
 
698
            raise errors.BzrError("sorry, %r not allowed in path" % f)
670
699
        elif (f == '.') or (f == ''):
671
700
            pass
672
701
        else:
677
706
    assert isinstance(p, list)
678
707
    for f in p:
679
708
        if (f == '..') or (f is None) or (f == ''):
680
 
            raise BzrError("sorry, %r not allowed in path" % f)
 
709
            raise errors.BzrError("sorry, %r not allowed in path" % f)
681
710
    return pathjoin(*p)
682
711
 
683
712
 
705
734
def link_or_copy(src, dest):
706
735
    """Hardlink a file, or copy it if it can't be hardlinked."""
707
736
    if not hardlinks_good():
708
 
        copyfile(src, dest)
 
737
        shutil.copyfile(src, dest)
709
738
        return
710
739
    try:
711
740
        os.link(src, dest)
712
741
    except (OSError, IOError), e:
713
742
        if e.errno != errno.EXDEV:
714
743
            raise
715
 
        copyfile(src, dest)
 
744
        shutil.copyfile(src, dest)
716
745
 
717
746
def delete_any(full_path):
718
747
    """Delete a file or directory."""
776
805
        if tail:
777
806
            s.insert(0, tail)
778
807
    else:
779
 
        raise PathNotChild(rp, base)
 
808
        raise errors.PathNotChild(rp, base)
780
809
 
781
810
    if s:
782
811
        return pathjoin(*s)
797
826
    try:
798
827
        return unicode_or_utf8_string.decode('utf8')
799
828
    except UnicodeDecodeError:
800
 
        raise BzrBadParameterNotUnicode(unicode_or_utf8_string)
 
829
        raise errors.BzrBadParameterNotUnicode(unicode_or_utf8_string)
801
830
 
802
831
 
803
832
_platform_normalizes_filenames = False
902
931
    if sys.platform != "win32":
903
932
        return
904
933
    if _validWin32PathRE.match(path) is None:
905
 
        raise IllegalPath(path)
 
934
        raise errors.IllegalPath(path)
906
935
 
907
936
 
908
937
def walkdirs(top, prefix=""):
941
970
    lstat = os.lstat
942
971
    pending = []
943
972
    _directory = _directory_kind
944
 
    _listdir = listdir
 
973
    _listdir = os.listdir
945
974
    pending = [(prefix, "", _directory, None, top)]
946
975
    while pending:
947
976
        dirblock = []