mercurial/scmwindows.py
author Anton Shestakov <av6@dwimlabs.net>
Sun, 14 Jan 2024 16:03:08 -0300
branchstable
changeset 51161 c7edfccfc11f
parent 49904 7a80a614c9e5
child 51302 9d3721552b6c
permissions -rw-r--r--
tests: don't use "status" operand of dd in test-censor.t (issue6858) Some implementations don't have this operand, let's just direct stderr into /dev/null, that's pretty cross-platform. Also specify bs=512 (the default for me), because the default might be different on different systems. Other uses of dd in the tests do specify it, so this is more consistent.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
     1
import os
49904
7a80a614c9e5 windows: drop some py2 registry module importing
Matt Harbison <matt_harbison@yahoo.com>
parents: 49903
diff changeset
     2
import winreg  # pytype: disable=import-error
27481
029f02757c20 scmwindows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26625
diff changeset
     3
49903
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 49065
diff changeset
     4
from typing import (
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 49065
diff changeset
     5
    List,
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 49065
diff changeset
     6
    Tuple,
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 49065
diff changeset
     7
)
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 49065
diff changeset
     8
27481
029f02757c20 scmwindows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26625
diff changeset
     9
from . import (
30642
344e68882cd3 py3: replace os.environ with encoding.environ (part 4 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30617
diff changeset
    10
    encoding,
30617
d623cc6b3742 py3: replace os.pathsep with pycompat.ospathsep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30327
diff changeset
    11
    pycompat,
27481
029f02757c20 scmwindows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26625
diff changeset
    12
    util,
30322
4b1af1c867fa scmutil: move util.termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 29772
diff changeset
    13
    win32,
27481
029f02757c20 scmwindows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26625
diff changeset
    14
)
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    15
49903
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 49065
diff changeset
    16
if pycompat.TYPE_CHECKING:
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 49065
diff changeset
    17
    from . import ui as uimod
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 49065
diff changeset
    18
32078
bf5e13e38390 pager: use less as a fallback on Unix
Yuya Nishihara <yuya@tcha.org>
parents: 30642
diff changeset
    19
# MS-DOS 'more' is the only pager available by default on Windows.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
    20
fallbackpager = b'more'
32078
bf5e13e38390 pager: use less as a fallback on Unix
Yuya Nishihara <yuya@tcha.org>
parents: 30642
diff changeset
    21
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 37098
diff changeset
    22
49903
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 49065
diff changeset
    23
def systemrcpath() -> List[bytes]:
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    24
    '''return default os-specific hgrc search path'''
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    25
    rcpath = []
37098
e24802ea8dbd rcutil: directly call win32.executablepath()
Yuya Nishihara <yuya@tcha.org>
parents: 32248
diff changeset
    26
    filename = win32.executablepath()
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    27
    # Use mercurial.ini found in directory with hg.exe
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
    28
    progrc = os.path.join(os.path.dirname(filename), b'mercurial.ini')
26625
adae8928fe09 windows: read all global config files, not just the first (issue4491) (BC)
Mads Kiilerich <madski@unity3d.com>
parents: 22583
diff changeset
    29
    rcpath.append(progrc)
43931
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43930
diff changeset
    30
49903
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 49065
diff changeset
    31
    def _processdir(progrcd: bytes) -> None:
43931
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43930
diff changeset
    32
        if os.path.isdir(progrcd):
45843
9ac96b9fa76e config: read system hgrc in lexicographical order
Martin von Zweigbergk <martinvonz@google.com>
parents: 43956
diff changeset
    33
            for f, kind in sorted(util.listdir(progrcd)):
43931
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43930
diff changeset
    34
                if f.endswith(b'.rc'):
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43930
diff changeset
    35
                    rcpath.append(os.path.join(progrcd, f))
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43930
diff changeset
    36
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    37
    # Use hgrc.d found in directory with hg.exe
43931
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43930
diff changeset
    38
    _processdir(os.path.join(os.path.dirname(filename), b'hgrc.d'))
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43930
diff changeset
    39
43956
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43931
diff changeset
    40
    # treat a PROGRAMDATA directory as equivalent to /etc/mercurial
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43931
diff changeset
    41
    programdata = encoding.environ.get(b'PROGRAMDATA')
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43931
diff changeset
    42
    if programdata:
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43931
diff changeset
    43
        programdata = os.path.join(programdata, b'Mercurial')
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43931
diff changeset
    44
        _processdir(os.path.join(programdata, b'hgrc.d'))
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43931
diff changeset
    45
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43931
diff changeset
    46
        ini = os.path.join(programdata, b'mercurial.ini')
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43931
diff changeset
    47
        if os.path.isfile(ini):
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43931
diff changeset
    48
            rcpath.append(ini)
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43931
diff changeset
    49
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43931
diff changeset
    50
        ini = os.path.join(programdata, b'hgrc')
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43931
diff changeset
    51
        if os.path.isfile(ini):
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43931
diff changeset
    52
            rcpath.append(ini)
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43931
diff changeset
    53
43929
9a3ac902d597 windows: clarify a comment about the hgrc search path
Matt Harbison <matt_harbison@yahoo.com>
parents: 43811
diff changeset
    54
    # next look for a system rcpath in the registry
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 37098
diff changeset
    55
    value = util.lookupreg(
49065
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48966
diff changeset
    56
        # pytype: disable=module-attr
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48966
diff changeset
    57
        b'SOFTWARE\\Mercurial',
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48966
diff changeset
    58
        None,
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48966
diff changeset
    59
        winreg.HKEY_LOCAL_MACHINE
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48966
diff changeset
    60
        # pytype: enable=module-attr
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 37098
diff changeset
    61
    )
43930
fa3835a15a17 windows: don't return early from building the hgrc search path
Matt Harbison <matt_harbison@yahoo.com>
parents: 43929
diff changeset
    62
    if value and isinstance(value, bytes):
fa3835a15a17 windows: don't return early from building the hgrc search path
Matt Harbison <matt_harbison@yahoo.com>
parents: 43929
diff changeset
    63
        value = util.localpath(value)
fa3835a15a17 windows: don't return early from building the hgrc search path
Matt Harbison <matt_harbison@yahoo.com>
parents: 43929
diff changeset
    64
        for p in value.split(pycompat.ospathsep):
fa3835a15a17 windows: don't return early from building the hgrc search path
Matt Harbison <matt_harbison@yahoo.com>
parents: 43929
diff changeset
    65
            if p.lower().endswith(b'mercurial.ini'):
fa3835a15a17 windows: don't return early from building the hgrc search path
Matt Harbison <matt_harbison@yahoo.com>
parents: 43929
diff changeset
    66
                rcpath.append(p)
43931
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43930
diff changeset
    67
            else:
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43930
diff changeset
    68
                _processdir(p)
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    69
    return rcpath
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    70
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 37098
diff changeset
    71
49903
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 49065
diff changeset
    72
def userrcpath() -> List[bytes]:
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    73
    '''return os-specific hgrc search path to the user dir'''
46094
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    74
    home = _legacy_expanduser(b'~')
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
    75
    path = [os.path.join(home, b'mercurial.ini'), os.path.join(home, b'.hgrc')]
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
    76
    userprofile = encoding.environ.get(b'USERPROFILE')
22583
23c995ed466b config: don't read the same config file twice
Mads Kiilerich <madski@unity3d.com>
parents: 18712
diff changeset
    77
    if userprofile and userprofile != home:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
    78
        path.append(os.path.join(userprofile, b'mercurial.ini'))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
    79
        path.append(os.path.join(userprofile, b'.hgrc'))
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    80
    return path
30322
4b1af1c867fa scmutil: move util.termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 29772
diff changeset
    81
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 37098
diff changeset
    82
49903
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 49065
diff changeset
    83
def _legacy_expanduser(path: bytes) -> bytes:
46094
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    84
    """Expand ~ and ~user constructs in the pre 3.8 style"""
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    85
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    86
    # Python 3.8+ changed the expansion of '~' from HOME to USERPROFILE.  See
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    87
    # https://bugs.python.org/issue36264.  It also seems to capitalize the drive
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    88
    # letter, as though it was processed through os.path.realpath().
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    89
    if not path.startswith(b'~'):
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    90
        return path
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    91
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    92
    i, n = 1, len(path)
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    93
    while i < n and path[i] not in b'\\/':
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    94
        i += 1
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    95
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    96
    if b'HOME' in encoding.environ:
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    97
        userhome = encoding.environ[b'HOME']
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    98
    elif b'USERPROFILE' in encoding.environ:
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
    99
        userhome = encoding.environ[b'USERPROFILE']
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
   100
    elif b'HOMEPATH' not in encoding.environ:
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
   101
        return path
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
   102
    else:
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
   103
        try:
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
   104
            drive = encoding.environ[b'HOMEDRIVE']
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
   105
        except KeyError:
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
   106
            drive = b''
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
   107
        userhome = os.path.join(drive, encoding.environ[b'HOMEPATH'])
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
   108
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
   109
    if i != 1:  # ~user
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
   110
        userhome = os.path.join(os.path.dirname(userhome), path[1:i])
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
   111
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
   112
    return userhome + path[i:]
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
   113
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45843
diff changeset
   114
49903
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 49065
diff changeset
   115
def termsize(ui: "uimod.ui") -> Tuple[int, int]:
30327
365812902904 scmutil: extend termwidth() to return terminal height, renamed to termsize()
Yuya Nishihara <yuya@tcha.org>
parents: 30323
diff changeset
   116
    return win32.termsize()