mercurial/scmwindows.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Tue, 20 Feb 2024 17:17:54 +0100
changeset 51402 2e10ddbb9faa
parent 51285 9d3721552b6c
child 51863 f4733654f144
permissions -rw-r--r--
phases: check secret presence the right way during discovery There is an official function for this, lets use it. This will prevent the code to break in the future while we refactor the phase code.
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()