~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

  • Committer: Robert Collins
  • Date: 2005-09-27 07:24:40 UTC
  • mfrom: (1185.1.41)
  • Revision ID: robertc@robertcollins.net-20050927072440-1bf4d99c3e1db5b3
pair programming worx... merge integration and weave

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Bazaar-NG -- distributed version control
2
 
 
 
2
#
3
3
# Copyright (C) 2005 by 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
7
7
# the Free Software Foundation; either version 2 of the License, or
8
8
# (at your option) any later version.
9
 
 
 
9
#
10
10
# This program is distributed in the hope that it will be useful,
11
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
13
# GNU General Public License for more details.
14
 
 
 
14
#
15
15
# You should have received a copy of the GNU General Public License
16
16
# along with this program; if not, write to the Free Software
17
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
18
 
19
 
import os, types, re, time, errno, sys
 
19
from stat import (S_ISREG, S_ISDIR, S_ISLNK, ST_MODE, ST_SIZE,
 
20
                  S_ISCHR, S_ISBLK, S_ISFIFO, S_ISSOCK)
 
21
from cStringIO import StringIO
 
22
import errno
 
23
import os
 
24
import re
20
25
import sha
21
 
from cStringIO import StringIO
22
 
 
23
 
from stat import S_ISREG, S_ISDIR, S_ISLNK, ST_MODE, ST_SIZE
24
 
 
 
26
import sys
 
27
import time
 
28
import types
 
29
 
 
30
import bzrlib
25
31
from bzrlib.errors import BzrError
26
32
from bzrlib.trace import mutter
27
 
import bzrlib
 
33
 
28
34
 
29
35
def make_readonly(filename):
30
36
    """Make a filename read-only."""
31
 
    # TODO: probably needs to be fixed for windows
32
37
    mod = os.stat(filename).st_mode
33
38
    mod = mod & 0777555
34
39
    os.chmod(filename, mod)
51
56
    # TODO: I'm not really sure this is the best format either.x
52
57
    global _QUOTE_RE
53
58
    if _QUOTE_RE == None:
54
 
        _QUOTE_RE = re.compile(r'([^a-zA-Z0-9.,:/_~-])')
 
59
        _QUOTE_RE = re.compile(r'([^a-zA-Z0-9.,:/\\_~-])')
55
60
        
56
61
    if _QUOTE_RE.search(f):
57
62
        return '"' + f + '"'
67
72
        return 'directory'
68
73
    elif S_ISLNK(mode):
69
74
        return 'symlink'
 
75
    elif S_ISCHR(mode):
 
76
        return 'chardev'
 
77
    elif S_ISBLK(mode):
 
78
        return 'block'
 
79
    elif S_ISFIFO(mode):
 
80
        return 'fifo'
 
81
    elif S_ISSOCK(mode):
 
82
        return 'socket'
70
83
    else:
71
 
        raise BzrError("can't handle file kind with mode %o of %r" % (mode, f))
 
84
        return 'unknown'
72
85
 
73
86
 
74
87
def kind_marker(kind):
82
95
        raise BzrError('invalid file kind %r' % kind)
83
96
 
84
97
 
