~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

  • Committer: Martin Pool
  • Date: 2005-04-15 01:31:21 UTC
  • Revision ID: mbp@sourcefrog.net-20050415013121-b18f1be12a735066
- Doc cleanups from Magnus Therning

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
import os, types, re, time, errno
20
20
from stat import S_ISREG, S_ISDIR, S_ISLNK, ST_MODE, ST_SIZE
21
21
 
22
22
from errors import bailout, BzrError
56
56
    elif S_ISLNK(mode):
57
57
        return 'symlink'
58
58
    else:
59
 
        raise BzrError("can't handle file kind with mode %o of %r" % (mode, f))
60
 
 
61
 
 
62
 
def kind_marker(kind):
63
 
    if kind == 'file':
64
 
        return ''
65
 
    elif kind == 'directory':
66
 
        return '/'
67
 
    elif kind == 'symlink':
68
 
        return '@'
69
 
    else:
70
 
        raise BzrError('invalid file kind %r' % kind)
 
59
        raise BzrError("can't handle file kind with mode %o of %r" % (mode, f)) 
71
60
 
72
61
 
73
62
 
88
77
        return False
89
78
 
90
79
 
91
 
def is_inside(dir, fname):
92
 
    """True if fname is inside dir.
93
 
    """
94
 
    return os.path.commonprefix([dir, fname]) == dir
95
 
 
96
 
 
97
 
def is_inside_any(dir_list, fname):
98
 
    """True if fname is inside any of given dirs."""
99
 
    # quick scan for perfect match
100
 
    if fname in dir_list:
101
 
        return True
102
 
    
103
 
    for dirname in dir_list:
104
 
        if is_inside(dirname, fname):
105
 
            return True
106
 
    else:
107
 
        return False
108
 
 
109
 
 
110
80
def pumpfile(fromfile, tofile):
111
81
    """Copy contents of one file to another."""
112
82
    tofile.write(fromfile.read())
114
84
 
115
85
def uuid():
116
86
    """Return a new UUID"""
 
87
    
 
88
    ## XXX: Could alternatively read /proc/sys/kernel/random/uuid on
 
89
    ## Linux, but we need something portable for other systems;
 
90
    ## preferably an implementation in Python.
117
91
    try:
118
 
        return file('/proc/sys/kernel/random/uuid').readline().rstrip('\n')
 
92
        return chomp(file('/proc/sys/kernel/random/uuid').readline())
119
93
    except IOError:
120
94
        return chomp(os.popen('uuidgen').readline())
121
95
 
122
96
 
 
97
def chomp(s):
 
98
    if s and (s[-1] == '\n'):
 
99
        return s[:-1]
 
100
    else:
 
101
        return s
 
102
 
 
103
 
123
104
def sha_file(f):
124
105
    import sha
 
106
    ## TODO: Maybe read in chunks to handle big files
125
107
    if hasattr(f, 'tell'):
126
108
        assert f.tell() == 0
127
109
    s = sha.new()
128
 
    BUFSIZE = 128<<10
129
 
    while True:
130
 
        b = f.read(BUFSIZE)
131
 
        if not b:
132
 
            break
133
 
        s.update(b)
 
110
    s.update(f.read())
134
111
    return s.hexdigest()
135
112
 
136
113
 
152
129
            'sha1': s.hexdigest()}
153
130
 
154
131
 
155
 
def config_dir():
156
 
    """Return per-user configuration directory.
157
 
 
158
 
    By default this is ~/.bzr.conf/
159
 
    
160
 
    TODO: Global option --config-dir to override this.
161
 
    """
162
 
    return os.path.expanduser("~/.bzr.conf")
