/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: Vincent Ladeuil
  • Date: 2012-01-18 14:09:19 UTC
  • mto: This revision was merged to the branch mainline in revision 6468.
  • Revision ID: v.ladeuil+lp@free.fr-20120118140919-rlvdrhpc0nq1lbwi
Change set/remove to require a lock for the branch config files.

This means that tests (or any plugin for that matter) do not requires an
explicit lock on the branch anymore to change a single option. This also
means the optimisation becomes "opt-in" and as such won't be as
spectacular as it may be and/or harder to get right (nothing fails
anymore).

This reduces the diff by ~300 lines.

Code/tests that were updating more than one config option is still taking
a lock to at least avoid some IOs and demonstrate the benefits through
the decreased number of hpss calls.

The duplication between BranchStack and BranchOnlyStack will be removed
once the same sharing is in place for local config files, at which point
the Stack class itself may be able to host the changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
342
342
        raise errors.BadFilenameEncoding(val, _fs_enc)
343
343
 
344
344
 
345
 
def _posix_get_home_dir():
346
 
    """Get the home directory of the current user as a unicode path"""
347
 
    path = posixpath.expanduser("~")
348
 
    try:
349
 
        return path.decode(_fs_enc)
350
 
    except UnicodeDecodeError:
351
 
        raise errors.BadFilenameEncoding(path, _fs_enc)
352
 
 
353
 
 
354
345
def _posix_getuser_unicode():
355
346
    """Get username from environment or password database as unicode"""
356
347
    name = getpass.getuser()
450
441
    return unicodedata.normalize('NFC', os.getcwdu())
451
442
 
452
443
 
453
 
def _rename_wrap_exception(rename_func):
454
 
    """Adds extra information to any exceptions that come from rename().
455
 
 
456
 
    The exception has an updated message and 'old_filename' and 'new_filename'
457
 
    attributes.
458
 
    """
459
 
 
460
 
    def _rename_wrapper(old, new):
461
 
        try:
462
 
            rename_func(old, new)
463
 
        except OSError, e:
464
 
            detailed_error = OSError(e.errno, e.strerror +
465
 
                                " [occurred when renaming '%s' to '%s']" %
466
 
                                (old, new))
467
 
            detailed_error.old_filename = old
468
 
            detailed_error.new_filename = new
469
 
            raise detailed_error
470
 
 
471
 
    return _rename_wrapper
472
 
 
473
 
# Default rename wraps os.rename()
474
 
rename = _rename_wrap_exception(os.rename)
475
 
 
476
444
# Default is to just use the python builtins, but these can be rebound on
477
445
# particular platforms.
478
446
abspath = _posix_abspath
480
448
pathjoin = os.path.join
481
449
normpath = _posix_normpath
482
450
path_from_environ = _posix_path_from_environ
483
 
_get_home_dir = _posix_get_home_dir
484
451
getuser_unicode = _posix_getuser_unicode
485
452
getcwd = os.getcwdu
 
453
rename = os.rename
486
454
dirname = os.path.dirname
487
455
basename = os.path.basename
488
456
split = os.path.split
510
478
    normpath = _win32_normpath
511
479
    getcwd = _win32_getcwd
512
480
    mkdtemp = _win32_mkdtemp
513
 
    rename = _rename_wrap_exception(_win32_rename)
 
481
    rename = _win32_rename
514
482
    try:
515
483
        from bzrlib import _walkdirs_win32
516
484
    except ImportError:
543
511
    if f is not None:
544
512
        get_unicode_argv = f
545
513
    path_from_environ = win32utils.get_environ_unicode
546
 
    _get_home_dir = win32utils.get_home_location
547
514
    getuser_unicode = win32utils.get_user_name
548
515
 
549
516
elif sys.platform == 'darwin':
2086
2053
# data at once.
2087
2054
MAX_SOCKET_CHUNK = 64 * 1024
2088
2055
 
2089
 
_end_of_stream_errors = [errno.ECONNRESET, errno.EPIPE, errno.EINVAL]
 
