~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

  • Committer: John Arbash Meinel
  • Date: 2006-07-12 18:05:01 UTC
  • mto: This revision was merged to the branch mainline in revision 1871.
  • Revision ID: john@arbash-meinel.com-20060712180501-1a638c0c5b1e7646
Updated WorkingTree to use the new user-level ignores.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
from cStringIO import StringIO
20
20
import errno
 
21
from ntpath import (abspath as _nt_abspath,
 
22
                    join as _nt_join,
 
23
                    normpath as _nt_normpath,
 
24
                    realpath as _nt_realpath,
 
25
                    splitdrive as _nt_splitdrive,
 
26
                    )
21
27
import os
22
28
from os import listdir
 
29
import posixpath
23
30
import re
24
31
import sha
25
32
import shutil
33
40
import types
34
41
import tempfile
35
42
import unicodedata
36
 
from ntpath import (abspath as _nt_abspath,
37
 
                    join as _nt_join,
38
 
                    normpath as _nt_normpath,
39
 
                    realpath as _nt_realpath,
40
 
                    )
41
43
 
42
44
import bzrlib
43
45
from bzrlib.errors import (BzrError,
46
48
                           PathNotChild,
47
49
                           IllegalPath,
48
50
                           )
49
 
from bzrlib.symbol_versioning import *
 
51
from bzrlib.symbol_versioning import (deprecated_function, 
 
52
        zero_nine)
50
53
from bzrlib.trace import mutter
51
 
import bzrlib.win32console
52
54
 
53
55
 
54
56
def make_readonly(filename):
203
205
# string.
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)
211
 
    # return 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)
212
213
 
213
214
 
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)
 
217
 
 
218
 
 
219
def _win32_fixdrive(path):
 
220
    """Force drive letters to be consistent.
 
221
 
 
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:\\
 
227
    """
 
228
    drive, path = _nt_splitdrive(path)
 
229
    return drive.upper() + path
216
230
 
217
231
 
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('\\', '/'))
220
235
 
221
236
 
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('\\', '/'))
224
240
 
225
241
 
226
242
def _win32_pathjoin(*args):
228
244
 
229
245
 
230
246
def _win32_normpath(path):
231
 
    return _nt_normpath(path).replace('\\', '/')
 
247
    return _win32_fixdrive(_nt_normpath(unicode(path)).replace('\\', '/'))
232
248
 
233
249
 
234
250
def _win32_getcwd():
235
 
    return os.getcwdu().replace('\\', '/')
 
251
    return _win32_fixdrive(os.getcwdu().replace('\\', '/'))
236
252
 
237
253
 
238
254
def _win32_mkdtemp(*args, **kwargs):
239
 
    return tempfile.mkdtemp(*args, **kwargs).replace('\\', '/')
 
255
    return _win32_fixdrive(tempfile.mkdtemp(*args, **kwargs).replace('\\', '/'))
240
256
 
241
257
 
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.
 
260
 
 
261
    On win32, if new exists, it must be moved out of the way first,
 
262
    and then deleted. 
 
263
    """
 
264
    try:
 
265
        fancy_rename(old, new, rename_func=os.rename, unlink_func=os.unlink)
 
266
    except OSError, e:
 
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
 
270
            # doesn't exist
 
271
            os.lstat(old)
 
272
        raise
244
273
 
245
274
 
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)
289
318
 
290
319
 
 
320
def get_terminal_encoding():
 
321
    """Find the best encoding for printing to the screen.
 
322
 
 
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
 
329
 
 
330
    On my standard US Windows XP, the preferred encoding is
 
331
    cp1252, but the console is cp437
 
332
    """
 
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)
 
339
        else:
 
340
            output_encoding = input_encoding
 
341
            mutter('encoding stdout as sys.stdin encoding %r', output_encoding)
 
342
    else:
 
343
        mutter('encoding stdout as sys.stdout encoding %r', output_encoding)
 
344
    return output_encoding
 
345
 
 
346
 
291
347
def normalizepath(f):
292
348
    if hasattr(os.path, 'realpath'):
293
349
        F = realpath
846
902
        for dir in reversed(dirblock):
847
903
            if dir[2] == _directory:
848
904
                pending.append(dir)
 
905
 
 
906
 
 
907
def path_prefix_key(path):
 
908
    """Generate a prefix-order path key for path.
 
909
 
 
910
    This can be used to sort paths in the same way that walkdirs does.
 
911
    """
 
912
    return (dirname(path) , path)
 
913
 
 
914
 
 
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)