160
58
# TODO: I'm not really sure this is the best format either.x
162
if _QUOTE_RE is None:
163
61
_QUOTE_RE = re.compile(r'([^a-zA-Z0-9.,:/\\_~-])')
165
63
if _QUOTE_RE.search(f):
166
64
return '"' + f + '"'
171
_directory_kind = 'directory'
174
"""Return the current umask"""
175
# Assume that people aren't messing with the umask while running
176
# XXX: This is not thread safe, but there is no way to get the
177
# umask without setting it
185
_directory_kind: "/",
187
'tree-reference': '+',
70
mode = os.lstat(f)[ST_MODE]
191
89
def kind_marker(kind):
193
return _kind_marker_map[kind]
195
# Slightly faster than using .get(, '') when the common case is that
200
lexists = getattr(os.path, 'lexists', None)
204
stat = getattr(os, 'lstat', os.stat)
208
if e.errno == errno.ENOENT:
211
raise errors.BzrError("lstat/stat of (%r): %r" % (f, e))
214
def fancy_rename(old, new, rename_func, unlink_func):
215
"""A fancy rename, when you don't have atomic rename.
217
:param old: The old path, to rename from
218
:param new: The new path, to rename to
219
:param rename_func: The potentially non-atomic rename function
220
:param unlink_func: A way to delete the target file if the full rename
223
# sftp rename doesn't allow overwriting, so play tricks:
224
base = os.path.basename(new)
225
dirname = os.path.dirname(new)
226
# callers use different encodings for the paths so the following MUST
227
# respect that. We rely on python upcasting to unicode if new is unicode
228
# and keeping a str if not.
229
tmp_name = 'tmp.%s.%.9f.%d.%s' % (base, time.time(),
230
os.getpid(), rand_chars(10))
231
tmp_name = pathjoin(dirname, tmp_name)
233
# Rename the file out of the way, but keep track if it didn't exist
234
# We don't want to grab just any exception
235
# something like EACCES should prevent us from continuing
236
# The downside is that the rename_func has to throw an exception
237
# with an errno = ENOENT, or NoSuchFile
240
rename_func(new, tmp_name)
241
except (errors.NoSuchFile,), e:
244
# RBC 20060103 abstraction leakage: the paramiko SFTP clients rename
245
# function raises an IOError with errno is None when a rename fails.
246
# This then gets caught here.
247
if e.errno not in (None, errno.ENOENT, errno.ENOTDIR):
250
if (getattr(e, 'errno', None) is None
251
or e.errno not in (errno.ENOENT, errno.ENOTDIR)):
260
# This may throw an exception, in which case success will
262
rename_func(old, new)
264
except (IOError, OSError), e:
265
# source and target may be aliases of each other (e.g. on a
266
# case-insensitive filesystem), so we may have accidentally renamed
267
# source by when we tried to rename target
268
failure_exc = sys.exc_info()
269
if (file_existed and e.errno in (None, errno.ENOENT)
270
and old.lower() == new.lower()):
271
# source and target are the same file on a case-insensitive
272
# filesystem, so we don't generate an exception
276
# If the file used to exist, rename it back into place
277
# otherwise just delete it from the tmp location
279
unlink_func(tmp_name)
281
rename_func(tmp_name, new)
282
if failure_exc is not None:
284
raise failure_exc[0], failure_exc[1], failure_exc[2]
289
# In Python 2.4.2 and older, os.path.abspath and os.path.realpath
290
# choke on a Unicode string containing a relative path if
291
# os.getcwd() returns a non-sys.getdefaultencoding()-encoded
293
_fs_enc = sys.getfilesystemencoding() or 'utf-8'
294
def _posix_abspath(path):
295
# jam 20060426 rather than encoding to fsencoding
296
# copy posixpath.abspath, but use os.getcwdu instead
297
if not posixpath.isabs(path):
298
path = posixpath.join(getcwd(), path)
299
return _posix_normpath(path)
302
def _posix_realpath(path):
303
return posixpath.realpath(path.encode(_fs_enc)).decode(_fs_enc)
306
def _posix_normpath(path):
307
path = posixpath.normpath(path)
308
# Bug 861008: posixpath.normpath() returns a path normalized according to
309
# the POSIX standard, which stipulates (for compatibility reasons) that two
310
# leading slashes must not be simplified to one, and only if there are 3 or
311
# more should they be simplified as one. So we treat the leading 2 slashes
312
# as a special case here by simply removing the first slash, as we consider
313
# that breaking POSIX compatibility for this obscure feature is acceptable.
314
# This is not a paranoid precaution, as we notably get paths like this when
315
# the repo is hosted at the root of the filesystem, i.e. in "/".
316
if path.startswith('//'):
321
def _win32_fixdrive(path):
322
"""Force drive letters to be consistent.
324
win32 is inconsistent whether it returns lower or upper case
325
and even if it was consistent the user might type the other
326
so we force it to uppercase
327
running python.exe under cmd.exe return capital C:\\
328
running win32 python inside a cygwin shell returns lowercase c:\\
330
drive, path = ntpath.splitdrive(path)
331
return drive.upper() + path
334
def _win32_abspath(path):
335
# Real ntpath.abspath doesn't have a problem with a unicode cwd
336
return _win32_fixdrive(ntpath.abspath(unicode(path)).replace('\\', '/'))
339
def _win98_abspath(path):
340
"""Return the absolute version of a path.
341
Windows 98 safe implementation (python reimplementation
342
of Win32 API function GetFullPathNameW)
347
# \\HOST\path => //HOST/path
348
# //HOST/path => //HOST/path
349
# path => C:/cwd/path
352
# check for absolute path
353
drive = ntpath.splitdrive(path)[0]
354
if drive == '' and path[:2] not in('//','\\\\'):
356
# we cannot simply os.path.join cwd and path
357
# because os.path.join('C:','/path') produce '/path'
358
# and this is incorrect
359
if path[:1] in ('/','\\'):
360
cwd = ntpath.splitdrive(cwd)[0]
362
path = cwd + '\\' + path
363
return _win32_fixdrive(ntpath.normpath(path).replace('\\', '/'))
366
def _win32_realpath(path):
367
# Real ntpath.realpath doesn't have a problem with a unicode cwd
368
return _win32_fixdrive(ntpath.realpath(unicode(path)).replace('\\', '/'))
371
def _win32_pathjoin(*args):
372
return ntpath.join(*args).replace('\\', '/')
375
def _win32_normpath(path):
376
return _win32_fixdrive(ntpath.normpath(unicode(path)).replace('\\', '/'))
380
return _win32_fixdrive(os.getcwdu().replace('\\', '/'))
383
def _win32_mkdtemp(*args, **kwargs):
384
return _win32_fixdrive(tempfile.mkdtemp(*args, **kwargs).replace('\\', '/'))
387
def _win32_rename(old, new):
388
"""We expect to be able to atomically replace 'new' with old.
390
On win32, if new exists, it must be moved out of the way first,
394
fancy_rename(old, new, rename_func=os.rename, unlink_func=os.unlink)
396
if e.errno in (errno.EPERM, errno.EACCES, errno.EBUSY, errno.EINVAL):
397
# If we try to rename a non-existant file onto cwd, we get
398
# EPERM or EACCES instead of ENOENT, this will raise ENOENT
399
# if the old path doesn't exist, sometimes we get EACCES
400
# On Linux, we seem to get EBUSY, on Mac we get EINVAL
406
return unicodedata.normalize('NFC', os.getcwdu())
409
# Default is to just use the python builtins, but these can be rebound on
410
# particular platforms.
411
abspath = _posix_abspath
412
realpath = _posix_realpath
413
pathjoin = os.path.join
414
normpath = _posix_normpath
417
dirname = os.path.dirname
418
basename = os.path.basename
419
split = os.path.split
420
splitext = os.path.splitext
421
# These were already lazily imported into local scope
422
# mkdtemp = tempfile.mkdtemp
423
# rmtree = shutil.rmtree
431
MIN_ABS_PATHLENGTH = 1
434
if sys.platform == 'win32':
435
if win32utils.winver == 'Windows 98':
436
abspath = _win98_abspath
438
abspath = _win32_abspath
439
realpath = _win32_realpath
440
pathjoin = _win32_pathjoin
441
normpath = _win32_normpath
442
getcwd = _win32_getcwd
443
mkdtemp = _win32_mkdtemp
444
rename = _win32_rename
446
from bzrlib import _walkdirs_win32
450
lstat = _walkdirs_win32.lstat
451
fstat = _walkdirs_win32.fstat
452
wrap_stat = _walkdirs_win32.wrap_stat
454
MIN_ABS_PATHLENGTH = 3
456
def _win32_delete_readonly(function, path, excinfo):
457
"""Error handler for shutil.rmtree function [for win32]
458
Helps to remove files and dirs marked as read-only.
460
exception = excinfo[1]
461
if function in (os.remove, os.rmdir) \
462
and isinstance(exception, OSError) \
463
and exception.errno == errno.EACCES:
469
def rmtree(path, ignore_errors=False, onerror=_win32_delete_readonly):
470
"""Replacer for shutil.rmtree: could remove readonly dirs/files"""
471
return shutil.rmtree(path, ignore_errors, onerror)
473
f = win32utils.get_unicode_argv # special function or None
477
elif sys.platform == 'darwin':
481
def get_terminal_encoding(trace=False):
482
"""Find the best encoding for printing to the screen.
484
This attempts to check both sys.stdout and sys.stdin to see
485
what encoding they are in, and if that fails it falls back to
486
osutils.get_user_encoding().
487
The problem is that on Windows, locale.getpreferredencoding()
488
is not the same encoding as that used by the console:
489
http://mail.python.org/pipermail/python-list/2003-May/162357.html
491
On my standard US Windows XP, the preferred encoding is
492
cp1252, but the console is cp437
494
:param trace: If True trace the selected encoding via mutter().
496
from bzrlib.trace import mutter
497
output_encoding = getattr(sys.stdout, 'encoding', None)
498
if not output_encoding:
499
input_encoding = getattr(sys.stdin, 'encoding', None)
500
if not input_encoding:
501
output_encoding = get_user_encoding()
503
mutter('encoding stdout as osutils.get_user_encoding() %r',
506
output_encoding = input_encoding
508
mutter('encoding stdout as sys.stdin encoding %r',
512
mutter('encoding stdout as sys.stdout encoding %r', output_encoding)
513
if output_encoding == 'cp0':
514
# invalid encoding (cp0 means 'no codepage' on Windows)
515
output_encoding = get_user_encoding()
517
mutter('cp0 is invalid encoding.'
518
' encoding stdout as osutils.get_user_encoding() %r',
522
codecs.lookup(output_encoding)
524
sys.stderr.write('bzr: warning:'
525
' unknown terminal encoding %s.\n'
526
' Using encoding %s instead.\n'
527
% (output_encoding, get_user_encoding())
529
output_encoding = get_user_encoding()
531
return output_encoding
92
elif kind == 'directory':
94
elif kind == 'symlink':
97
raise BzrError('invalid file kind %r' % kind)
101
if hasattr(os, 'lstat'):
107
if e.errno == errno.ENOENT:
110
raise BzrError("lstat/stat of (%r): %r" % (f, e))
534
112
def normalizepath(f):
535
if getattr(os.path, 'realpath', None) is not None:
113
if hasattr(os.path, 'realpath'):
539
117
[p,e] = os.path.split(f)
540
118
if e == "" or e == "." or e == "..":
543
return pathjoin(F(p), e)
121
return os.path.join(F(p), e)
123
if os.name == "posix":
124
# In Python 2.4.2 and older, os.path.abspath and os.path.realpath
125
# choke on a Unicode string containing a relative path if
126
# os.getcwd() returns a non-sys.getdefaultencoding()-encoded
128
_fs_enc = sys.getfilesystemencoding()
130
return os.path.abspath(path.encode(_fs_enc)).decode(_fs_enc)
132
return os.path.realpath(path.encode(_fs_enc)).decode(_fs_enc)
134
# We need to use the Unicode-aware os.path.abspath and
135
# os.path.realpath on Windows systems.
136
abspath = os.path.abspath
137
realpath = os.path.realpath
140
"""Copy a file to a backup.
142
Backups are named in GNU-style, with a ~ suffix.
144
If the file is already a backup, it's not copied.
150
if has_symlinks() and os.path.islink(fn):
151
target = os.readlink(fn)
152
os.symlink(target, bfn)
160
outf = file(bfn, 'wb')
547
174
"""True if f is an accessible directory."""
549
return stat.S_ISDIR(os.lstat(f)[stat.ST_MODE])
176
return S_ISDIR(os.lstat(f)[ST_MODE])
1175
467
def relpath(base, path):
1176
"""Return path relative to base, or raise PathNotChild exception.
468
"""Return path relative to base, or raise exception.
1178
470
The path may be either an absolute path or a path relative to the
1179
471
current working directory.
1181
473
os.path.commonprefix (python2.4) has a bad bug that it works just
1182
474
on string prefixes, assuming that '/u' is a prefix of '/u2'. This
1183
avoids that problem.
1185
NOTE: `base` should not have a trailing slash otherwise you'll get
1186
PathNotChild exceptions regardless of `path`.
1189
if len(base) < MIN_ABS_PATHLENGTH:
1190
# must have space for e.g. a drive letter
1191
raise ValueError('%r is too short to calculate a relative path'
475
avoids that problem."""
1194
476
rp = abspath(path)
1199
if len(head) <= len(base) and head != base:
1200
raise errors.PathNotChild(rp, base)
480
while len(head) >= len(base):
1201
481
if head == base:
1203
head, tail = split(head)
483
head, tail = os.path.split(head)
1208
return pathjoin(*reversed(s))
1213
def _cicp_canonical_relpath(base, path):
1214
"""Return the canonical path relative to base.
1216
Like relpath, but on case-insensitive-case-preserving file-systems, this
1217
will return the relpath as stored on the file-system rather than in the
1218
case specified in the input string, for all existing portions of the path.
1220
This will cause O(N) behaviour if called for every path in a tree; if you
1221
have a number of paths to convert, you should use canonical_relpaths().
1223
# TODO: it should be possible to optimize this for Windows by using the
1224
# win32 API FindFiles function to look for the specified name - but using
1225
# os.listdir() still gives us the correct, platform agnostic semantics in
1228
rel = relpath(base, path)
1229
# '.' will have been turned into ''
1233
abs_base = abspath(base)
1235
_listdir = os.listdir
1237
# use an explicit iterator so we can easily consume the rest on early exit.
1238
bit_iter = iter(rel.split('/'))
1239
for bit in bit_iter:
1242
next_entries = _listdir(current)
1243
except OSError: # enoent, eperm, etc
1244
# We can't find this in the filesystem, so just append the
1246
current = pathjoin(current, bit, *list(bit_iter))
1248
for look in next_entries:
1249
if lbit == look.lower():
1250
current = pathjoin(current, look)
1253
# got to the end, nothing matched, so we just return the
1254
# non-existing bits as they were specified (the filename may be
1255
# the target of a move, for example).
1256
current = pathjoin(current, bit, *list(bit_iter))
1258
return current[len(abs_base):].lstrip('/')
1260
# XXX - TODO - we need better detection/integration of case-insensitive
1261
# file-systems; Linux often sees FAT32 devices (or NFS-mounted OSX
1262
# filesystems), for example, so could probably benefit from the same basic
1263
# support there. For now though, only Windows and OSX get that support, and
1264
# they get it for *all* file-systems!
1265
if sys.platform in ('win32', 'darwin'):
1266
canonical_relpath = _cicp_canonical_relpath
1268
canonical_relpath = relpath
1270
def canonical_relpaths(base, paths):
1271
"""Create an iterable to canonicalize a sequence of relative paths.
1273
The intent is for this implementation to use a cache, vastly speeding
1274
up multiple transformations in the same directory.
1276
# but for now, we haven't optimized...
1277
return [canonical_relpath(base, p) for p in paths]
1280
def decode_filename(filename):
1281
"""Decode the filename using the filesystem encoding
1283
If it is unicode, it is returned.
1284
Otherwise it is decoded from the the filesystem's encoding. If decoding
1285
fails, a errors.BadFilenameEncoding exception is raised.
1287
if type(filename) is unicode:
1290
return filename.decode(_fs_enc)
1291
except UnicodeDecodeError:
1292
raise errors.BadFilenameEncoding(filename, _fs_enc)
1295
def safe_unicode(unicode_or_utf8_string):
1296
"""Coerce unicode_or_utf8_string into unicode.
1298
If it is unicode, it is returned.
1299
Otherwise it is decoded from utf-8. If decoding fails, the exception is
1300
wrapped in a BzrBadParameterNotUnicode exception.
1302
if isinstance(unicode_or_utf8_string, unicode):
1303
return unicode_or_utf8_string
1305
return unicode_or_utf8_string.decode('utf8')
1306
except UnicodeDecodeError:
1307
raise errors.BzrBadParameterNotUnicode(unicode_or_utf8_string)
1310
def safe_utf8(unicode_or_utf8_string):
1311
"""Coerce unicode_or_utf8_string to a utf8 string.
1313
If it is a str, it is returned.
1314
If it is Unicode, it is encoded into a utf-8 string.
1316
if isinstance(unicode_or_utf8_string, str):
1317
# TODO: jam 20070209 This is overkill, and probably has an impact on
1318
# performance if we are dealing with lots of apis that want a
1321
# Make sure it is a valid utf-8 string
1322
unicode_or_utf8_string.decode('utf-8')
1323
except UnicodeDecodeError:
1324
raise errors.BzrBadParameterNotUnicode(unicode_or_utf8_string)
1325
return unicode_or_utf8_string
1326
return unicode_or_utf8_string.encode('utf-8')
1329
_revision_id_warning = ('Unicode revision ids were deprecated in bzr 0.15.'
1330
' Revision id generators should be creating utf8'
1334
def safe_revision_id(unicode_or_utf8_string, warn=True):
1335
"""Revision ids should now be utf8, but at one point they were unicode.
1337
:param unicode_or_utf8_string: A possibly Unicode revision_id. (can also be
1339
:param warn: Functions that are sanitizing user data can set warn=False
1340
:return: None or a utf8 revision id.
1342
if (unicode_or_utf8_string is None
1343
or unicode_or_utf8_string.__class__ == str):
1344
return unicode_or_utf8_string
1346
symbol_versioning.warn(_revision_id_warning, DeprecationWarning,
1348
return cache_utf8.encode(unicode_or_utf8_string)
1351
_file_id_warning = ('Unicode file ids were deprecated in bzr 0.15. File id'
1352
' generators should be creating utf8 file ids.')
1355
def safe_file_id(unicode_or_utf8_string, warn=True):
1356
"""File ids should now be utf8, but at one point they were unicode.
1358
This is the same as safe_utf8, except it uses the cached encode functions
1359
to save a little bit of performance.
1361
:param unicode_or_utf8_string: A possibly Unicode file_id. (can also be
1363
:param warn: Functions that are sanitizing user data can set warn=False
1364
:return: None or a utf8 file id.
1366
if (unicode_or_utf8_string is None
1367
or unicode_or_utf8_string.__class__ == str):
1368
return unicode_or_utf8_string
1370
symbol_versioning.warn(_file_id_warning, DeprecationWarning,
1372
return cache_utf8.encode(unicode_or_utf8_string)
1375
_platform_normalizes_filenames = False
1376
if sys.platform == 'darwin':
1377
_platform_normalizes_filenames = True
1380
def normalizes_filenames():
1381
"""Return True if this platform normalizes unicode filenames.
1385
return _platform_normalizes_filenames
1388
def _accessible_normalized_filename(path):
1389
"""Get the unicode normalized path, and if you can access the file.
1391
On platforms where the system normalizes filenames (Mac OSX),
1392
you can access a file by any path which will normalize correctly.
1393
On platforms where the system does not normalize filenames
1394
(everything else), you have to access a file by its exact path.
1396
Internally, bzr only supports NFC normalization, since that is
1397
the standard for XML documents.
1399
So return the normalized path, and a flag indicating if the file
1400
can be accessed by that path.
1403
return unicodedata.normalize('NFC', unicode(path)), True
1406
def _inaccessible_normalized_filename(path):
1407
__doc__ = _accessible_normalized_filename.__doc__
1409
normalized = unicodedata.normalize('NFC', unicode(path))
1410
return normalized, normalized == path
1413
if _platform_normalizes_filenames:
1414
normalized_filename = _accessible_normalized_filename
1416
normalized_filename = _inaccessible_normalized_filename
1419
def set_signal_handler(signum, handler, restart_syscall=True):
1420
"""A wrapper for signal.signal that also calls siginterrupt(signum, False)
1421
on platforms that support that.
1423
:param restart_syscall: if set, allow syscalls interrupted by a signal to
1424
automatically restart (by calling `signal.siginterrupt(signum,
1425
False)`). May be ignored if the feature is not available on this
1426
platform or Python version.
1430
siginterrupt = signal.siginterrupt
1432
# This python implementation doesn't provide signal support, hence no
1435
except AttributeError:
1436
# siginterrupt doesn't exist on this platform, or for this version
1438
siginterrupt = lambda signum, flag: None
1440
def sig_handler(*args):
1441
# Python resets the siginterrupt flag when a signal is
1442
# received. <http://bugs.python.org/issue8354>
1443
# As a workaround for some cases, set it back the way we want it.
1444
siginterrupt(signum, False)
1445
# Now run the handler function passed to set_signal_handler.
1448
sig_handler = handler
1449
old_handler = signal.signal(signum, sig_handler)
1451
siginterrupt(signum, False)
1455
default_terminal_width = 80
1456
"""The default terminal width for ttys.
1458
This is defined so that higher levels can share a common fallback value when
1459
terminal_width() returns None.
1462
# Keep some state so that terminal_width can detect if _terminal_size has
1463
# returned a different size since the process started. See docstring and
1464
# comments of terminal_width for details.
1465
# _terminal_size_state has 3 possible values: no_data, unchanged, and changed.
1466
_terminal_size_state = 'no_data'
1467
_first_terminal_size = None
487
# XXX This should raise a NotChildPath exception, as its not tied
489
raise NotBranchError("path %r is not within branch %r" % (rp, base))
491
return os.sep.join(s)
1469
495
def terminal_width():
1470
"""Return terminal width.
1472
None is returned if the width can't established precisely.
1475
- if BZR_COLUMNS is set, returns its value
1476
- if there is no controlling terminal, returns None
1477
- query the OS, if the queried size has changed since the last query,
1479
- if COLUMNS is set, returns its value,
1480
- if the OS has a value (even though it's never changed), return its value.
1482
From there, we need to query the OS to get the size of the controlling
1485
On Unices we query the OS by:
1486
- get termios.TIOCGWINSZ
1487
- if an error occurs or a negative value is obtained, returns None
1489
On Windows we query the OS by:
1490
- win32utils.get_console_size() decides,
1491
- returns None on error (provided default value)
1493
# Note to implementors: if changing the rules for determining the width,
1494
# make sure you've considered the behaviour in these cases:
1495
# - M-x shell in emacs, where $COLUMNS is set and TIOCGWINSZ returns 0,0.
1496
# - bzr log | less, in bash, where $COLUMNS not set and TIOCGWINSZ returns
1498
# - (add more interesting cases here, if you find any)
1499
# Some programs implement "Use $COLUMNS (if set) until SIGWINCH occurs",
1500
# but we don't want to register a signal handler because it is impossible
1501
# to do so without risking EINTR errors in Python <= 2.6.5 (see
1502
# <http://bugs.python.org/issue8354>). Instead we check TIOCGWINSZ every
1503
# time so we can notice if the reported size has changed, which should have
1506
# If BZR_COLUMNS is set, take it, user is always right
1507
# Except if they specified 0 in which case, impose no limit here
1509
width = int(os.environ['BZR_COLUMNS'])
1510
except (KeyError, ValueError):
1512
if width is not None:
1518
isatty = getattr(sys.stdout, 'isatty', None)
1519
if isatty is None or not isatty():
1520
# Don't guess, setting BZR_COLUMNS is the recommended way to override.
1524
width, height = os_size = _terminal_size(None, None)
1525
global _first_terminal_size, _terminal_size_state
1526
if _terminal_size_state == 'no_data':
1527
_first_terminal_size = os_size
1528
_terminal_size_state = 'unchanged'
1529
elif (_terminal_size_state == 'unchanged' and
1530
_first_terminal_size != os_size):
1531
_terminal_size_state = 'changed'
1533
# If the OS claims to know how wide the terminal is, and this value has
1534
# ever changed, use that.
1535
if _terminal_size_state == 'changed':
1536
if width is not None and width > 0:
1539
# If COLUMNS is set, use it.
496
"""Return estimated terminal width."""
498
# TODO: Do something smart on Windows?
500
# TODO: Is there anything that gets a better update when the window
501
# is resized while the program is running? We could use the Python termcap
1541
504
return int(os.environ['COLUMNS'])
1542
except (KeyError, ValueError):
1545
# Finally, use an unchanged size from the OS, if we have one.
1546
if _terminal_size_state == 'unchanged':
1547
if width is not None and width > 0:
1550
# The width could not be determined.
1554
def _win32_terminal_size(width, height):
1555
width, height = win32utils.get_console_size(defaultx=width, defaulty=height)
1556
return width, height
1559
def _ioctl_terminal_size(width, height):
1561
import struct, fcntl, termios
1562
s = struct.pack('HHHH', 0, 0, 0, 0)
1563
x = fcntl.ioctl(1, termios.TIOCGWINSZ, s)
1564
height, width = struct.unpack('HHHH', x)[0:2]
1565
except (IOError, AttributeError):
1567
return width, height
1569
_terminal_size = None
1570
"""Returns the terminal size as (width, height).
1572
:param width: Default value for width.
1573
:param height: Default value for height.
1575
This is defined specifically for each OS and query the size of the controlling
1576
terminal. If any error occurs, the provided default values should be returned.
1578
if sys.platform == 'win32':
1579
_terminal_size = _win32_terminal_size
1581
_terminal_size = _ioctl_terminal_size
1584
def supports_executable():
1585
return sys.platform != "win32"
1588
def supports_posix_readonly():
1589
"""Return True if 'readonly' has POSIX semantics, False otherwise.
1591
Notably, a win32 readonly file cannot be deleted, unlike POSIX where the
1592
directory controls creation/deletion, etc.
1594
And under win32, readonly means that the directory itself cannot be
1595
deleted. The contents of a readonly directory can be changed, unlike POSIX
1596
where files in readonly directories cannot be added, deleted or renamed.
1598
return sys.platform != "win32"
1601
def set_or_unset_env(env_variable, value):
1602
"""Modify the environment, setting or removing the env_variable.
1604
:param env_variable: The environment variable in question
1605
:param value: The value to set the environment to. If None, then
1606
the variable will be removed.
1607
:return: The original value of the environment variable.
1609
orig_val = os.environ.get(env_variable)
1611
if orig_val is not None:
1612
del os.environ[env_variable]
1614
if isinstance(value, unicode):
1615
value = value.encode(get_user_encoding())
1616
os.environ[env_variable] = value
1620
_validWin32PathRE = re.compile(r'^([A-Za-z]:[/\\])?[^:<>*"?\|]*$')
1623
def check_legal_path(path):
1624
"""Check whether the supplied path is legal.
1625
This is only required on Windows, so we don't test on other platforms
1628
if sys.platform != "win32":
1630
if _validWin32PathRE.match(path) is None:
1631
raise errors.IllegalPath(path)
1634
_WIN32_ERROR_DIRECTORY = 267 # Similar to errno.ENOTDIR
1636
def _is_error_enotdir(e):
1637
"""Check if this exception represents ENOTDIR.
1639
Unfortunately, python is very inconsistent about the exception
1640
here. The cases are:
1641
1) Linux, Mac OSX all versions seem to set errno == ENOTDIR
1642
2) Windows, Python2.4, uses errno == ERROR_DIRECTORY (267)
1643
which is the windows error code.
1644
3) Windows, Python2.5 uses errno == EINVAL and
1645
winerror == ERROR_DIRECTORY
1647
:param e: An Exception object (expected to be OSError with an errno
1648
attribute, but we should be able to cope with anything)
1649
:return: True if this represents an ENOTDIR error. False otherwise.
1651
en = getattr(e, 'errno', None)
1652
if (en == errno.ENOTDIR
1653
or (sys.platform == 'win32'
1654
and (en == _WIN32_ERROR_DIRECTORY
1655
or (en == errno.EINVAL
1656
and getattr(e, 'winerror', None) == _WIN32_ERROR_DIRECTORY)
1662
def walkdirs(top, prefix=""):
1663
"""Yield data about all the directories in a tree.
1665
This yields all the data about the contents of a directory at a time.
1666
After each directory has been yielded, if the caller has mutated the list
1667
to exclude some directories, they are then not descended into.
1669
The data yielded is of the form:
1670
((directory-relpath, directory-path-from-top),
1671
[(relpath, basename, kind, lstat, path-from-top), ...]),
1672
- directory-relpath is the relative path of the directory being returned
1673
with respect to top. prefix is prepended to this.
1674
- directory-path-from-root is the path including top for this directory.
1675
It is suitable for use with os functions.
1676
- relpath is the relative path within the subtree being walked.
1677
- basename is the basename of the path
1678
- kind is the kind of the file now. If unknown then the file is not
1679
present within the tree - but it may be recorded as versioned. See
1681
- lstat is the stat data *if* the file was statted.
1682
- planned, not implemented:
1683
path_from_tree_root is the path from the root of the tree.
1685
:param prefix: Prefix the relpaths that are yielded with 'prefix'. This
1686
allows one to walk a subtree but get paths that are relative to a tree
1688
:return: an iterator over the dirs.
1690
#TODO there is a bit of a smell where the results of the directory-
1691
# summary in this, and the path from the root, may not agree
1692
# depending on top and prefix - i.e. ./foo and foo as a pair leads to
1693
# potentially confusing output. We should make this more robust - but
1694
# not at a speed cost. RBC 20060731
1696
_directory = _directory_kind
1697
_listdir = os.listdir
1698
_kind_from_mode = file_kind_from_stat_mode
1699
pending = [(safe_unicode(prefix), "", _directory, None, safe_unicode(top))]
1701
# 0 - relpath, 1- basename, 2- kind, 3- stat, 4-toppath
1702
relroot, _, _, _, top = pending.pop()
1704
relprefix = relroot + u'/'
1707
top_slash = top + u'/'
1710
append = dirblock.append
1712
names = sorted(map(decode_filename, _listdir(top)))
1714
if not _is_error_enotdir(e):
1718
abspath = top_slash + name
1719
statvalue = _lstat(abspath)
1720
kind = _kind_from_mode(statvalue.st_mode)
1721
append((relprefix + name, name, kind, statvalue, abspath))
1722
yield (relroot, top), dirblock
1724
# push the user specified dirs from dirblock
1725
pending.extend(d for d in reversed(dirblock) if d[2] == _directory)
1728
class DirReader(object):
1729
"""An interface for reading directories."""
1731
def top_prefix_to_starting_dir(self, top, prefix=""):
1732
"""Converts top and prefix to a starting dir entry
1734
:param top: A utf8 path
1735
:param prefix: An optional utf8 path to prefix output relative paths
1737
:return: A tuple starting with prefix, and ending with the native
1740
raise NotImplementedError(self.top_prefix_to_starting_dir)
1742
def read_dir(self, prefix, top):
1743
"""Read a specific dir.
1745
:param prefix: A utf8 prefix to be preprended to the path basenames.
1746
:param top: A natively encoded path to read.
1747
:return: A list of the directories contents. Each item contains:
1748
(utf8_relpath, utf8_name, kind, lstatvalue, native_abspath)
1750
raise NotImplementedError(self.read_dir)
1753
_selected_dir_reader = None
1756
def _walkdirs_utf8(top, prefix=""):
1757
"""Yield data about all the directories in a tree.
1759
This yields the same information as walkdirs() only each entry is yielded
1760
in utf-8. On platforms which have a filesystem encoding of utf8 the paths
1761
are returned as exact byte-strings.
1763
:return: yields a tuple of (dir_info, [file_info])
1764
dir_info is (utf8_relpath, path-from-top)
1765
file_info is (utf8_relpath, utf8_name, kind, lstat, path-from-top)
1766
if top is an absolute path, path-from-top is also an absolute path.
1767
path-from-top might be unicode or utf8, but it is the correct path to
1768
pass to os functions to affect the file in question. (such as os.lstat)
1770
global _selected_dir_reader
1771
if _selected_dir_reader is None:
1772
fs_encoding = _fs_enc.upper()
1773
if sys.platform == "win32" and win32utils.winver == 'Windows NT':
1774
# Win98 doesn't have unicode apis like FindFirstFileW
1775
# TODO: We possibly could support Win98 by falling back to the
1776
# original FindFirstFile, and using TCHAR instead of WCHAR,
1777
# but that gets a bit tricky, and requires custom compiling
1780
from bzrlib._walkdirs_win32 import Win32ReadDir
1781
_selected_dir_reader = Win32ReadDir()
1784
elif fs_encoding in ('UTF-8', 'US-ASCII', 'ANSI_X3.4-1968'):
1785
# ANSI_X3.4-1968 is a form of ASCII
1787
from bzrlib._readdir_pyx import UTF8DirReader
1788
_selected_dir_reader = UTF8DirReader()
1789
except ImportError, e:
1790
failed_to_load_extension(e)
1793
if _selected_dir_reader is None:
1794
# Fallback to the python version
1795
_selected_dir_reader = UnicodeDirReader()
1797
# 0 - relpath, 1- basename, 2- kind, 3- stat, 4-toppath
1798
# But we don't actually uses 1-3 in pending, so set them to None
1799
pending = [[_selected_dir_reader.top_prefix_to_starting_dir(top, prefix)]]
1800
read_dir = _selected_dir_reader.read_dir
1801
_directory = _directory_kind
1803
relroot, _, _, _, top = pending[-1].pop()
1806
dirblock = sorted(read_dir(relroot, top))
1807
yield (relroot, top), dirblock
1808
# push the user specified dirs from dirblock
1809
next = [d for d in reversed(dirblock) if d[2] == _directory]
1811
pending.append(next)
1814
class UnicodeDirReader(DirReader):
1815
"""A dir reader for non-utf8 file systems, which transcodes."""
1817
__slots__ = ['_utf8_encode']
1820
self._utf8_encode = codecs.getencoder('utf8')
1822
def top_prefix_to_starting_dir(self, top, prefix=""):
1823
"""See DirReader.top_prefix_to_starting_dir."""
1824
return (safe_utf8(prefix), None, None, None, safe_unicode(top))
1826
def read_dir(self, prefix, top):
1827
"""Read a single directory from a non-utf8 file system.
1829
top, and the abspath element in the output are unicode, all other paths
1830
are utf8. Local disk IO is done via unicode calls to listdir etc.
1832
This is currently the fallback code path when the filesystem encoding is
1833
not UTF-8. It may be better to implement an alternative so that we can
1834
safely handle paths that are not properly decodable in the current
1837
See DirReader.read_dir for details.
1839
_utf8_encode = self._utf8_encode
1841
_listdir = os.listdir
1842
_kind_from_mode = file_kind_from_stat_mode
1845
relprefix = prefix + '/'
1848
top_slash = top + u'/'
1851
append = dirblock.append
1852
for name in sorted(_listdir(top)):
1854
name_utf8 = _utf8_encode(name)[0]
1855
except UnicodeDecodeError:
1856
raise errors.BadFilenameEncoding(
1857
_utf8_encode(relprefix)[0] + name, _fs_enc)
1858
abspath = top_slash + name
1859
statvalue = _lstat(abspath)
1860
kind = _kind_from_mode(statvalue.st_mode)
1861
append((relprefix + name_utf8, name_utf8, kind, statvalue, abspath))
1865
def copy_tree(from_path, to_path, handlers={}):
1866
"""Copy all of the entries in from_path into to_path.
1868
:param from_path: The base directory to copy.
1869
:param to_path: The target directory. If it does not exist, it will
1871
:param handlers: A dictionary of functions, which takes a source and
1872
destinations for files, directories, etc.
1873
It is keyed on the file kind, such as 'directory', 'symlink', or 'file'
1874
'file', 'directory', and 'symlink' should always exist.
1875
If they are missing, they will be replaced with 'os.mkdir()',
1876
'os.readlink() + os.symlink()', and 'shutil.copy2()', respectively.
1878
# Now, just copy the existing cached tree to the new location
1879
# We use a cheap trick here.
1880
# Absolute paths are prefixed with the first parameter
1881
# relative paths are prefixed with the second.
1882
# So we can get both the source and target returned
1883
# without any extra work.
1885
def copy_dir(source, dest):
1888
def copy_link(source, dest):
1889
"""Copy the contents of a symlink"""
1890
link_to = os.readlink(source)
1891
os.symlink(link_to, dest)
1893
real_handlers = {'file':shutil.copy2,
1894
'symlink':copy_link,
1895
'directory':copy_dir,
1897
real_handlers.update(handlers)
1899
if not os.path.exists(to_path):
1900
real_handlers['directory'](from_path, to_path)
1902
for dir_info, entries in walkdirs(from_path, prefix=to_path):
1903
for relpath, name, kind, st, abspath in entries:
1904
real_handlers[kind](abspath, relpath)
1907
def copy_ownership_from_path(dst, src=None):
1908
"""Copy usr/grp ownership from src file/dir to dst file/dir.
1910
If src is None, the containing directory is used as source. If chown
1911
fails, the error is ignored and a warning is printed.
1913
chown = getattr(os, 'chown', None)
1918
src = os.path.dirname(dst)
1924
chown(dst, s.st_uid, s.st_gid)
1927
'Unable to copy ownership from "%s" to "%s". '
1928
'You may want to set it manually.', src, dst)
1929
trace.log_exception_quietly()
1932
def path_prefix_key(path):
1933
"""Generate a prefix-order path key for path.
1935
This can be used to sort paths in the same way that walkdirs does.
1937
return (dirname(path) , path)
1940
def compare_paths_prefix_order(path_a, path_b):
1941
"""Compare path_a and path_b to generate the same order walkdirs uses."""
1942
key_a = path_prefix_key(path_a)
1943
key_b = path_prefix_key(path_b)
1944
return cmp(key_a, key_b)
1947
_cached_user_encoding = None
1950
def get_user_encoding(use_cache=True):
1951
"""Find out what the preferred user encoding is.
1953
This is generally the encoding that is used for command line parameters
1954
and file contents. This may be different from the terminal encoding
1955
or the filesystem encoding.
1957
:param use_cache: Enable cache for detected encoding.
1958
(This parameter is turned on by default,
1959
and required only for selftesting)
1961
:return: A string defining the preferred user encoding
1963
global _cached_user_encoding
1964
if _cached_user_encoding is not None and use_cache:
1965
return _cached_user_encoding
1967
if sys.platform == 'darwin':
1968
# python locale.getpreferredencoding() always return
1969
# 'mac-roman' on darwin. That's a lie.
1970
sys.platform = 'posix'
1972
if os.environ.get('LANG', None) is None:
1973
# If LANG is not set, we end up with 'ascii', which is bad
1974
# ('mac-roman' is more than ascii), so we set a default which
1975
# will give us UTF-8 (which appears to work in all cases on
1976
# OSX). Users are still free to override LANG of course, as
1977
# long as it give us something meaningful. This work-around
1978
# *may* not be needed with python 3k and/or OSX 10.5, but will
1979
# work with them too -- vila 20080908
1980
os.environ['LANG'] = 'en_US.UTF-8'
1983
sys.platform = 'darwin'
1988
user_encoding = locale.getpreferredencoding()
1989
except locale.Error, e:
1990
sys.stderr.write('bzr: warning: %s\n'
1991
' Could not determine what text encoding to use.\n'
1992
' This error usually means your Python interpreter\n'
1993
' doesn\'t support the locale set by $LANG (%s)\n'
1994
" Continuing with ascii encoding.\n"
1995
% (e, os.environ.get('LANG')))
1996
user_encoding = 'ascii'
1998
# Windows returns 'cp0' to indicate there is no code page. So we'll just
1999
# treat that as ASCII, and not support printing unicode characters to the
2002
# For python scripts run under vim, we get '', so also treat that as ASCII
2003
if user_encoding in (None, 'cp0', ''):
2004
user_encoding = 'ascii'
2008
codecs.lookup(user_encoding)
2010
sys.stderr.write('bzr: warning:'
2011
' unknown encoding %s.'
2012
' Continuing with ascii encoding.\n'
2015
user_encoding = 'ascii'
2018
_cached_user_encoding = user_encoding
2020
return user_encoding
2023
def get_diff_header_encoding():
2024
return get_terminal_encoding()
2027
def get_host_name():
2028
"""Return the current unicode host name.
2030
This is meant to be used in place of socket.gethostname() because that
2031
behaves inconsistently on different platforms.
2033
if sys.platform == "win32":
2035
return win32utils.get_host_name()
2038
return socket.gethostname().decode(get_user_encoding())
2041
# We must not read/write any more than 64k at a time from/to a socket so we
2042
# don't risk "no buffer space available" errors on some platforms. Windows in
2043
# particular is likely to throw WSAECONNABORTED or WSAENOBUFS if given too much
2045
MAX_SOCKET_CHUNK = 64 * 1024
2047
_end_of_stream_errors = [errno.ECONNRESET]
2048
for _eno in ['WSAECONNRESET', 'WSAECONNABORTED']:
2049
_eno = getattr(errno, _eno, None)
2050
if _eno is not None:
2051
_end_of_stream_errors.append(_eno)
2055
def read_bytes_from_socket(sock, report_activity=None,
2056
max_read_size=MAX_SOCKET_CHUNK):
2057
"""Read up to max_read_size of bytes from sock and notify of progress.
2059
Translates "Connection reset by peer" into file-like EOF (return an
2060
empty string rather than raise an error), and repeats the recv if
2061
interrupted by a signal.
2065
bytes = sock.recv(max_read_size)
2066
except socket.error, e:
2068
if eno in _end_of_stream_errors:
2069
# The connection was closed by the other side. Callers expect
2070
# an empty string to signal end-of-stream.
2072
elif eno == errno.EINTR:
2073
# Retry the interrupted recv.
2077
if report_activity is not None:
2078
report_activity(len(bytes), 'read')
2082
def recv_all(socket, count):
2083
"""Receive an exact number of bytes.
2085
Regular Socket.recv() may return less than the requested number of bytes,
2086
depending on what's in the OS buffer. MSG_WAITALL is not available
2087
on all platforms, but this should work everywhere. This will return
2088
less than the requested amount if the remote end closes.
2090
This isn't optimized and is intended mostly for use in testing.
2093
while len(b) < count:
2094
new = read_bytes_from_socket(socket, None, count - len(b))
2101
def send_all(sock, bytes, report_activity=None):
2102
"""Send all bytes on a socket.
2104
Breaks large blocks in smaller chunks to avoid buffering limitations on
2105
some platforms, and catches EINTR which may be thrown if the send is
2106
interrupted by a signal.
2108
This is preferred to socket.sendall(), because it avoids portability bugs
2109
and provides activity reporting.
2111
:param report_activity: Call this as bytes are read, see
2112
Transport._report_activity
2115
byte_count = len(bytes)
2116
while sent_total < byte_count:
2118
sent = sock.send(buffer(bytes, sent_total, MAX_SOCKET_CHUNK))
2119
except socket.error, e:
2120
if e.args[0] != errno.EINTR:
2124
report_activity(sent, 'write')
2127
def connect_socket(address):
2128
# Slight variation of the socket.create_connection() function (provided by
2129
# python-2.6) that can fail if getaddrinfo returns an empty list. We also
2130
# provide it for previous python versions. Also, we don't use the timeout
2131
# parameter (provided by the python implementation) so we don't implement
2133
err = socket.error('getaddrinfo returns an empty list')
2134
host, port = address
2135
for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
2136
af, socktype, proto, canonname, sa = res
2139
sock = socket.socket(af, socktype, proto)
2143
except socket.error, err:
2144
# 'err' is now the most recent error
2145
if sock is not None:
2150
def dereference_path(path):
2151
"""Determine the real path to a file.
2153
All parent elements are dereferenced. But the file itself is not
2155
:param path: The original path. May be absolute or relative.
2156
:return: the real path *to* the file
2158
parent, base = os.path.split(path)
2159
# The pathjoin for '.' is a workaround for Python bug #1213894.
2160
# (initial path components aren't dereferenced)
2161
return pathjoin(realpath(pathjoin('.', parent)), base)
2164
def supports_mapi():
2165
"""Return True if we can use MAPI to launch a mail client."""
2166
return sys.platform == "win32"
2169
def resource_string(package, resource_name):
2170
"""Load a resource from a package and return it as a string.
2172
Note: Only packages that start with bzrlib are currently supported.
2174
This is designed to be a lightweight implementation of resource
2175
loading in a way which is API compatible with the same API from
2177
http://peak.telecommunity.com/DevCenter/PkgResources#basic-resource-access.
2178
If and when pkg_resources becomes a standard library, this routine
2181
# Check package name is within bzrlib
2182
if package == "bzrlib":
2183
resource_relpath = resource_name
2184
elif package.startswith("bzrlib."):
2185
package = package[len("bzrlib."):].replace('.', os.sep)
2186
resource_relpath = pathjoin(package, resource_name)
2188
raise errors.BzrError('resource package %s not in bzrlib' % package)
2190
# Map the resource to a file and read its contents
2191
base = dirname(bzrlib.__file__)
2192
if getattr(sys, 'frozen', None): # bzr.exe
2193
base = abspath(pathjoin(base, '..', '..'))
2194
f = file(pathjoin(base, resource_relpath), "rU")
2200
def file_kind_from_stat_mode_thunk(mode):
2201
global file_kind_from_stat_mode
2202
if file_kind_from_stat_mode is file_kind_from_stat_mode_thunk:
2204
from bzrlib._readdir_pyx import UTF8DirReader
2205
file_kind_from_stat_mode = UTF8DirReader().kind_from_mode
2206
except ImportError, e:
2207
# This is one time where we won't warn that an extension failed to
2208
# load. The extension is never available on Windows anyway.
2209
from bzrlib._readdir_py import (
2210
_kind_from_mode as file_kind_from_stat_mode
2212
return file_kind_from_stat_mode(mode)
2213
file_kind_from_stat_mode = file_kind_from_stat_mode_thunk
2216
def file_kind(f, _lstat=os.lstat):
2218
return file_kind_from_stat_mode(_lstat(f).st_mode)
2220
if getattr(e, 'errno', None) in (errno.ENOENT, errno.ENOTDIR):
2221
raise errors.NoSuchFile(f)
2225
def until_no_eintr(f, *a, **kw):
2226
"""Run f(*a, **kw), retrying if an EINTR error occurs.
2228
WARNING: you must be certain that it is safe to retry the call repeatedly
2229
if EINTR does occur. This is typically only true for low-level operations
2230
like os.read. If in any doubt, don't use this.
2232
Keep in mind that this is not a complete solution to EINTR. There is
2233
probably code in the Python standard library and other dependencies that
2234
may encounter EINTR if a signal arrives (and there is signal handler for
2235
that signal). So this function can reduce the impact for IO that bzrlib
2236
directly controls, but it is not a complete solution.
2238
# Borrowed from Twisted's twisted.python.util.untilConcludes function.
2242
except (IOError, OSError), e:
2243
if e.errno == errno.EINTR:
2248
@deprecated_function(deprecated_in((2, 2, 0)))
2249
def re_compile_checked(re_string, flags=0, where=""):
2250
"""Return a compiled re, or raise a sensible error.
2252
This should only be used when compiling user-supplied REs.
2254
:param re_string: Text form of regular expression.
2255
:param flags: eg re.IGNORECASE
2256
:param where: Message explaining to the user the context where
2257
it occurred, eg 'log search filter'.
2259
# from https://bugs.launchpad.net/bzr/+bug/251352
2261
re_obj = re.compile(re_string, flags)
2264
except errors.InvalidPattern, e:
2266
where = ' in ' + where
2267
# despite the name 'error' is a type
2268
raise errors.BzrCommandError('Invalid regular expression%s: %s'
2272
if sys.platform == "win32":
2275
return msvcrt.getch()
2280
fd = sys.stdin.fileno()
2281
settings = termios.tcgetattr(fd)
2284
ch = sys.stdin.read(1)
2286
termios.tcsetattr(fd, termios.TCSADRAIN, settings)
2289
if sys.platform == 'linux2':
2290
def _local_concurrency():
2292
return os.sysconf('SC_NPROCESSORS_ONLN')
2293
except (ValueError, OSError, AttributeError):
2295
elif sys.platform == 'darwin':
2296
def _local_concurrency():
2297
return subprocess.Popen(['sysctl', '-n', 'hw.availcpu'],
2298
stdout=subprocess.PIPE).communicate()[0]
2299
elif "bsd" in sys.platform:
2300
def _local_concurrency():
2301
return subprocess.Popen(['sysctl', '-n', 'hw.ncpu'],
2302
stdout=subprocess.PIPE).communicate()[0]
2303
elif sys.platform == 'sunos5':
2304
def _local_concurrency():
2305
return subprocess.Popen(['psrinfo', '-p',],
2306
stdout=subprocess.PIPE).communicate()[0]
2307
elif sys.platform == "win32":
2308
def _local_concurrency():
2309
# This appears to return the number of cores.
2310
return os.environ.get('NUMBER_OF_PROCESSORS')
2312
def _local_concurrency():
2317
_cached_local_concurrency = None
2319
def local_concurrency(use_cache=True):
2320
"""Return how many processes can be run concurrently.
2322
Rely on platform specific implementations and default to 1 (one) if
2323
anything goes wrong.
2325
global _cached_local_concurrency
2327
if _cached_local_concurrency is not None and use_cache:
2328
return _cached_local_concurrency
2330
concurrency = os.environ.get('BZR_CONCURRENCY', None)
2331
if concurrency is None:
2333
import multiprocessing
2335
# multiprocessing is only available on Python >= 2.6
2337
concurrency = _local_concurrency()
2338
except (OSError, IOError):
2341
concurrency = multiprocessing.cpu_count()
2343
concurrency = int(concurrency)
2344
except (TypeError, ValueError):
2347
_cached_concurrency = concurrency
2351
class UnicodeOrBytesToBytesWriter(codecs.StreamWriter):
2352
"""A stream writer that doesn't decode str arguments."""
2354
def __init__(self, encode, stream, errors='strict'):
2355
codecs.StreamWriter.__init__(self, stream, errors)
2356
self.encode = encode
2358
def write(self, object):
2359
if type(object) is str:
2360
self.stream.write(object)
2362
data, _ = self.encode(object, self.errors)
2363
self.stream.write(data)
2365
if sys.platform == 'win32':
2366
def open_file(filename, mode='r', bufsize=-1):
2367
"""This function is used to override the ``open`` builtin.
2369
But it uses O_NOINHERIT flag so the file handle is not inherited by
2370
child processes. Deleting or renaming a closed file opened with this
2371
function is not blocking child processes.
2373
writing = 'w' in mode
2374
appending = 'a' in mode
2375
updating = '+' in mode
2376
binary = 'b' in mode
2379
# see http://msdn.microsoft.com/en-us/library/yeby3zcb%28VS.71%29.aspx
2380
# for flags for each modes.
2390
flags |= os.O_WRONLY
2391
flags |= os.O_CREAT | os.O_TRUNC
2396
flags |= os.O_WRONLY
2397
flags |= os.O_CREAT | os.O_APPEND
2402
flags |= os.O_RDONLY
2404
return os.fdopen(os.open(filename, flags), mode, bufsize)
2409
def getuser_unicode():
2410
"""Return the username as unicode.
2413
user_encoding = get_user_encoding()
2414
username = getpass.getuser().decode(user_encoding)
2415
except UnicodeDecodeError:
2416
raise errors.BzrError("Can't decode username as %s." % \
2418
except ImportError, e:
2419
if sys.platform != 'win32':
2421
if str(e) != 'No module named pwd':
2423
# https://bugs.launchpad.net/bzr/+bug/660174
2424
# getpass.getuser() is unable to return username on Windows
2425
# if there is no USERNAME environment variable set.
2426
# That could be true if bzr is running as a service,
2427
# e.g. running `bzr serve` as a service on Windows.
2428
# We should not fail with traceback in this case.
2429
username = u'UNKNOWN'
2433
def available_backup_name(base, exists):
2434
"""Find a non-existing backup file name.
2436
This will *not* create anything, this only return a 'free' entry. This
2437
should be used for checking names in a directory below a locked
2438
tree/branch/repo to avoid race conditions. This is LBYL (Look Before You
2439
Leap) and generally discouraged.
2441
:param base: The base name.
2443
:param exists: A callable returning True if the path parameter exists.
2446
name = "%s.~%d~" % (base, counter)
2449
name = "%s.~%d~" % (base, counter)
2453
def set_fd_cloexec(fd):
2454
"""Set a Unix file descriptor's FD_CLOEXEC flag. Do nothing if platform
2455
support for this is not available.
2459
old = fcntl.fcntl(fd, fcntl.F_GETFD)
2460
fcntl.fcntl(fd, fcntl.F_SETFD, old | fcntl.FD_CLOEXEC)
2461
except (ImportError, AttributeError):
2462
# Either the fcntl module or specific constants are not present
2466
def find_executable_on_path(name):
2467
"""Finds an executable on the PATH.
2469
On Windows, this will try to append each extension in the PATHEXT
2470
environment variable to the name, if it cannot be found with the name
2473
:param name: The base name of the executable.
2474
:return: The path to the executable found or None.
2476
path = os.environ.get('PATH')
2479
path = path.split(os.pathsep)
2480
if sys.platform == 'win32':
2481
exts = os.environ.get('PATHEXT', '').split(os.pathsep)
2482
exts = [ext.lower() for ext in exts]
2483
base, ext = os.path.splitext(name)
2485
if ext.lower() not in exts:
2493
f = os.path.join(d, name) + ext
2494
if os.access(f, os.X_OK):
2499
def _posix_is_local_pid_dead(pid):
2500
"""True if pid doesn't correspond to live process on this machine"""
2502
# Special meaning of unix kill: just check if it's there.
2505
if e.errno == errno.ESRCH:
2506
# On this machine, and really not found: as sure as we can be
2509
elif e.errno == errno.EPERM:
2510
# exists, though not ours
2513
mutter("os.kill(%d, 0) failed: %s" % (pid, e))
2514
# Don't really know.
2517
# Exists and our process: not dead.
2520
if sys.platform == "win32":
2521
is_local_pid_dead = win32utils.is_local_pid_dead
2523
is_local_pid_dead = _posix_is_local_pid_dead
2526
def fdatasync(fileno):
2527
"""Flush file contents to disk if possible.
2529
:param fileno: Integer OS file handle.
2530
:raises TransportNotPossible: If flushing to disk is not possible.
2532
fn = getattr(os, 'fdatasync', getattr(os, 'fsync', None))
2537
def ensure_empty_directory_exists(path, exception_class):
2538
"""Make sure a local directory exists and is empty.
2540
If it does not exist, it is created. If it exists and is not empty, an
2541
instance of exception_class is raised.
2546
if e.errno != errno.EEXIST:
2548
if os.listdir(path) != []:
2549
raise exception_class(path)
505
except (IndexError, KeyError, ValueError):