2056
_end_of_stream_errors = [errno.ECONNRESET]
2090
2057
for _eno in ['WSAECONNRESET', 'WSAECONNABORTED']:
2091
2058
    _eno = getattr(errno, _eno, None)
2092
2059
    if _eno is not None:
2158
2125
    while sent_total < byte_count:
2159
2126
        try:
2160
2127
            sent = sock.send(buffer(bytes, sent_total, MAX_SOCKET_CHUNK))
2161
 
        except (socket.error, IOError), e:
2162
 
            if e.args[0] in _end_of_stream_errors:
2163
 
                raise errors.ConnectionReset(
2164
 
                    "Error trying to write to socket", e)
 
2128
        except socket.error, e:
2165
2129
            if e.args[0] != errno.EINTR:
2166
2130
                raise
2167
2131
        else:
2168
 
            if sent == 0:
2169
 
                raise errors.ConnectionReset('Sending to %s returned 0 bytes'
2170
 
                                             % (sock,))
2171
2132
            sent_total += sent
2172
 
            if report_activity is not None:
2173
 
                report_activity(sent, 'write')
 
2133
            report_activity(sent, 'write')
2174
2134
 
2175
2135
 
2176
2136
def connect_socket(address):
2502
2462
    :param name: The base name of the executable.
2503
2463
    :return: The path to the executable found or None.
2504
2464
    """
 
2465
    path = os.environ.get('PATH')
 
2466
    if path is None:
 
2467
        return None
 
2468
    path = path.split(os.pathsep)
2505
2469
    if sys.platform == 'win32':
2506
2470
        exts = os.environ.get('PATHEXT', '').split(os.pathsep)
2507
2471
        exts = [ext.lower() for ext in exts]
2513
2477
            exts = [ext]
2514
2478
    else:
2515
2479
        exts = ['']
2516
 
    path = os.environ.get('PATH')
2517
 
    if path is not None:
2518
 
        path = path.split(os.pathsep)
2519
 
        for ext in exts:
2520
 
            for d in path:
2521
 
                f = os.path.join(d, name) + ext
2522
 
                if os.access(f, os.X_OK):
2523
 
                    return f
2524
 
    if sys.platform == 'win32':
2525
 
        app_path = win32utils.get_app_path(name)
2526
 
        if app_path != name:
2527
 
            return app_path
 
2480
    for ext in exts:
 
2481
        for d in path:
 
2482
            f = os.path.join(d, name) + ext
 
2483
            if os.access(f, os.X_OK):
 
2484
                return f
2528
2485
    return None
2529
2486
 
2530
2487
 
2554
2511
else:
2555
2512
    is_local_pid_dead = _posix_is_local_pid_dead
2556
2513
 
2557
 
_maybe_ignored = ['EAGAIN', 'EINTR', 'ENOTSUP', 'EOPNOTSUPP', 'EACCES']
2558
 
_fdatasync_ignored = [getattr(errno, name) for name in _maybe_ignored
2559
 
                      if getattr(errno, name, None) is not None]
2560
 
 
2561
2514
 
2562
2515
def fdatasync(fileno):
2563
2516
    """Flush file contents to disk if possible.
2567
2520
    """
2568
2521
    fn = getattr(os, 'fdatasync', getattr(os, 'fsync', None))
2569
2522
    if fn is not None:
2570
 
        try:
2571
 
            fn(fileno)
2572
 
        except IOError, e:
2573
 
            # See bug #1075108, on some platforms fdatasync exists, but can
2574
 
            # raise ENOTSUP. However, we are calling fdatasync to be helpful
2575
 
            # and reduce the chance of corruption-on-powerloss situations. It
2576
 
            # is not a mandatory call, so it is ok to suppress failures.
2577
 
            trace.mutter("ignoring error calling fdatasync: %s" % (e,))
2578
 
            if getattr(e, 'errno', None) not in _fdatasync_ignored:
2579
 
                raise
 
2523
        fn(fileno)
2580
2524
 
2581
2525
 
2582
2526
def ensure_empty_directory_exists(path, exception_class):