/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 breezy/osutils.py

Support user.signingkey configuration variable in .git/config.

Merged from https://code.launchpad.net/~jelmer/brz/local-git-key/+merge/381000

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
50
52
from breezy.i18n import gettext
51
53
""")
52
54
 
 
55
from .sixish import (
 
56
    PY3,
 
57
    text_type,
 
58
    )
 
59
 
53
60
from hashlib import (
54
61
    md5,
55
62
    sha1 as sha,
84
91
 
85
92
 
86
93
def get_unicode_argv():
87
 
    return sys.argv[1:]
 
94
    if PY3:
 
95
        return sys.argv[1:]
 
96
    try:
 
97
        user_encoding = get_user_encoding()
 
98
        return [a.decode(user_encoding) for a in sys.argv[1:]]
 
99
    except UnicodeDecodeError:
 
100
        raise errors.BzrError(gettext("Parameter {0!r} encoding is unsupported by {1} "
 
101
                                      "application locale.").format(a, user_encoding))
88
102
 
89
103
 
90
104
def make_readonly(filename):
317
331
    Note that posix systems use arbitrary byte strings for filesystem objects,
318
332
    so a path that raises BadFilenameEncoding here may still be accessible.
319
333
    """
320
 
    return os.environ.get(key, None)
 
334
    val = os.environ.get(key, None)
 
335
    if PY3 or val is None:
 
336
        return val
 
337
    try:
 
338
        return val.decode(_fs_enc)
 
339
    except UnicodeDecodeError:
 
340
        # GZ 2011-12-12:Ideally want to include `key` in the exception message
 
341
        raise errors.BadFilenameEncoding(val, _fs_enc)
321
342
 
322
343
 
323
344
def _posix_get_home_dir():
333
354
 
334
355
def _posix_getuser_unicode():
335
356
    """Get username from environment or password database as unicode"""
336
 
    return getpass.getuser()
 
357
    name = getpass.getuser()
 
358
    if PY3:
 
359
        return name
 
360
    user_encoding = get_user_encoding()
 
361
    try:
 
362
        return name.decode(user_encoding)
 
363
    except UnicodeDecodeError:
 
364
        raise errors.BzrError("Encoding of username %r is unsupported by %s "
 
365
                              "application locale." % (name, user_encoding))
337
366
 
338
367
 
339
368
def _win32_fixdrive(path):
418
447
    return _rename_wrapper
419
448
 
420
449
 
421
 
_getcwd = os.getcwd
 
450
if sys.version_info > (3,):
 
451
    _getcwd = os.getcwd
 
452
else:
 
453
    _getcwd = os.getcwdu
422
454
 
423
455
 
424
456
# Default rename wraps os.rename()
706
738
 
707
739
# GZ 2017-09-16: Makes sense in general for hexdigest() result to be text, but
708
740
# used as bytes through most interfaces so encode with this wrapper.
709
 
def _hexdigest(hashobj):
710
 
    return hashobj.hexdigest().encode()
 
741
if PY3:
 
742
    def _hexdigest(hashobj):
 
743
        return hashobj.hexdigest().encode()
 
744
else:
 
745
    def _hexdigest(hashobj):
 
746
        return hashobj.hexdigest()
711
747
 
712
748
 
713
749
def sha_file(f):
859
895
    (date_fmt, tt, offset_str) = \
860
896
        _format_date(t, offset, timezone, date_fmt, show_offset)
861
897
    date_str = time.strftime(date_fmt, tt)
862
 
    if not isinstance(date_str, str):
 
898
    if not isinstance(date_str, text_type):
863
899
        date_str = date_str.decode(get_user_encoding(), 'replace')
864
900
    return date_str + offset_str
865
901
 
976
1012
    """
977
1013
    s = ''
978
1014
    for raw_byte in rand_bytes(num):
979
 
        s += ALNUM[raw_byte % 36]
 
1015
        if not PY3:
 
1016
            s += ALNUM[ord(raw_byte) % 36]
 
1017
        else:
 
1018
            s += ALNUM[raw_byte % 36]
980
1019
    return s
981
1020
 
982
1021
 
1283
1322
 
1284
1323
    abs_base = abspath(base)
1285
1324
    current = abs_base
 
1325
    _listdir = os.listdir
1286
1326
 
1287
1327
    # use an explicit iterator so we can easily consume the rest on early exit.
1288
1328
    bit_iter = iter(rel.split('/'))
1289
1329
    for bit in bit_iter:
1290
1330
        lbit = bit.lower()
1291
1331
        try:
1292
 
            next_entries = scandir(current)
 
1332
            next_entries = _listdir(current)
1293
1333
        except OSError:  # enoent, eperm, etc
1294
1334
            # We can't find this in the filesystem, so just append the
1295
1335
            # remaining bits.
1296
1336
            current = pathjoin(current, bit, *list(bit_iter))
1297
1337
            break
1298
 
        for entry in next_entries:
1299
 
            if lbit == entry.name.lower():
1300
 
                current = entry.path
 
1338
        for look in next_entries:
 
1339
            if lbit == look.lower():
 
1340
                current = pathjoin(current, look)
1301
1341
                break
1302
1342
        else:
1303
1343
            # got to the end, nothing matched, so we just return the
1336
1376
    Otherwise it is decoded from the the filesystem's encoding. If decoding
1337
1377
    fails, a errors.BadFilenameEncoding exception is raised.
1338
1378
    """
1339
 
    if isinstance(filename, str):
 
1379
    if isinstance(filename, text_type):
1340
1380
        return filename
1341
1381
    try:
1342
1382
        return filename.decode(_fs_enc)
