/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

  • Committer: Jelmer Vernooij
  • Date: 2012-01-02 14:27:58 UTC
  • mfrom: (6410 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6441.
  • Revision ID: jelmer@samba.org-20120102142758-hl7xrn7m5hjhecdv
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
 
17
from __future__ import absolute_import
 
18
 
17
19
import errno
18
20
import os
19
21
import re
28
30
import getpass
29
31
import ntpath
30
32
import posixpath
 
33
import select
31
34
# We need to import both shutil and rmtree as we export the later on posix
32
35
# and need the former on windows
33
36
import shutil
62
65
 
63
66
 
64
67
import bzrlib
65
 
from bzrlib import symbol_versioning
 
68
from bzrlib import symbol_versioning, _fs_enc
66
69
 
67
70
 
68
71
# Cross platform wall-clock time functionality with decent resolution.
99
102
    mod = os.lstat(filename).st_mode
100
103
    if not stat.S_ISLNK(mod):
101
104
        mod = mod & 0777555
102
 
        os.chmod(filename, mod)
 
105
        chmod_if_possible(filename, mod)
103
106
 
104
107
 
105
108
def make_writable(filename):
106
109
    mod = os.lstat(filename).st_mode
107
110
    if not stat.S_ISLNK(mod):
108
111
        mod = mod | 0200
109
 
        os.chmod(filename, mod)
 
112
        chmod_if_possible(filename, mod)
 
113
 
 
114
 
 
115
def chmod_if_possible(filename, mode):
 
116
    # Set file mode if that can be safely done.
 
117
    # Sometimes even on unix the filesystem won't allow it - see
 
118
    # https://bugs.launchpad.net/bzr/+bug/606537
 
119
    try:
 
120
        # It is probably faster to just do the chmod, rather than
 
121
        # doing a stat, and then trying to compare
 
122
        os.chmod(filename, mode)
 
123
    except (IOError, OSError),e:
 
124
        # Permission/access denied seems to commonly happen on smbfs; there's
 
125
        # probably no point warning about it.
 
126
        # <https://bugs.launchpad.net/bzr/+bug/606537>
 
127
        if getattr(e, 'errno') in (errno.EPERM, errno.EACCES):
 
128
            trace.mutter("ignore error on chmod of %r: %r" % (
 
129
                filename, e))
 
130
            return
 
131
        raise
110
132
 
111
133
 
112
134
def minimum_path_selection(paths):
273
295
# choke on a Unicode string containing a relative path if
274
296
# os.getcwd() returns a non-sys.getdefaultencoding()-encoded
275
297
# string.
276
 
_fs_enc = sys.getfilesystemencoding() or 'utf-8'
277
298
def _posix_abspath(path):
278
299
    # jam 20060426 rather than encoding to fsencoding
279
300
    # copy posixpath.abspath, but use os.getcwdu instead
301
322
    return path
302
323
 
303
324
 
 
325
def _posix_path_from_environ(key):
 
326
    """Get unicode path from `key` in environment or None if not present
 
327
 
 
328
    Note that posix systems use arbitrary byte strings for filesystem objects,
 
329
    so a path that raises BadFilenameEncoding here may still be accessible.
 
330
    """
 
331
    val = os.environ.get(key, None)
 
332
    if val is None:
 
333
        return val
 
334
    try:
 
335
        return val.decode(_fs_enc)
 
336
    except UnicodeDecodeError:
 
337
        # GZ 2011-12-12:Ideally want to include `key` in the exception message
 
338
        raise errors.BadFilenameEncoding(val, _fs_enc)
 
339
 
 
340
 
 
341
def _posix_getuser_unicode():
 
342
    """Get username from environment or password database as unicode"""
 
343
    name = getpass.getuser()
 
344
    user_encoding = get_user_encoding()
 
345
    try:
 
346
        return name.decode(user_encoding)
 
347
    except UnicodeDecodeError:
 
348
        raise errors.BzrError("Encoding of username %r is unsupported by %s "
 
349
            "application locale." % (name, user_encoding))
 
350
 
 
351
 
304
352
def _win32_fixdrive(path):
305
353
    """Force drive letters to be consistent.
306
354
 
395
443
realpath = _posix_realpath
396
444
pathjoin = os.path.join
397
445
normpath = _posix_normpath
 
446
path_from_environ = _posix_path_from_environ
 
447
getuser_unicode = _posix_getuser_unicode
398
448
getcwd = os.getcwdu
399
449
rename = os.rename
400
450
dirname = os.path.dirname
456
506
    f = win32utils.get_unicode_argv     # special function or None
457
507
    if f is not None:
458
508
        get_unicode_argv = f
 
509
    path_from_environ = win32utils.get_environ_unicode
 
510
    getuser_unicode = win32utils.get_user_name
459
511
 
460
512
elif sys.platform == 'darwin':
461
513
    getcwd = _mac_getcwd
1751
1803
    """
1752
1804
    global _selected_dir_reader
1753
1805
    if _selected_dir_reader is None:
1754
 
        fs_encoding = _fs_enc.upper()
1755
1806
        if sys.platform == "win32" and win32utils.winver == 'Windows NT':
1756
1807
            # Win98 doesn't have unicode apis like FindFirstFileW
1757
1808
            # TODO: We possibly could support Win98 by falling back to the
1763
1814
                _selected_dir_reader = Win32ReadDir()
1764
1815
            except ImportError:
1765
1816
                pass
1766
 
        elif fs_encoding in ('UTF-8', 'US-ASCII', 'ANSI_X3.4-1968'):
1767
 
            # ANSI_X3.4-1968 is a form of ASCII
 
1817
        elif _fs_enc in ('utf-8', 'ascii'):
1768
1818
            try:
1769
1819
                from bzrlib._readdir_pyx import UTF8DirReader
1770
1820
                _selected_dir_reader = UTF8DirReader()
2006
2056
    return get_terminal_encoding()
2007
2057
 
2008
2058
 
 
2059
_message_encoding = None
 
2060
 
 
2061
 
 
2062
def get_message_encoding():
 
2063
    """Return the encoding used for messages
 
2064
 
 
2065
    While the message encoding is a general setting it should usually only be
 
2066
    needed for decoding system error strings such as from OSError instances.
 
2067
    """
 
2068
    global _message_encoding
 
2069
    if _message_encoding is None:
 
2070
        if os.name == "posix":
 
2071
            import locale
 
2072
            # This is a process-global setting that can change, but should in
 
2073
            # general just get set once at process startup then be constant.
 
2074
            _message_encoding = locale.getlocale(locale.LC_MESSAGES)[1]
 
2075
        else:
 
2076
            # On windows want the result of GetACP() which this boils down to.
 
2077
            _message_encoding = get_user_encoding()
 
2078
    return _message_encoding or "ascii"
 
2079
        
 
2080
 
2009
2081
def get_host_name():
2010
2082
    """Return the current unicode host name.
2011
2083
 
2255
2327
 
2256
2328
 
2257
2329
if sys.platform == "win32":
2258
 
    import msvcrt
2259
2330
    def getchar():
 
2331
        import msvcrt
2260
2332
        return msvcrt.getch()
2261
2333
else:
2262
 
    import tty
2263
 
    import termios
2264
2334
    def getchar():
 
2335
        import tty
 
2336
        import termios
2265
2337
        fd = sys.stdin.fileno()
2266
2338
        settings = termios.tcgetattr(fd)
2267
2339
        try:
2316
2388
    if concurrency is None:
2317
2389
        try:
2318
2390
            import multiprocessing
2319
 
        except ImportError:
 
2391
            concurrency = multiprocessing.cpu_count()
 
2392
        except (ImportError, NotImplementedError):
2320
2393
            # multiprocessing is only available on Python >= 2.6
 
2394
            # and multiprocessing.cpu_count() isn't implemented on all
 
2395
            # platforms
2321
2396
            try:
2322
2397
                concurrency = _local_concurrency()
2323
2398
            except (OSError, IOError):
2324
2399
                pass
2325
 
        else:
2326
 
            concurrency = multiprocessing.cpu_count()
2327
2400
    try:
2328
2401
        concurrency = int(concurrency)
2329
2402
    except (TypeError, ValueError):
2391
2464
    open_file = open
2392
2465
 
2393
2466
 
2394
 
def getuser_unicode():
2395
 
    """Return the username as unicode.
2396
 
    """
2397
 
    try:
2398
 
        user_encoding = get_user_encoding()
2399
 
        username = getpass.getuser().decode(user_encoding)
2400
 
    except UnicodeDecodeError:
2401
 
        raise errors.BzrError("Can't decode username as %s." % \
2402
 
                user_encoding)
2403
 
    except ImportError, e:
2404
 
        if sys.platform != 'win32':
2405
 
            raise
2406
 
        if str(e) != 'No module named pwd':
2407
 
            raise
2408
 
        # https://bugs.launchpad.net/bzr/+bug/660174
2409
 
        # getpass.getuser() is unable to return username on Windows
2410
 
        # if there is no USERNAME environment variable set.
2411
 
        # That could be true if bzr is running as a service,
2412
 
        # e.g. running `bzr serve` as a service on Windows.
2413
 
        # We should not fail with traceback in this case.
2414
 
        username = u'UNKNOWN'
2415
 
    return username
2416
 
 
2417
 
 
2418
2467
def available_backup_name(base, exists):
2419
2468
    """Find a non-existing backup file name.
2420
2469
 
2517
2566
    fn = getattr(os, 'fdatasync', getattr(os, 'fsync', None))
2518
2567
    if fn is not None:
2519
2568
        fn(fileno)
 
2569
 
 
2570
 
 
2571
def ensure_empty_directory_exists(path, exception_class):
 
2572
    """Make sure a local directory exists and is empty.
 
2573
    
 
2574
    If it does not exist, it is created.  If it exists and is not empty, an
 
2575
    instance of exception_class is raised.
 
2576
    """
 
2577
    try:
 
2578
        os.mkdir(path)
 
2579
    except OSError, e:
 
2580
        if e.errno != errno.EEXIST:
 
2581
            raise
 
2582
        if os.listdir(path) != []:
 
2583
            raise exception_class(path)
 
2584
 
 
2585
 
 
2586
def is_environment_error(evalue):
 
2587
    """True if exception instance is due to a process environment issue
 
2588
 
 
2589
    This includes OSError and IOError, but also other errors that come from
 
2590
    the operating system or core libraries but are not subclasses of those.
 
2591
    """
 
2592
    if isinstance(evalue, (EnvironmentError, select.error)):
 
2593
        return True
 
2594
    if sys.platform == "win32" and win32utils._is_pywintypes_error(evalue):
 
2595
        return True
 
2596
    return False