85
 
 
86
98
def backup_file(fn):
87
99
    """Copy a file to a backup.
88
100
 
106
118
    finally:
107
119
        outf.close()
108
120
 
109
 
def rename(path_from, path_to):
110
 
    """Basically the same as os.rename() just special for win32"""
111
 
    if sys.platform == 'win32':
112
 
        try:
113
 
            os.remove(path_to)
114
 
        except OSError, e:
115
 
            if e.errno != e.ENOENT:
116
 
                raise
117
 
    os.rename(path_from, path_to)
118
 
 
119
 
 
120
 
 
 
121
if os.name == 'nt':
 
122
    import shutil
 
123
    rename = shutil.move
 
124
else:
 
125
    rename = os.rename
121
126
 
122
127
 
123
128
def isdir(f):
128
133
        return False
129
134
 
130
135
 
131
 
 
132
136
def isfile(f):
133
137
    """True if f is a regular file."""
134
138
    try:
147
151
    The empty string as a dir name is taken as top-of-tree and matches 
148
152
    everything.
149
153
    
150
 
    >>> is_inside('src', 'src/foo.c')
 
154
    >>> is_inside('src', os.path.join('src', 'foo.c'))
151
155
    True
152
156
    >>> is_inside('src', 'srccontrol')
153
157
    False
154
 
    >>> is_inside('src', 'src/a/a/a/foo.c')
 
158
    >>> is_inside('src', os.path.join('src', 'a', 'a', 'a', 'foo.c'))
155
159
    True
156
160
    >>> is_inside('foo.c', 'foo.c')
157
161
    True
167
171
    
168
172
    if dir == '':
169
173
        return True
170
 
    
 
174
 
171
175
    if dir[-1] != os.sep:
172
176
        dir += os.sep
173
 
    
 
177
 
174
178
    return fname.startswith(dir)
175
179
 
176
180
 
188
192
    tofile.write(fromfile.read())
189
193
 
190
194
 
191
 
def uuid():
192
 
    """Return a new UUID"""
193
 
    try:
194
 
        return file('/proc/sys/kernel/random/uuid').readline().rstrip('\n')
195
 
    except IOError:
196
 
        return chomp(os.popen('uuidgen').readline())
197
 
 
198
 
 
199
195
def sha_file(f):
200
196
    if hasattr(f, 'tell'):
201
197
        assert f.tell() == 0
223
219
    return s.hexdigest()
224
220
 
225
221
 
226
 
 
227
222
def fingerprint_file(f):
228
223
    s = sha.new()
229
224
    b = f.read()
240
235
    
241
236
    TODO: Global option --config-dir to override this.
242
237
    """
243
 
    return os.path.expanduser("~/.bzr.conf")
 
238
    return os.path.join(os.path.expanduser("~"), ".bzr.conf")
244
239
 
245
240
 
246
241
def _auto_user_id():
350
345
    if e:
351
346
        m = re.search(r'[\w+.-]+@[\w+.-]+', e)
352
347
        if not m:
353
 
            raise BzrError("%r doesn't seem to contain a reasonable email address" % e)
 
348
            raise BzrError("%r doesn't seem to contain "
 
349
                           "a reasonable email address" % e)
354
350
        return m.group(0)
355
351
 
356
352
    return _auto_user_id()[1]
357
 
    
358
353
 
359
354
 
360
355
def compare_files(a, b):
369
364
            return True
370
365
 
371
366
 
372
 
 
373
367
def local_time_offset(t=None):
374
368
    """Return offset of local zone from GMT, either at present or at time t."""
375
369
    # python2.3 localtime() can't take None
414
408
    """Return size of given open file."""
415
409
    return os.fstat(f.fileno())[ST_SIZE]
416
410
 
417
 
 
418
 
if hasattr(os, 'urandom'): # python 2.4 and later
 
411
# Define rand_bytes based on platform.
 
412
try:
 
413
    # Python 2.4 and later have os.urandom,
 
414
    # but it doesn't work on some arches
 
415
    os.urandom(1)
419
416
    rand_bytes = os.urandom
420
 
elif sys.platform == 'linux2':
421
 
    rand_bytes = file('/dev/urandom', 'rb').read
422
 
else:
423
 
    # not well seeded, but better than nothing
424
 
    def rand_bytes(n):
425
 
        import random
426
 
        s = ''
427
 
        while n:
428
 
            s += chr(random.randint(0, 255))
429
 
            n -= 1
430
 
        return s
431
 
 
 
417
except (NotImplementedError, AttributeError):
 
418
    # If python doesn't have os.urandom, or it doesn't work,
 
419
    # then try to first pull random data from /dev/urandom
 
420
    if os.path.exists("/dev/urandom"):
 
421
        rand_bytes = file('/dev/urandom', 'rb').read
 
422
    # Otherwise, use this hack as a last resort
 
423
    else:
 
424
        # not well seeded, but better than nothing
 
425
        def rand_bytes(n):
 
426
            import random
 
427
            s = ''
 
428
            while n:
 
429
                s += chr(random.randint(0, 255))
 
430
                n -= 1
 
431
            return s
432
432
 
433
433
## TODO: We could later have path objects that remember their list
434
434
## decomposition (might be too tricksy though.)
499
499
        raise
500
500
 
501
501
 
502
 
 
503
502
def split_lines(s):
504
503
    """Split s into lines, but without removing the newline characters."""
505
504
    return StringIO(s).readlines()
506