1351
1391
    Otherwise it is decoded from utf-8. If decoding fails, the exception is
1352
1392
    wrapped in a BzrBadParameterNotUnicode exception.
1353
1393
    """
1354
 
    if isinstance(unicode_or_utf8_string, str):
 
1394
    if isinstance(unicode_or_utf8_string, text_type):
1355
1395
        return unicode_or_utf8_string
1356
1396
    try:
1357
1397
        return unicode_or_utf8_string.decode('utf8')
1690
1730
        if orig_val is not None:
1691
1731
            del os.environ[env_variable]
1692
1732
    else:
 
1733
        if not PY3 and isinstance(value, text_type):
 
1734
            value = value.encode(get_user_encoding())
1693
1735
        os.environ[env_variable] = value
1694
1736
    return orig_val
1695
1737
 
1711
1753
_WIN32_ERROR_DIRECTORY = 267  # Similar to errno.ENOTDIR
1712
1754
 
1713
1755
 
1714
 
try:
1715
 
    scandir = os.scandir
1716
 
except AttributeError:  # Python < 3
1717
 
    lazy_import(globals(), """\
1718
 
from scandir import scandir
1719
 
""")
1720
 
 
1721
 
 
1722
1756
def _is_error_enotdir(e):
1723
1757
    """Check if this exception represents ENOTDIR.
1724
1758
 
1778
1812
    # depending on top and prefix - i.e. ./foo and foo as a pair leads to
1779
1813
    # potentially confusing output. We should make this more robust - but
1780
1814
    # not at a speed cost. RBC 20060731
 
1815
    _lstat = os.lstat
1781
1816
    _directory = _directory_kind
 
1817
    _listdir = os.listdir
 
1818
    _kind_from_mode = file_kind_from_stat_mode
1782
1819
    pending = [(safe_unicode(prefix), "", _directory, None, safe_unicode(top))]
1783
1820
    while pending:
1784
1821
        # 0 - relpath, 1- basename, 2- kind, 3- stat, 4-toppath
1790
1827
        top_slash = top + u'/'
1791
1828
 
1792
1829
        dirblock = []
 
1830
        append = dirblock.append
1793
1831
        try:
1794
 
            for entry in scandir(top):
1795
 
                name = decode_filename(entry.name)
1796
 
                statvalue = entry.stat(follow_symlinks=False)
1797
 
                kind = file_kind_from_stat_mode(statvalue.st_mode)
1798
 
                dirblock.append((relprefix + name, name, kind, statvalue, entry.path))
 
1832
            names = sorted(map(decode_filename, _listdir(top)))
1799
1833
        except OSError as e:
1800
1834
            if not _is_error_enotdir(e):
1801
1835
                raise
1802
 
        except UnicodeDecodeError as e:
1803
 
            raise errors.BadFilenameEncoding(e.object, _fs_enc)
1804
 
        dirblock.sort()
 
1836
        else:
 
1837
            for name in names:
 
1838
                abspath = top_slash + name
 
1839
                statvalue = _lstat(abspath)
 
1840
                kind = _kind_from_mode(statvalue.st_mode)
 
1841
                append((relprefix + name, name, kind, statvalue, abspath))
1805
1842
        yield (relroot, top), dirblock
1806
1843
 
1807
1844
        # push the user specified dirs from dirblock
1917
1954
        def _fs_decode(s): return s.decode(_fs_enc)
1918
1955
 
1919
1956
        def _fs_encode(s): return s.encode(_fs_enc)
 
1957
        _lstat = os.lstat
 
1958
        _listdir = os.listdir
 
1959
        _kind_from_mode = file_kind_from_stat_mode
1920
1960
 
1921
1961
        if prefix:
1922
1962
            relprefix = prefix + b'/'
1926
1966
 
1927
1967
        dirblock = []
1928
1968
        append = dirblock.append
1929
 
        for entry in scandir(safe_utf8(top)):
 
1969
        for name_native in _listdir(top.encode('utf-8')):
1930
1970
            try:
1931
 
                name = _fs_decode(entry.name)
 
1971
                name = _fs_decode(name_native)
1932
1972
            except UnicodeDecodeError:
1933
1973
                raise errors.BadFilenameEncoding(
1934
 
                    relprefix + entry.name, _fs_enc)
 
1974
                    relprefix + name_native, _fs_enc)
 
1975
            name_utf8 = _utf8_encode(name)[0]
1935
1976
            abspath = top_slash + name
1936
 
            name_utf8 = _utf8_encode(name)[0]
1937
 
            statvalue = entry.stat(follow_symlinks=False)
1938
 
            kind = file_kind_from_stat_mode(statvalue.st_mode)
 
1977
            statvalue = _lstat(abspath)
 
1978
            kind = _kind_from_mode(statvalue.st_mode)
1939
1979
            append((relprefix + name_utf8, name_utf8, kind, statvalue, abspath))
1940
1980
        return sorted(dirblock)
1941
1981
 
2086
2126
        return win32utils.get_host_name()
2087
2127
    else:
2088
2128
        import socket
2089
 
        return socket.gethostname()
 
2129
        if PY3:
 
2130
            return socket.gethostname()
 
2131
        return socket.gethostname().decode(get_user_encoding())
2090
2132
 
2091
2133
 
2092
2134
# We must not read/write any more than 64k at a time from/to a socket so we
2671
2713
    return _FILESYSTEM_FINDER.find(path)
2672
2714
 
2673
2715
 
2674
 
perf_counter = time.perf_counter
 
2716
if PY3:
 
2717
    perf_counter = time.perf_counter
 
2718
else:
 
2719
    perf_counter = time.clock