1
1
# Bazaar-NG -- distributed version control
3
3
# Copyright (C) 2005 by Canonical Ltd
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.
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.
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
19
import os, types, re, time, errno, sys
19
from shutil import copyfile
20
20
from stat import (S_ISREG, S_ISDIR, S_ISLNK, ST_MODE, ST_SIZE,
21
S_ISCHR, S_ISBLK, S_ISFIFO, S_ISSOCK)
21
S_ISCHR, S_ISBLK, S_ISFIFO, S_ISSOCK)
22
from cStringIO import StringIO
23
32
from bzrlib.errors import BzrError
24
33
from bzrlib.trace import mutter
27
36
def make_readonly(filename):
28
37
"""Make a filename read-only."""
29
# TODO: probably needs to be fixed for windows
30
38
mod = os.stat(filename).st_mode
31
39
mod = mod & 0777555
32
40
os.chmod(filename, mod)
88
96
raise BzrError('invalid file kind %r' % kind)
100
if hasattr(os, 'lstat'):
106
if e.errno == errno.ENOENT:
109
raise BzrError("lstat/stat of (%r): %r" % (f, e))
111
def normalizepath(f):
112
if hasattr(os.path, 'realpath'):
116
[p,e] = os.path.split(f)
117
if e == "" or e == "." or e == "..":
120
return os.path.join(F(p), e)
92
123
def backup_file(fn):
93
124
"""Copy a file to a backup.
116
def rename(path_from, path_to):
117
"""Basically the same as os.rename() just special for win32"""
118
if sys.platform == 'win32':
122
if e.errno != e.ENOENT:
124
os.rename(path_from, path_to)
169
"""True if f is a symlink."""
171
return S_ISLNK(os.lstat(f)[ST_MODE])
147
175
def is_inside(dir, fname):
148
176
"""True if fname is inside dir.
154
182
The empty string as a dir name is taken as top-of-tree and matches
157
>>> is_inside('src', 'src/foo.c')
185
>>> is_inside('src', os.path.join('src', 'foo.c'))
159
187
>>> is_inside('src', 'srccontrol')
161
>>> is_inside('src', 'src/a/a/a/foo.c')
189
>>> is_inside('src', os.path.join('src', 'a', 'a', 'a', 'foo.c'))
163
191
>>> is_inside('foo.c', 'foo.c')
353
377
m = re.search(r'[\w+.-]+@[\w+.-]+', e)
355
raise BzrError("%r doesn't seem to contain a reasonable email address" % e)
379
raise BzrError("%r doesn't seem to contain "
380
"a reasonable email address" % e)
356
381
return m.group(0)
358
383
return _auto_user_id()[1]
362
386
def compare_files(a, b):
488
511
return os.path.join(p1, p2)
491
def extern_command(cmd, ignore_errors = False):
492
mutter('external command: %s' % `cmd`)
494
if not ignore_errors:
495
raise BzrError('command failed')
498
514
def _read_config_value(name):
499
515
"""Read a config value from the file ~/.bzr.conf/<name>
500
516
Return None if the file does not exist"""
527
"""Split s into lines, but without removing the newline characters."""
528
return StringIO(s).readlines()
531
def hardlinks_good():
532
return sys.platform not in ('win32', 'cygwin', 'darwin')
535
def link_or_copy(src, dest):
536
"""Hardlink a file, or copy it if it can't be hardlinked."""
537
if not hardlinks_good():
542
except (OSError, IOError), e:
543
if e.errno != errno.EXDEV:
549
if hasattr(os, 'symlink'):