163
 
 
164
 
 
165
132
def _auto_user_id():
166
133
    """Calculate automatic user identification.
167
134
 
188
155
            realname = gecos
189
156
        else:
190
157
            realname = gecos[:comma]
191
 
        if not realname:
192
 
            realname = username
193
158
 
194
159
    except ImportError:
 
160
        realname = ''
195
161
        import getpass
196
 
        realname = username = getpass.getuser().decode(bzrlib.user_encoding)
 
162
        username = getpass.getuser().decode(bzrlib.user_encoding)
197
163
 
198
 
    return realname, (username + '@' + socket.gethostname())
 
164
    return realname, (username + '@' + os.gethostname())
199
165
 
200
166
 
201
167
def _get_user_id():
202
 
    """Return the full user id from a file or environment variable.
203
 
 
204
 
    TODO: Allow taking this from a file in the branch directory too
205
 
    for per-branch ids."""
206
168
    v = os.environ.get('BZREMAIL')
207
169
    if v:
208
170
        return v.decode(bzrlib.user_encoding)
209
171
    
210
172
    try:
211
 
        return (open(os.path.join(config_dir(), "email"))
 
173
        return (open(os.path.expanduser("~/.bzr.email"))
212
174
                .read()
213
175
                .decode(bzrlib.user_encoding)
214
176
                .rstrip("\r\n"))
215
 
    except IOError, e:
216
 
        if e.errno != errno.ENOENT:
 
177
    except OSError, e:
 
178
        if e.errno != ENOENT:
217
179
            raise e
218
180
 
219
181
    v = os.environ.get('EMAIL')
229
191
    Something similar to 'Martin Pool <mbp@sourcefrog.net>'
230
192
 
231
193
    TODO: Check it's reasonably well-formed.
 
194
 
 
195
    TODO: Allow taking it from a dotfile to help people on windows
 
196
           who can't easily set variables.
232
197
    """
233
198
    v = _get_user_id()
234
199
    if v:
257
222
 
258
223
def compare_files(a, b):
259
224
    """Returns true if equal in contents"""
 
225
    # TODO: don't read the whole thing in one go.
260
226
    BUFSIZE = 4096
261
227
    while True:
262
228
        ai = a.read(BUFSIZE)
315
281
 
316
282
if hasattr(os, 'urandom'): # python 2.4 and later
317
283
    rand_bytes = os.urandom
318
 
elif sys.platform == 'linux2':
319
 
    rand_bytes = file('/dev/urandom', 'rb').read
320
284
else:
321
 
    # not well seeded, but better than nothing
322
 
    def rand_bytes(n):
323
 
        import random
324
 
        s = ''
325
 
        while n:
326
 
            s += chr(random.randint(0, 255))
327
 
            n -= 1
328
 
        return s
 
285
    # FIXME: No good on non-Linux
 
286
    _rand_file = file('/dev/urandom', 'rb')
 
287
    rand_bytes = _rand_file.read
329
288
 
330
289
 
331
290
## TODO: We could later have path objects that remember their list
348
307
    BzrError: ("sorry, '..' not allowed in path", [])
349
308
    """
350
309
    assert isinstance(p, types.StringTypes)
351
 
 
352
 
    # split on either delimiter because people might use either on
353
 
    # Windows
354
 
    ps = re.split(r'[\\/]', p)
355
 
 
356
 
    rps = []
 
310
    ps = [f for f in p.split('/') if (f != '.' and f != '')]
357
311
    for f in ps:
358
312
        if f == '..':
359
313
            bailout("sorry, %r not allowed in path" % f)
360
 
        elif (f == '.') or (f == ''):
361
 
            pass
362
 
        else:
363
 
            rps.append(f)
364
 
    return rps
 
314
    return ps
365
315
 
366
316
def joinpath(p):
367
317
    assert isinstance(p, list)
368
318
    for f in p:
369
319
        if (f == '..') or (f == None) or (f == ''):
370
320
            bailout("sorry, %r not allowed in path" % f)
371
 
    return os.path.join(*p)
 
321
    return '/'.join(p)
372
322
 
373
323
 
374
324
def appendpath(p1, p2):
375
325
    if p1 == '':
376
326
        return p2
377
327
    else:
378
 
        return os.path.join(p1, p2)
 
328
        return p1 + '/' + p2
379
329
    
380
330
 
381
331
def extern_command(cmd, ignore_errors = False):