mercurial/scmwindows.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Mon, 25 Mar 2024 16:27:48 +0000
changeset 51538 e4eeb9fedfe3
parent 51285 9d3721552b6c
permissions -rw-r--r--
branching: merge stable into default
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
49809
7a80a614c9e5 windows: drop some py2 registry module importing
Matt Harbison <matt_harbison@yahoo.com>
parents: 49808
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
49808
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 48986
diff changeset
     4
from typing import (
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 48986
diff changeset
     5
    List,
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49809
diff changeset
     6
    TYPE_CHECKING,
49808
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 48986
diff changeset
     7
    Tuple,
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 48986
diff changeset
     8
)
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 48986
diff changeset
     9
27481
029f02757c20 scmwindows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26625
diff changeset
    10
from . import (
30637
344e68882cd3 py3: replace os.environ with encoding.environ (part 4 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30612
diff changeset
    11
    encoding,
30612
d623cc6b3742 py3: replace os.pathsep with pycompat.ospathsep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30314
diff changeset
    12
    pycompat,
27481
029f02757c20 scmwindows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26625
diff changeset
    13
    util,
30309
4b1af1c867fa scmutil: move util.termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 29760
diff changeset
    14
    win32,
27481
029f02757c20 scmwindows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26625
diff changeset
    15
)
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    16
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49809
diff changeset
    17
if TYPE_CHECKING:
49808
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 48986
diff changeset
    18
    from . import ui as uimod
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 48986
diff changeset
    19
32078
bf5e13e38390 pager: use less as a fallback on Unix
Yuya Nishihara <yuya@tcha.org>
parents: 30637
diff changeset
    20
# 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
    21
fallbackpager = b'more'
32078
bf5e13e38390 pager: use less as a fallback on Unix
Yuya Nishihara <yuya@tcha.org>
parents: 30637
diff changeset
    22
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 37095
diff changeset
    23
49808
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 48986
diff changeset
    24
def systemrcpath() -> List[bytes]:
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    25
    '''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
    26
    rcpath = []
37095
e24802ea8dbd rcutil: directly call win32.executablepath()
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
    27
    filename = win32.executablepath()
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    28
    # 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
    29
    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
    30
    rcpath.append(progrc)
43925
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43924
diff changeset
    31
49808
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 48986
diff changeset
    32
    def _processdir(progrcd: bytes) -> None:
43925
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43924
diff changeset
    33
        if os.path.isdir(progrcd):
45824
9ac96b9fa76e config: read system hgrc in lexicographical order
Martin von Zweigbergk <martinvonz@google.com>
parents: 43951
diff changeset
    34
            for f, kind in sorted(util.listdir(progrcd)):
43925
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43924
diff changeset
    35
                if f.endswith(b'.rc'):
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43924
diff changeset
    36
                    rcpath.append(os.path.join(progrcd, f))
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43924
diff changeset
    37
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    38
    # Use hgrc.d found in directory with hg.exe
43925
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43924
diff changeset
    39
    _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: 43924
diff changeset
    40
43951
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43925
diff changeset
    41
    # 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: 43925
diff changeset
    42
    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: 43925
diff changeset
    43
    if programdata:
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43925
diff changeset
    44
        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: 43925
diff changeset
    45
        _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: 43925
diff changeset
    46
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43925
diff changeset
    47
        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: 43925
diff changeset
    48
        if os.path.isfile(ini):
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43925
diff changeset
    49
            rcpath.append(ini)
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43925
diff changeset
    50
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43925
diff changeset
    51
        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: 43925
diff changeset
    52
        if os.path.isfile(ini):
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43925
diff changeset
    53
            rcpath.append(ini)
1ccf340acf14 windows: add a global equivalent to /etc/mercurial for *.rc processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 43925
diff changeset
    54
43923
9a3ac902d597 windows: clarify a comment about the hgrc search path
Matt Harbison <matt_harbison@yahoo.com>
parents: 43793
diff changeset
    55
    # 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: 37095
diff changeset
    56
    value = util.lookupreg(
48986
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48875
diff changeset
    57
        # pytype: disable=module-attr
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48875
diff changeset
    58
        b'SOFTWARE\\Mercurial',
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48875
diff changeset
    59
        None,
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48875
diff changeset
    60
        winreg.HKEY_LOCAL_MACHINE
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48875
diff changeset
    61
        # pytype: enable=module-attr
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 37095
diff changeset
    62
    )
43924
fa3835a15a17 windows: don't return early from building the hgrc search path
Matt Harbison <matt_harbison@yahoo.com>
parents: 43923
diff changeset
    63
    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: 43923
diff changeset
    64
        value = util.localpath(value)
fa3835a15a17 windows: don't return early from building the hgrc search path
Matt Harbison <matt_harbison@yahoo.com>
parents: 43923
diff changeset
    65
        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: 43923
diff changeset
    66
            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: 43923
diff changeset
    67
                rcpath.append(p)
43925
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43924
diff changeset
    68
            else:
7929bb58146f windows: factor the hgrc directory scan into a function
Matt Harbison <matt_harbison@yahoo.com>
parents: 43924
diff changeset
    69
                _processdir(p)
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    70
    return rcpath
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    71
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 37095
diff changeset
    72
49808
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 48986
diff changeset
    73
def userrcpath() -> List[bytes]:
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
    74
    '''return os-specific hgrc search path to the user dir'''
46093
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
    75
    home = _legacy_expanduser(b'~')
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
    76
    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
    77
    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
    78
    if userprofile and userprofile != home:
43077
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'mercurial.ini'))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
    80
        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
    81
    return path
30309
4b1af1c867fa scmutil: move util.termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 29760
diff changeset
    82
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 37095
diff changeset
    83
49808
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 48986
diff changeset
    84
def _legacy_expanduser(path: bytes) -> bytes:
46093
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
    85
    """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: 45824
diff changeset
    86
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
    87
    # 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: 45824
diff changeset
    88
    # 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: 45824
diff changeset
    89
    # 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: 45824
diff changeset
    90
    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: 45824
diff changeset
    91
        return path
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
    92
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
    93
    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: 45824
diff changeset
    94
    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: 45824
diff changeset
    95
        i += 1
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
    96
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
    97
    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: 45824
diff changeset
    98
        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: 45824
diff changeset
    99
    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: 45824
diff changeset
   100
        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: 45824
diff changeset
   101
    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: 45824
diff changeset
   102
        return path
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
   103
    else:
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
   104
        try:
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
   105
            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: 45824
diff changeset
   106
        except KeyError:
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
   107
            drive = b''
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
   108
        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: 45824
diff changeset
   109
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
   110
    if i != 1:  # ~user
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
   111
        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: 45824
diff changeset
   112
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
   113
    return userhome + path[i:]
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
   114
224af78021de windows: continue looking at `%HOME%` for user config files with py3.8+
Matt Harbison <matt_harbison@yahoo.com>
parents: 45824
diff changeset
   115
49808
7a4143428db7 typing: add type hints to the platform specific scm modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 48986
diff changeset
   116
def termsize(ui: "uimod.ui") -> Tuple[int, int]:
30314
365812902904 scmutil: extend termwidth() to return terminal height, renamed to termsize()
Yuya Nishihara <yuya@tcha.org>
parents: 30310
diff changeset
   117
    return win32.termsize()