19
19
from cStringIO import StringIO
21
from ntpath import (abspath as _nt_abspath,
23
normpath as _nt_normpath,
24
realpath as _nt_realpath,
25
splitdrive as _nt_splitdrive,
22
28
from os import listdir
36
from ntpath import (abspath as _nt_abspath,
38
normpath as _nt_normpath,
39
realpath as _nt_realpath,
43
45
from bzrlib.errors import (BzrError,
49
from bzrlib.symbol_versioning import *
51
from bzrlib.symbol_versioning import (deprecated_function,
50
53
from bzrlib.trace import mutter
51
import bzrlib.win32console
54
56
def make_readonly(filename):
204
206
_fs_enc = sys.getfilesystemencoding()
205
207
def _posix_abspath(path):
206
return os.path.abspath(path.encode(_fs_enc)).decode(_fs_enc)
207
# jam 20060426 This is another possibility which mimics
208
# os.path.abspath, only uses unicode characters instead
209
# if not os.path.isabs(path):
210
# return os.path.join(os.getcwdu(), path)
208
# jam 20060426 rather than encoding to fsencoding
209
# copy posixpath.abspath, but use os.getcwdu instead
210
if not posixpath.isabs(path):
211
path = posixpath.join(getcwd(), path)
212
return posixpath.normpath(path)
214
215
def _posix_realpath(path):
215
return os.path.realpath(path.encode(_fs_enc)).decode(_fs_enc)
216
return posixpath.realpath(path.encode(_fs_enc)).decode(_fs_enc)
219
def _win32_fixdrive(path):
220
"""Force drive letters to be consistent.
222
win32 is inconsistent whether it returns lower or upper case
223
and even if it was consistent the user might type the other
224
so we force it to uppercase
225
running python.exe under cmd.exe return capital C:\\
226
running win32 python inside a cygwin shell returns lowercase c:\\
228
drive, path = _nt_splitdrive(path)
229
return drive.upper() + path
218
232
def _win32_abspath(path):
219
return _nt_abspath(path.encode(_fs_enc)).decode(_fs_enc).replace('\\', '/')
233
# Real _nt_abspath doesn't have a problem with a unicode cwd
234
return _win32_fixdrive(_nt_abspath(unicode(path)).replace('\\', '/'))
222
237
def _win32_realpath(path):
223
return _nt_realpath(path.encode(_fs_enc)).decode(_fs_enc).replace('\\', '/')
238
# Real _nt_realpath doesn't have a problem with a unicode cwd
239
return _win32_fixdrive(_nt_realpath(unicode(path)).replace('\\', '/'))
226
242
def _win32_pathjoin(*args):
230
246
def _win32_normpath(path):
231
return _nt_normpath(path).replace('\\', '/')
247
return _win32_fixdrive(_nt_normpath(unicode(path)).replace('\\', '/'))
234
250
def _win32_getcwd():
235
return os.getcwdu().replace('\\', '/')
251
return _win32_fixdrive(os.getcwdu().replace('\\', '/'))
238
254
def _win32_mkdtemp(*args, **kwargs):
239
return tempfile.mkdtemp(*args, **kwargs).replace('\\', '/')
255
return _win32_fixdrive(tempfile.mkdtemp(*args, **kwargs).replace('\\', '/'))
242
258
def _win32_rename(old, new):
243
fancy_rename(old, new, rename_func=os.rename, unlink_func=os.unlink)
259
"""We expect to be able to atomically replace 'new' with old.
261
On win32, if new exists, it must be moved out of the way first,
265
fancy_rename(old, new, rename_func=os.rename, unlink_func=os.unlink)
267
if e.errno in (errno.EPERM, errno.EACCES, errno.EBUSY):
268
# If we try to rename a non-existant file onto cwd, we get EPERM
269
# instead of ENOENT, this will raise ENOENT if the old path
246
275
# Default is to just use the python builtins, but these can be rebound on
288
317
return shutil.rmtree(path, ignore_errors, onerror)
320
def get_terminal_encoding():
321
"""Find the best encoding for printing to the screen.
323
This attempts to check both sys.stdout and sys.stdin to see
324
what encoding they are in, and if that fails it falls back to
325
bzrlib.user_encoding.
326
The problem is that on Windows, locale.getpreferredencoding()
327
is not the same encoding as that used by the console:
328
http://mail.python.org/pipermail/python-list/2003-May/162357.html
330
On my standard US Windows XP, the preferred encoding is
331
cp1252, but the console is cp437
333
output_encoding = getattr(sys.stdout, 'encoding', None)
334
if not output_encoding:
335
input_encoding = getattr(sys.stdin, 'encoding', None)
336
if not input_encoding:
337
output_encoding = bzrlib.user_encoding
338
mutter('encoding stdout as bzrlib.user_encoding %r', output_encoding)
340
output_encoding = input_encoding
341
mutter('encoding stdout as sys.stdin encoding %r', output_encoding)
343
mutter('encoding stdout as sys.stdout encoding %r', output_encoding)
344
return output_encoding
291
347
def normalizepath(f):
292
348
if hasattr(os.path, 'realpath'):
846
902
for dir in reversed(dirblock):
847
903
if dir[2] == _directory:
848
904
pending.append(dir)
907
def path_prefix_key(path):
908
"""Generate a prefix-order path key for path.
910
This can be used to sort paths in the same way that walkdirs does.
912
return (dirname(path) , path)
915
def compare_paths_prefix_order(path_a, path_b):
916
"""Compare path_a and path_b to generate the same order walkdirs uses."""
917
key_a = path_prefix_key(path_a)
918
key_b = path_prefix_key(path_b)
919
return cmp(key_a, key_b)