1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
1
# Copyright (C) 2005, 2006, 2007, 2009 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
77
78
O_BINARY = getattr(os, 'O_BINARY', 0)
81
def get_unicode_argv():
83
user_encoding = get_user_encoding()
84
return [a.decode(user_encoding) for a in sys.argv[1:]]
85
except UnicodeDecodeError:
86
raise errors.BzrError(("Parameter '%r' is unsupported by the current "
80
90
def make_readonly(filename):
81
91
"""Make a filename read-only."""
82
92
mod = os.lstat(filename).st_mode
98
108
:param paths: A container (and hence not None) of paths.
99
109
:return: A set of paths sufficient to include everything in paths via
100
is_inside_any, drawn from the paths parameter.
110
is_inside, drawn from the paths parameter.
105
other_paths = paths.difference([path])
106
if not is_inside_any(other_paths, path):
107
# this is a top level path, we must check it.
108
search_paths.add(path)
116
return path.split('/')
117
sorted_paths = sorted(list(paths), key=sort_key)
119
search_paths = [sorted_paths[0]]
120
for path in sorted_paths[1:]:
121
if not is_inside(search_paths[-1], path):
122
# This path is unique, add it
123
search_paths.append(path)
125
return set(search_paths)
384
400
def rmtree(path, ignore_errors=False, onerror=_win32_delete_readonly):
385
401
"""Replacer for shutil.rmtree: could remove readonly dirs/files"""
386
402
return shutil.rmtree(path, ignore_errors, onerror)
404
f = win32utils.get_unicode_argv # special function or None
387
408
elif sys.platform == 'darwin':
388
409
getcwd = _mac_getcwd
597
618
return s.hexdigest()
621
def size_sha_file(f):
622
"""Calculate the size and hexdigest of an open file.
624
The file cursor should be already at the start and
625
the caller is responsible for closing the file afterwards.
636
return size, s.hexdigest()
600
639
def sha_file_by_name(fname):
601
640
"""Calculate the SHA1 of a file by reading the full text"""
683
722
_format_date(t, offset, timezone, date_fmt, show_offset)
684
723
date_str = time.strftime(date_fmt, tt)
685
724
if not isinstance(date_str, unicode):
686
date_str = date_str.decode(bzrlib.user_encoding, 'replace')
725
date_str = date_str.decode(get_user_encoding(), 'replace')
687
726
return date_str + offset_str
689
728
def _format_date(t, offset, timezone, date_fmt, show_offset):
829
868
return pathjoin(*p)
871
def parent_directories(filename):
872
"""Return the list of parent directories, deepest first.
874
For example, parent_directories("a/b/c") -> ["a/b", "a"].
877
parts = splitpath(dirname(filename))
879
parents.append(joinpath(parts))
833
885
from bzrlib._chunks_to_lines_pyx import chunks_to_lines
834
886
except ImportError:
907
959
and sys.platform not in ('cygwin', 'win32'))
962
def readlink(abspath):
963
"""Return a string representing the path to which the symbolic link points.
965
:param abspath: The link absolute unicode path.
967
This his guaranteed to return the symbolic link in unicode in all python
970
link = abspath.encode(_fs_enc)
971
target = os.readlink(link)
972
target = target.decode(_fs_enc)
910
976
def contains_whitespace(s):
911
977
"""True if there are any whitespace characters in s."""
912
978
# string.whitespace can include '\xa0' in certain locales, because it is
1012
1078
return current[len(abs_base)+1:]
1014
1080
# XXX - TODO - we need better detection/integration of case-insensitive
1015
# file-systems; Linux often sees FAT32 devices, for example, so could
1016
# probably benefit from the same basic support there. For now though, only
1017
# Windows gets that support, and it gets it for *all* file-systems!
1018
if sys.platform == "win32":
1081
# file-systems; Linux often sees FAT32 devices (or NFS-mounted OSX
1082
# filesystems), for example, so could probably benefit from the same basic
1083
# support there. For now though, only Windows and OSX get that support, and
1084
# they get it for *all* file-systems!
1085
if sys.platform in ('win32', 'darwin'):
1019
1086
canonical_relpath = _cicp_canonical_relpath
1021
1088
canonical_relpath = relpath
1033
1100
"""Coerce unicode_or_utf8_string into unicode.
1035
1102
If it is unicode, it is returned.
1036
Otherwise it is decoded from utf-8. If a decoding error
1037
occurs, it is wrapped as a If the decoding fails, the exception is wrapped
1038
as a BzrBadParameter exception.
1103
Otherwise it is decoded from utf-8. If decoding fails, the exception is
1104
wrapped in a BzrBadParameterNotUnicode exception.
1040
1106
if isinstance(unicode_or_utf8_string, unicode):
1041
1107
return unicode_or_utf8_string
1374
1440
# for win98 anyway.
1376
1442
from bzrlib._walkdirs_win32 import Win32ReadDir
1378
_selected_dir_reader = UnicodeDirReader()
1380
1443
_selected_dir_reader = Win32ReadDir()
1381
elif fs_encoding not in ('UTF-8', 'US-ASCII', 'ANSI_X3.4-1968'):
1446
elif fs_encoding in ('UTF-8', 'US-ASCII', 'ANSI_X3.4-1968'):
1382
1447
# ANSI_X3.4-1968 is a form of ASCII
1383
_selected_dir_reader = UnicodeDirReader()
1386
1449
from bzrlib._readdir_pyx import UTF8DirReader
1388
# No optimised code path
1389
_selected_dir_reader = UnicodeDirReader()
1391
1450
_selected_dir_reader = UTF8DirReader()
1454
if _selected_dir_reader is None:
1455
# Fallback to the python version
1456
_selected_dir_reader = UnicodeDirReader()
1392
1458
# 0 - relpath, 1- basename, 2- kind, 3- stat, 4-toppath
1393
1459
# But we don't actually uses 1-3 in pending, so set them to None
1394
1460
pending = [[_selected_dir_reader.top_prefix_to_starting_dir(top, prefix)]]
1791
def re_compile_checked(re_string, flags=0, where=""):
1792
"""Return a compiled re, or raise a sensible error.
1794
This should only be used when compiling user-supplied REs.
1796
:param re_string: Text form of regular expression.
1797
:param flags: eg re.IGNORECASE
1798
:param where: Message explaining to the user the context where
1799
it occurred, eg 'log search filter'.
1801
# from https://bugs.launchpad.net/bzr/+bug/251352
1803
re_obj = re.compile(re_string, flags)
1808
where = ' in ' + where
1809
# despite the name 'error' is a type
1810
raise errors.BzrCommandError('Invalid regular expression%s: %r: %s'
1811
% (where, re_string, e))
1726
1814
if sys.platform == "win32":
1740
1828
termios.tcsetattr(fd, termios.TCSADRAIN, settings)
1832
if sys.platform == 'linux2':
1833
def _local_concurrency():
1835
prefix = 'processor'
1836
for line in file('/proc/cpuinfo', 'rb'):
1837
if line.startswith(prefix):
1838
concurrency = int(line[line.find(':')+1:]) + 1
1840
elif sys.platform == 'darwin':
1841
def _local_concurrency():
1842
return subprocess.Popen(['sysctl', '-n', 'hw.availcpu'],
1843
stdout=subprocess.PIPE).communicate()[0]
1844
elif sys.platform[0:7] == 'freebsd':
1845
def _local_concurrency():
1846
return subprocess.Popen(['sysctl', '-n', 'hw.ncpu'],
1847
stdout=subprocess.PIPE).communicate()[0]
1848
elif sys.platform == 'sunos5':
1849
def _local_concurrency():
1850
return subprocess.Popen(['psrinfo', '-p',],
1851
stdout=subprocess.PIPE).communicate()[0]
1852
elif sys.platform == "win32":
1853
def _local_concurrency():
1854
# This appears to return the number of cores.
1855
return os.environ.get('NUMBER_OF_PROCESSORS')
1857
def _local_concurrency():
1862
_cached_local_concurrency = None
1864
def local_concurrency(use_cache=True):
1865
"""Return how many processes can be run concurrently.
1867
Rely on platform specific implementations and default to 1 (one) if
1868
anything goes wrong.
1870
global _cached_local_concurrency
1871
if _cached_local_concurrency is not None and use_cache:
1872
return _cached_local_concurrency
1875
concurrency = _local_concurrency()
1876
except (OSError, IOError):
1879
concurrency = int(concurrency)
1880
except (TypeError, ValueError):
1883
_cached_concurrency = concurrency