mercurial/windows.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Tue, 10 Oct 2023 11:24:37 +0200
changeset 51064 47d43efda8b7
parent 50952 18c8c18993f0
child 51302 9d3721552b6c
permissions -rw-r--r--
revlog: remove legacy usage of `_withsparseread` All core code is now getting the setting from the DeltaConfig object.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8226
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     1
# windows.py - Windows utility function implementations for Mercurial
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     2
#
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 45957
diff changeset
     3
#  Copyright 2005-2009 Olivia Mackall <olivia@selenic.com> and others
8226
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     4
#
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9594
diff changeset
     6
# GNU General Public License version 2 or any later version.
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
8421
b6d0fa8c7685 posixfile: remove posixfile_nt and fix import bug in windows.py
Sune Foldager <cryo@cyanite.org>
parents: 8364
diff changeset
     8
27360
6daa795ed32f windows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26375
diff changeset
     9
import errno
43910
1b26cb044097 windows: if username(uid=None) is loaded, just use getpass
Augie Fackler <augie@google.com>
parents: 43807
diff changeset
    10
import getpass
49325
a75b530cfc29 typing: add a missing suppression directive for `msvcrt`
Matt Harbison <matt_harbison@yahoo.com>
parents: 49324
diff changeset
    11
import msvcrt  # pytype: disable=import-error
27360
6daa795ed32f windows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26375
diff changeset
    12
import os
6daa795ed32f windows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26375
diff changeset
    13
import re
6daa795ed32f windows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26375
diff changeset
    14
import stat
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
    15
import string
27360
6daa795ed32f windows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26375
diff changeset
    16
import sys
49913
3fd5824f1177 typing: attempt to remove @overloads in the platform module for stdlib methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 49912
diff changeset
    17
import typing
49324
6b39c7265935 windows: drop some py2 compatibility code
Matt Harbison <matt_harbison@yahoo.com>
parents: 49323
diff changeset
    18
import winreg  # pytype: disable=import-error
27360
6daa795ed32f windows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26375
diff changeset
    19
49888
8147abc05794 pytype: stop excluding mercurial/ui.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49426
diff changeset
    20
from typing import (
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
    21
    AnyStr,
49888
8147abc05794 pytype: stop excluding mercurial/ui.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49426
diff changeset
    22
    BinaryIO,
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
    23
    Iterable,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
    24
    Iterator,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
    25
    List,
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
    26
    Mapping,
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
    27
    NoReturn,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
    28
    Optional,
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
    29
    Pattern,
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
    30
    Sequence,
49913
3fd5824f1177 typing: attempt to remove @overloads in the platform module for stdlib methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 49912
diff changeset
    31
    Tuple,
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
    32
    Union,
49888
8147abc05794 pytype: stop excluding mercurial/ui.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49426
diff changeset
    33
)
8147abc05794 pytype: stop excluding mercurial/ui.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49426
diff changeset
    34
27360
6daa795ed32f windows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26375
diff changeset
    35
from .i18n import _
6daa795ed32f windows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26375
diff changeset
    36
from . import (
6daa795ed32f windows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26375
diff changeset
    37
    encoding,
33649
739cc0f9cbb4 ssh: ban any username@host or host that starts with - (SEC)
Augie Fackler <augie@google.com>
parents: 32706
diff changeset
    38
    error,
32406
a9c71d578a1c osutil: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 32331
diff changeset
    39
    policy,
30617
d623cc6b3742 py3: replace os.pathsep with pycompat.ospathsep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30483
diff changeset
    40
    pycompat,
49888
8147abc05794 pytype: stop excluding mercurial/ui.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49426
diff changeset
    41
    typelib,
27436
912255f8f087 windows: correct the import of win32
Matt Harbison <matt_harbison@yahoo.com>
parents: 27360
diff changeset
    42
    win32,
27360
6daa795ed32f windows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26375
diff changeset
    43
)
6daa795ed32f windows: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26375
diff changeset
    44
29772
3df9f780c90e py3: conditionalize _winreg import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29530
diff changeset
    45
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
    46
osutil = policy.importmod('osutil')
32406
a9c71d578a1c osutil: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 32331
diff changeset
    47
35517
c4caf530b1c7 util: add a function to show the mount point of the filesystem
Matt Harbison <matt_harbison@yahoo.com>
parents: 35514
diff changeset
    48
getfsmountpoint = win32.getvolumename
35514
2062f7c2ac83 win32: implement util.getfstype()
Matt Harbison <matt_harbison@yahoo.com>
parents: 35513
diff changeset
    49
getfstype = win32.getfstype
15016
871c77e78f5d windows: fix pyflakes warning on unused imports
Matt Mackall <mpm@selenic.com>
parents: 15011
diff changeset
    50
getuser = win32.getuser
871c77e78f5d windows: fix pyflakes warning on unused imports
Matt Mackall <mpm@selenic.com>
parents: 15011
diff changeset
    51
hidewindow = win32.hidewindow
871c77e78f5d windows: fix pyflakes warning on unused imports
Matt Mackall <mpm@selenic.com>
parents: 15011
diff changeset
    52
makedir = win32.makedir
871c77e78f5d windows: fix pyflakes warning on unused imports
Matt Mackall <mpm@selenic.com>
parents: 15011
diff changeset
    53
nlinks = win32.nlinks
871c77e78f5d windows: fix pyflakes warning on unused imports
Matt Mackall <mpm@selenic.com>
parents: 15011
diff changeset
    54
oslink = win32.oslink
871c77e78f5d windows: fix pyflakes warning on unused imports
Matt Mackall <mpm@selenic.com>
parents: 15011
diff changeset
    55
samedevice = win32.samedevice
871c77e78f5d windows: fix pyflakes warning on unused imports
Matt Mackall <mpm@selenic.com>
parents: 15011
diff changeset
    56
samefile = win32.samefile
871c77e78f5d windows: fix pyflakes warning on unused imports
Matt Mackall <mpm@selenic.com>
parents: 15011
diff changeset
    57
setsignalhandler = win32.setsignalhandler
871c77e78f5d windows: fix pyflakes warning on unused imports
Matt Mackall <mpm@selenic.com>
parents: 15011
diff changeset
    58
spawndetached = win32.spawndetached
17560
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17537
diff changeset
    59
split = os.path.split
15016
871c77e78f5d windows: fix pyflakes warning on unused imports
Matt Mackall <mpm@selenic.com>
parents: 15011
diff changeset
    60
testpid = win32.testpid
871c77e78f5d windows: fix pyflakes warning on unused imports
Matt Mackall <mpm@selenic.com>
parents: 15011
diff changeset
    61
unlink = win32.unlink
14985
dbf91976f900 windows: eliminate win32 wildcard import
Adrian Buehlmann <adrian@cadifra.com>
parents: 14969
diff changeset
    62
49913
3fd5824f1177 typing: attempt to remove @overloads in the platform module for stdlib methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 49912
diff changeset
    63
if typing.TYPE_CHECKING:
3fd5824f1177 typing: attempt to remove @overloads in the platform module for stdlib methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 49912
diff changeset
    64
    # Replace the various overloads that come along with aliasing stdlib methods
3fd5824f1177 typing: attempt to remove @overloads in the platform module for stdlib methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 49912
diff changeset
    65
    # with the narrow definition that we care about in the type checking phase
3fd5824f1177 typing: attempt to remove @overloads in the platform module for stdlib methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 49912
diff changeset
    66
    # only.  This ensures that both Windows and POSIX see only the definition
3fd5824f1177 typing: attempt to remove @overloads in the platform module for stdlib methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 49912
diff changeset
    67
    # that is actually available.
3fd5824f1177 typing: attempt to remove @overloads in the platform module for stdlib methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 49912
diff changeset
    68
    #
3fd5824f1177 typing: attempt to remove @overloads in the platform module for stdlib methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 49912
diff changeset
    69
    # Note that if we check pycompat.TYPE_CHECKING here, it is always False, and
3fd5824f1177 typing: attempt to remove @overloads in the platform module for stdlib methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 49912
diff changeset
    70
    # the methods aren't replaced.
3fd5824f1177 typing: attempt to remove @overloads in the platform module for stdlib methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 49912
diff changeset
    71
    def split(p: bytes) -> Tuple[bytes, bytes]:
3fd5824f1177 typing: attempt to remove @overloads in the platform module for stdlib methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 49912
diff changeset
    72
        raise NotImplementedError
3fd5824f1177 typing: attempt to remove @overloads in the platform module for stdlib methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 49912
diff changeset
    73
3fd5824f1177 typing: attempt to remove @overloads in the platform module for stdlib methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 49912
diff changeset
    74
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
    75
umask: int = 0o022
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
    77
49037
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48990
diff changeset
    78
class mixedfilemodewrapper:
26375
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    79
    """Wraps a file handle when it is opened in read/write mode.
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    80
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    81
    fopen() and fdopen() on Windows have a specific-to-Windows requirement
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    82
    that files opened with mode r+, w+, or a+ make a call to a file positioning
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    83
    function when switching between reads and writes. Without this extra call,
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    84
    Python will raise a not very intuitive "IOError: [Errno 0] Error."
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    85
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    86
    This class wraps posixfile instances when the file is opened in read/write
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    87
    mode and automatically adds checks or inserts appropriate file positioning
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    88
    calls when necessary.
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    89
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
    90
26375
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    91
    OPNONE = 0
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    92
    OPREAD = 1
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    93
    OPWRITE = 2
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    94
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    95
    def __init__(self, fp):
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
    96
        object.__setattr__(self, '_fp', fp)
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
    97
        object.__setattr__(self, '_lastop', 0)
26375
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    98
31891
87f293edabb6 windows: add context manager support to mixedfilemodewrapper
Matt Harbison <matt_harbison@yahoo.com>
parents: 31649
diff changeset
    99
    def __enter__(self):
40467
9ae4aed27930 windows: ensure mixedfilemodewrapper fd doesn't escape by entering context mgr
Matt Harbison <matt_harbison@yahoo.com>
parents: 40466
diff changeset
   100
        self._fp.__enter__()
9ae4aed27930 windows: ensure mixedfilemodewrapper fd doesn't escape by entering context mgr
Matt Harbison <matt_harbison@yahoo.com>
parents: 40466
diff changeset
   101
        return self
31891
87f293edabb6 windows: add context manager support to mixedfilemodewrapper
Matt Harbison <matt_harbison@yahoo.com>
parents: 31649
diff changeset
   102
87f293edabb6 windows: add context manager support to mixedfilemodewrapper
Matt Harbison <matt_harbison@yahoo.com>
parents: 31649
diff changeset
   103
    def __exit__(self, exc_type, exc_val, exc_tb):
87f293edabb6 windows: add context manager support to mixedfilemodewrapper
Matt Harbison <matt_harbison@yahoo.com>
parents: 31649
diff changeset
   104
        self._fp.__exit__(exc_type, exc_val, exc_tb)
87f293edabb6 windows: add context manager support to mixedfilemodewrapper
Matt Harbison <matt_harbison@yahoo.com>
parents: 31649
diff changeset
   105
26375
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   106
    def __getattr__(self, name):
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   107
        return getattr(self._fp, name)
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   108
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   109
    def __setattr__(self, name, value):
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   110
        return self._fp.__setattr__(name, value)
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   111
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   112
    def _noopseek(self):
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   113
        self._fp.seek(0, os.SEEK_CUR)
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   114
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   115
    def seek(self, *args, **kwargs):
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
   116
        object.__setattr__(self, '_lastop', self.OPNONE)
26375
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   117
        return self._fp.seek(*args, **kwargs)
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   118
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   119
    def write(self, d):
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   120
        if self._lastop == self.OPREAD:
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   121
            self._noopseek()
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   122
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
   123
        object.__setattr__(self, '_lastop', self.OPWRITE)
26375
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   124
        return self._fp.write(d)
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   125
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   126
    def writelines(self, *args, **kwargs):
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   127
        if self._lastop == self.OPREAD:
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   128
            self._noopeseek()
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   129
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
   130
        object.__setattr__(self, '_lastop', self.OPWRITE)
26375
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   131
        return self._fp.writelines(*args, **kwargs)
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   132
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   133
    def read(self, *args, **kwargs):
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   134
        if self._lastop == self.OPWRITE:
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   135
            self._noopseek()
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   136
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
   137
        object.__setattr__(self, '_lastop', self.OPREAD)
26375
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   138
        return self._fp.read(*args, **kwargs)
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   139
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   140
    def readline(self, *args, **kwargs):
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   141
        if self._lastop == self.OPWRITE:
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   142
            self._noopseek()
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   143
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
   144
        object.__setattr__(self, '_lastop', self.OPREAD)
26375
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   145
        return self._fp.readline(*args, **kwargs)
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   146
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   147
    def readlines(self, *args, **kwargs):
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   148
        if self._lastop == self.OPWRITE:
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   149
            self._noopseek()
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   150
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
   151
        object.__setattr__(self, '_lastop', self.OPREAD)
26375
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   152
        return self._fp.readlines(*args, **kwargs)
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   153
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   154
49037
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48990
diff changeset
   155
class fdproxy:
39825
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   156
    """Wraps osutil.posixfile() to override the name attribute to reflect the
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   157
    underlying file name.
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   158
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   159
39825
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   160
    def __init__(self, name, fp):
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   161
        self.name = name
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   162
        self._fp = fp
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   163
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   164
    def __enter__(self):
40466
e11e03f72baf py3: ensure the proxied Windows fd doesn't escape by entering context manager
Matt Harbison <matt_harbison@yahoo.com>
parents: 40266
diff changeset
   165
        self._fp.__enter__()
e11e03f72baf py3: ensure the proxied Windows fd doesn't escape by entering context manager
Matt Harbison <matt_harbison@yahoo.com>
parents: 40266
diff changeset
   166
        # Return this wrapper for the context manager so that the name is
e11e03f72baf py3: ensure the proxied Windows fd doesn't escape by entering context manager
Matt Harbison <matt_harbison@yahoo.com>
parents: 40266
diff changeset
   167
        # still available.
e11e03f72baf py3: ensure the proxied Windows fd doesn't escape by entering context manager
Matt Harbison <matt_harbison@yahoo.com>
parents: 40266
diff changeset
   168
        return self
39825
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   169
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   170
    def __exit__(self, exc_type, exc_value, traceback):
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   171
        self._fp.__exit__(exc_type, exc_value, traceback)
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   172
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   173
    def __iter__(self):
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   174
        return iter(self._fp)
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   175
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   176
    def __getattr__(self, name):
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   177
        return getattr(self._fp, name)
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   178
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   179
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   180
def posixfile(name, mode=b'r', buffering=-1):
24069
c6666395fdd2 windows: adjust doc string and comments of posixfile()
Adrian Buehlmann <adrian@cadifra.com>
parents: 24051
diff changeset
   181
    '''Open a file with even more POSIX-like semantics'''
8421
b6d0fa8c7685 posixfile: remove posixfile_nt and fix import bug in windows.py
Sune Foldager <cryo@cyanite.org>
parents: 8364
diff changeset
   182
    try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   183
        fp = osutil.posixfile(name, mode, buffering)  # may raise WindowsError
24051
7956d17431bc windows: seek to the end of posixfile when opening in append mode
Matt Harbison <matt_harbison@yahoo.com>
parents: 23682
diff changeset
   184
39825
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   185
        # PyFile_FromFd() ignores the name, and seems to report fp.name as the
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   186
        # underlying file descriptor.
48989
a98e32e5fca1 windows: remove conditional for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48966
diff changeset
   187
        fp = fdproxy(name, fp)
39825
68ea1f8dcb84 py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39735
diff changeset
   188
24051
7956d17431bc windows: seek to the end of posixfile when opening in append mode
Matt Harbison <matt_harbison@yahoo.com>
parents: 23682
diff changeset
   189
        # The position when opening in append mode is implementation defined, so
7956d17431bc windows: seek to the end of posixfile when opening in append mode
Matt Harbison <matt_harbison@yahoo.com>
parents: 23682
diff changeset
   190
        # make it consistent with other platforms, which position at EOF.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   191
        if b'a' in mode:
25462
021e68d37c5b windows: use os.SEEK_END
Adrian Buehlmann <adrian@cadifra.com>
parents: 25420
diff changeset
   192
            fp.seek(0, os.SEEK_END)
24051
7956d17431bc windows: seek to the end of posixfile when opening in append mode
Matt Harbison <matt_harbison@yahoo.com>
parents: 23682
diff changeset
   193
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   194
        if b'+' in mode:
26375
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   195
            return mixedfilemodewrapper(fp)
3686fa2b8eee windows: insert file positioning call between reads and writes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   196
24051
7956d17431bc windows: seek to the end of posixfile when opening in append mode
Matt Harbison <matt_harbison@yahoo.com>
parents: 23682
diff changeset
   197
        return fp
48032
94d4a3f78e99 typing: suppress an name-error warning in `mercurial/windows.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 47858
diff changeset
   198
    except WindowsError as err:  # pytype: disable=name-error
24069
c6666395fdd2 windows: adjust doc string and comments of posixfile()
Adrian Buehlmann <adrian@cadifra.com>
parents: 24051
diff changeset
   199
        # convert to a friendlier exception
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   200
        raise IOError(
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
   201
            err.errno, '%s: %s' % (encoding.strfromlocal(name), err.strerror)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   202
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   203
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   204
32248
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31891
diff changeset
   205
# may be wrapped by win32mbcs extension
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31891
diff changeset
   206
listdir = osutil.listdir
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31891
diff changeset
   207
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   208
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   209
def get_password() -> bytes:
47038
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   210
    """Prompt for password with echo off, using Windows getch().
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   211
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   212
    This shouldn't be called directly- use ``ui.getpass()`` instead, which
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   213
    checks if the session is interactive first.
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   214
    """
47788
064cd182555f windows: avoid a bytes vs unicode crash reading passwords on py2
Matt Harbison <matt_harbison@yahoo.com>
parents: 47622
diff changeset
   215
    pw = u""
47038
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   216
    while True:
47430
f77404040776 typing: disable warnings for a couple of Windows specific attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 47038
diff changeset
   217
        c = msvcrt.getwch()  # pytype: disable=module-attr
47788
064cd182555f windows: avoid a bytes vs unicode crash reading passwords on py2
Matt Harbison <matt_harbison@yahoo.com>
parents: 47622
diff changeset
   218
        if c == u'\r' or c == u'\n':
47038
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   219
            break
47788
064cd182555f windows: avoid a bytes vs unicode crash reading passwords on py2
Matt Harbison <matt_harbison@yahoo.com>
parents: 47622
diff changeset
   220
        if c == u'\003':
47038
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   221
            raise KeyboardInterrupt
47788
064cd182555f windows: avoid a bytes vs unicode crash reading passwords on py2
Matt Harbison <matt_harbison@yahoo.com>
parents: 47622
diff changeset
   222
        if c == u'\b':
47038
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   223
            pw = pw[:-1]
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   224
        else:
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   225
            pw = pw + c
47788
064cd182555f windows: avoid a bytes vs unicode crash reading passwords on py2
Matt Harbison <matt_harbison@yahoo.com>
parents: 47622
diff changeset
   226
    msvcrt.putwch(u'\r')  # pytype: disable=module-attr
064cd182555f windows: avoid a bytes vs unicode crash reading passwords on py2
Matt Harbison <matt_harbison@yahoo.com>
parents: 47622
diff changeset
   227
    msvcrt.putwch(u'\n')  # pytype: disable=module-attr
064cd182555f windows: avoid a bytes vs unicode crash reading passwords on py2
Matt Harbison <matt_harbison@yahoo.com>
parents: 47622
diff changeset
   228
    return encoding.unitolocal(pw)
47038
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   229
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   230
49888
8147abc05794 pytype: stop excluding mercurial/ui.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49426
diff changeset
   231
class winstdout(typelib.BinaryIO_Proxy):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45158
diff changeset
   232
    """Some files on Windows misbehave.
45145
aea246bc04bd windows: augment docstring of `winstdout` class
Manuel Jacob <me@manueljacob.de>
parents: 44926
diff changeset
   233
aea246bc04bd windows: augment docstring of `winstdout` class
Manuel Jacob <me@manueljacob.de>
parents: 44926
diff changeset
   234
    When writing to a broken pipe, EINVAL instead of EPIPE may be raised.
aea246bc04bd windows: augment docstring of `winstdout` class
Manuel Jacob <me@manueljacob.de>
parents: 44926
diff changeset
   235
aea246bc04bd windows: augment docstring of `winstdout` class
Manuel Jacob <me@manueljacob.de>
parents: 44926
diff changeset
   236
    When writing too many bytes to a console at the same, a "Not enough space"
aea246bc04bd windows: augment docstring of `winstdout` class
Manuel Jacob <me@manueljacob.de>
parents: 44926
diff changeset
   237
    error may happen. Python 3 already works around that.
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45158
diff changeset
   238
    """
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   239
49888
8147abc05794 pytype: stop excluding mercurial/ui.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49426
diff changeset
   240
    def __init__(self, fp: BinaryIO):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   241
        self.fp = fp
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   242
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   243
    def __getattr__(self, key):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   244
        return getattr(self.fp, key)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   245
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   246
    def close(self):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   247
        try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   248
            self.fp.close()
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13986
diff changeset
   249
        except IOError:
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13986
diff changeset
   250
            pass
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   251
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   252
    def write(self, s):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   253
        try:
48990
563eb25e079b windows: remove write throttling support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48989
diff changeset
   254
            return self.fp.write(s)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25658
diff changeset
   255
        except IOError as inst:
37882
3a0f322af192 windows: fix incorrect detection of broken pipe when writing to pager
Sune Foldager <cryo@cyanite.org>
parents: 37460
diff changeset
   256
            if inst.errno != 0 and not win32.lasterrorwaspipeerror(inst):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   257
                raise
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   258
            self.close()
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
   259
            raise IOError(errno.EPIPE, 'Broken pipe')
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   260
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   261
    def flush(self):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   262
        try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   263
            return self.fp.flush()
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25658
diff changeset
   264
        except IOError as inst:
37882
3a0f322af192 windows: fix incorrect detection of broken pipe when writing to pager
Sune Foldager <cryo@cyanite.org>
parents: 37460
diff changeset
   265
            if not win32.lasterrorwaspipeerror(inst):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   266
                raise
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
   267
            raise IOError(errno.EPIPE, 'Broken pipe')
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   268
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   269
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   270
def openhardlinks() -> bool:
43928
70abcb614a5c windows: drop detection of Windows 95/98/ME
Matt Harbison <matt_harbison@yahoo.com>
parents: 43910
diff changeset
   271
    return True
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   272
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   273
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   274
def parsepatchoutput(output_line: bytes) -> bytes:
8761
0289f384e1e5 Generally replace "file name" with "filename" in help and comments.
timeless <timeless@gmail.com>
parents: 8657
diff changeset
   275
    """parses the output produced by patch and returns the filename"""
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   276
    pf = output_line[14:]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   277
    if pf[0] == b'`':
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   278
        pf = pf[1:-1]  # Remove the quotes
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   279
    return pf
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   280
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   281
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   282
def sshargs(
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   283
    sshcmd: bytes, host: bytes, user: Optional[bytes], port: Optional[bytes]
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   284
) -> bytes:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   285
    '''Build argument list for ssh or Plink'''
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   286
    pflag = b'plink' in sshcmd.lower() and b'-P' or b'-p'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   287
    args = user and (b"%s@%s" % (user, host)) or host
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   288
    if args.startswith(b'-') or args.startswith(b'/'):
33649
739cc0f9cbb4 ssh: ban any username@host or host that starts with - (SEC)
Augie Fackler <augie@google.com>
parents: 32706
diff changeset
   289
        raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   290
            _(b'illegal ssh hostname or username starting with - or /: %s')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   291
            % args
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   292
        )
33657
8cb9e921ef8c ssh: quote parameters using shellquote (SEC)
Jun Wu <quark@fb.com>
parents: 33649
diff changeset
   293
    args = shellquote(args)
8cb9e921ef8c ssh: quote parameters using shellquote (SEC)
Jun Wu <quark@fb.com>
parents: 33649
diff changeset
   294
    if port:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   295
        args = b'%s %s %s' % (pflag, shellquote(port), args)
33657
8cb9e921ef8c ssh: quote parameters using shellquote (SEC)
Jun Wu <quark@fb.com>
parents: 33649
diff changeset
   296
    return args
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   297
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   298
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   299
def setflags(f: bytes, l: bool, x: bool) -> None:
15011
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14985
diff changeset
   300
    pass
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14985
diff changeset
   301
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   302
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   303
def copymode(
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   304
    src: bytes,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   305
    dst: bytes,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   306
    mode: Optional[bytes] = None,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   307
    enforcewritable: bool = False,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   308
) -> None:
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   309
    pass
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   310
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   311
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   312
def checkexec(path: bytes) -> bool:
13879
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13777
diff changeset
   313
    return False
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13777
diff changeset
   314
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   315
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   316
def checklink(path: bytes) -> bool:
13890
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   317
    return False
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   318
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   319
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   320
def setbinary(fd) -> None:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   321
    # When run without console, pipes may expose invalid
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   322
    # fileno(), usually set to -1.
14969
a3f97038c1c2 windows: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14927
diff changeset
   323
    fno = getattr(fd, 'fileno', None)
a3f97038c1c2 windows: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14927
diff changeset
   324
    if fno is not None and fno() >= 0:
43788
fe73ec69350e windows: suppress pytype warnings for Windows imports and functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 43554
diff changeset
   325
        msvcrt.setmode(fno(), os.O_BINARY)  # pytype: disable=module-attr
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   326
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   327
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   328
def pconvert(path: bytes) -> bytes:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   329
    return path.replace(pycompat.ossep, b'/')
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   330
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   331
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   332
def localpath(path: bytes) -> bytes:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   333
    return path.replace(b'/', b'\\')
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   334
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   335
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   336
def normpath(path: bytes) -> bytes:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   337
    return pconvert(os.path.normpath(path))
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   338
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   339
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   340
def normcase(path: bytes) -> bytes:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   341
    return encoding.upper(path)  # NTFS compares via upper()
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   342
15488
6eff984d8e76 dirstate: fix case-folding identity for traditional Unix
Matt Mackall <mpm@selenic.com>
parents: 15016
diff changeset
   343
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   344
DRIVE_RE_B: Pattern[bytes] = re.compile(b'^[a-z]:')
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   345
DRIVE_RE_S: Pattern[str] = re.compile('^[a-z]:')
47622
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   346
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   347
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   348
# TODO: why is this accepting str?
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   349
def abspath(path: AnyStr) -> AnyStr:
47622
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   350
    abs_path = os.path.abspath(path)  # re-exports
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   351
    # Python on Windows is inconsistent regarding the capitalization of drive
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   352
    # letter and this cause issue with various path comparison along the way.
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   353
    # So we normalize the drive later to upper case here.
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   354
    #
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   355
    # See https://bugs.python.org/issue40368 for and example of this hell.
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   356
    if isinstance(abs_path, bytes):
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   357
        if DRIVE_RE_B.match(abs_path):
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   358
            abs_path = abs_path[0:1].upper() + abs_path[1:]
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   359
    elif DRIVE_RE_S.match(abs_path):
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   360
        abs_path = abs_path[0:1].upper() + abs_path[1:]
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   361
    return abs_path
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   362
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47430
diff changeset
   363
24598
22f49c7dd11b windows: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24148
diff changeset
   364
# see posix.py for definitions
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   365
normcasespec: int = encoding.normcasespecs.upper
24598
22f49c7dd11b windows: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24148
diff changeset
   366
normcasefallback = encoding.upperfallback
22f49c7dd11b windows: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24148
diff changeset
   367
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   368
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   369
def samestat(s1: os.stat_result, s2: os.stat_result) -> bool:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   370
    return False
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   371
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   372
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   373
def shelltocmdexe(path: bytes, env: Mapping[bytes, bytes]) -> bytes:
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   374
    r"""Convert shell variables in the form $var and ${var} inside ``path``
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   375
    to %var% form.  Existing Windows style variables are left unchanged.
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   376
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   377
    The variables are limited to the given environment.  Unknown variables are
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   378
    left unchanged.
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   379
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   380
    >>> e = {b'var1': b'v1', b'var2': b'v2', b'var3': b'v3'}
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   381
    >>> # Only valid values are expanded
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   382
    >>> shelltocmdexe(b'cmd $var1 ${var2} %var3% $missing ${missing} %missing%',
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   383
    ...               e)
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   384
    'cmd %var1% %var2% %var3% $missing ${missing} %missing%'
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   385
    >>> # Single quote prevents expansion, as does \$ escaping
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   386
    >>> shelltocmdexe(b"cmd '$var1 ${var2} %var3%' \$var1 \${var2} \\", e)
38724
02b5b5c1bba8 windows: replace single quote with double quote when translating to cmd.exe
Matt Harbison <matt_harbison@yahoo.com>
parents: 38627
diff changeset
   387
    'cmd "$var1 ${var2} %var3%" $var1 ${var2} \\'
38627
93ed193bc03e windows: don't consider '$$' to be an escaped '$' when translating to cmd.exe
Matt Harbison <matt_harbison@yahoo.com>
parents: 38602
diff changeset
   388
    >>> # $$ is not special. %% is not special either, but can be the end and
93ed193bc03e windows: don't consider '$$' to be an escaped '$' when translating to cmd.exe
Matt Harbison <matt_harbison@yahoo.com>
parents: 38602
diff changeset
   389
    >>> # start of consecutive variables
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   390
    >>> shelltocmdexe(b"cmd $$ %% %var1%%var2%", e)
38627
93ed193bc03e windows: don't consider '$$' to be an escaped '$' when translating to cmd.exe
Matt Harbison <matt_harbison@yahoo.com>
parents: 38602
diff changeset
   391
    'cmd $$ %% %var1%%var2%'
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   392
    >>> # No double substitution
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   393
    >>> shelltocmdexe(b"$var1 %var1%", {b'var1': b'%var2%', b'var2': b'boom'})
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   394
    '%var1% %var1%'
38725
c382c19ce9bd windows: expand '~/' and '~\' to %USERPROFILE% when translating to cmd.exe
Matt Harbison <matt_harbison@yahoo.com>
parents: 38724
diff changeset
   395
    >>> # Tilde expansion
c382c19ce9bd windows: expand '~/' and '~\' to %USERPROFILE% when translating to cmd.exe
Matt Harbison <matt_harbison@yahoo.com>
parents: 38724
diff changeset
   396
    >>> shelltocmdexe(b"~/dir ~\dir2 ~tmpfile \~/", {})
c382c19ce9bd windows: expand '~/' and '~\' to %USERPROFILE% when translating to cmd.exe
Matt Harbison <matt_harbison@yahoo.com>
parents: 38724
diff changeset
   397
    '%USERPROFILE%/dir %USERPROFILE%\\dir2 ~tmpfile ~/'
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   398
    """
38725
c382c19ce9bd windows: expand '~/' and '~\' to %USERPROFILE% when translating to cmd.exe
Matt Harbison <matt_harbison@yahoo.com>
parents: 38724
diff changeset
   399
    if not any(c in path for c in b"$'~"):
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   400
        return path
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   401
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   402
    varchars = pycompat.sysbytes(string.ascii_letters + string.digits) + b'_-'
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   403
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   404
    res = b''
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   405
    index = 0
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   406
    pathlen = len(path)
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   407
    while index < pathlen:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   408
        c = path[index : index + 1]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   409
        if c == b'\'':  # no expansion within single quotes
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   410
            path = path[index + 1 :]
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   411
            pathlen = len(path)
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   412
            try:
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   413
                index = path.index(b'\'')
38724
02b5b5c1bba8 windows: replace single quote with double quote when translating to cmd.exe
Matt Harbison <matt_harbison@yahoo.com>
parents: 38627
diff changeset
   414
                res += b'"' + path[:index] + b'"'
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   415
            except ValueError:
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   416
                res += c + path
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   417
                index = pathlen - 1
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   418
        elif c == b'%':  # variable
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   419
            path = path[index + 1 :]
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   420
            pathlen = len(path)
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   421
            try:
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   422
                index = path.index(b'%')
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   423
            except ValueError:
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   424
                res += b'%' + path
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   425
                index = pathlen - 1
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   426
            else:
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   427
                var = path[:index]
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   428
                res += b'%' + var + b'%'
38627
93ed193bc03e windows: don't consider '$$' to be an escaped '$' when translating to cmd.exe
Matt Harbison <matt_harbison@yahoo.com>
parents: 38602
diff changeset
   429
        elif c == b'$':  # variable
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   430
            if path[index + 1 : index + 2] == b'{':
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   431
                path = path[index + 2 :]
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   432
                pathlen = len(path)
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   433
                try:
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   434
                    index = path.index(b'}')
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   435
                    var = path[:index]
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   436
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   437
                    # See below for why empty variables are handled specially
39915
6e2c8f7f894e py3: byteify windows.shelltocmdexe()
Matt Harbison <matt_harbison@yahoo.com>
parents: 39909
diff changeset
   438
                    if env.get(var, b'') != b'':
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   439
                        res += b'%' + var + b'%'
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   440
                    else:
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   441
                        res += b'${' + var + b'}'
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   442
                except ValueError:
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   443
                    res += b'${' + path
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   444
                    index = pathlen - 1
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   445
            else:
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   446
                var = b''
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   447
                index += 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   448
                c = path[index : index + 1]
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   449
                while c != b'' and c in varchars:
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   450
                    var += c
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   451
                    index += 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   452
                    c = path[index : index + 1]
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   453
                # Some variables (like HG_OLDNODE) may be defined, but have an
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   454
                # empty value.  Those need to be skipped because when spawning
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   455
                # cmd.exe to run the hook, it doesn't replace %VAR% for an empty
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   456
                # VAR, and that really confuses things like revset expressions.
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   457
                # OTOH, if it's left in Unix format and the hook runs sh.exe, it
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   458
                # will substitute to an empty string, and everything is happy.
39915
6e2c8f7f894e py3: byteify windows.shelltocmdexe()
Matt Harbison <matt_harbison@yahoo.com>
parents: 39909
diff changeset
   459
                if env.get(var, b'') != b'':
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   460
                    res += b'%' + var + b'%'
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   461
                else:
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   462
                    res += b'$' + var
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   463
39915
6e2c8f7f894e py3: byteify windows.shelltocmdexe()
Matt Harbison <matt_harbison@yahoo.com>
parents: 39909
diff changeset
   464
                if c != b'':
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   465
                    index -= 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   466
        elif (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   467
            c == b'~'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   468
            and index + 1 < pathlen
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   469
            and path[index + 1 : index + 2] in (b'\\', b'/')
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   470
        ):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   471
            res += b"%USERPROFILE%"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   472
        elif (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   473
            c == b'\\'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   474
            and index + 1 < pathlen
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   475
            and path[index + 1 : index + 2] in (b'$', b'~')
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   476
        ):
38725
c382c19ce9bd windows: expand '~/' and '~\' to %USERPROFILE% when translating to cmd.exe
Matt Harbison <matt_harbison@yahoo.com>
parents: 38724
diff changeset
   477
            # Skip '\', but only if it is escaping $ or ~
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   478
            res += path[index + 1 : index + 2]
38487
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   479
            index += 1
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   480
        else:
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   481
            res += c
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   482
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   483
        index += 1
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   484
    return res
3efadf2317c7 windows: add a method to convert Unix style command lines to Windows style
Matt Harbison <matt_harbison@yahoo.com>
parents: 37460
diff changeset
   485
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   486
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   487
# A sequence of backslashes is special iff it precedes a double quote:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   488
# - if there's an even number of backslashes, the double quote is not
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   489
#   quoted (i.e. it ends the quoted region)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   490
# - if there's an odd number of backslashes, the double quote is quoted
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   491
# - in both cases, every pair of backslashes is unquoted into a single
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   492
#   backslash
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   493
# (See http://msdn2.microsoft.com/en-us/library/a1y7w461.aspx )
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   494
# So, to quote a string, we must surround it in double quotes, double
17505
ae791d371864 spelling: precede
timeless@mozdev.org
parents: 17223
diff changeset
   495
# the number of backslashes that precede double quotes and add another
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   496
# backslash before every double quote (being careful with the double
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   497
# quote we've appended to the end)
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   498
_quotere: Optional[Pattern[bytes]] = None
23682
1642eb429536 windows: quote the specified string only when it has to be quoted
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22245
diff changeset
   499
_needsshellquote = None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   500
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   501
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   502
def shellquote(s: bytes) -> bytes:
24908
30b910fea244 windows: add doctest for shellquote()
Matt Harbison <matt_harbison@yahoo.com>
parents: 24885
diff changeset
   503
    r"""
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34040
diff changeset
   504
    >>> shellquote(br'C:\Users\xyz')
24908
30b910fea244 windows: add doctest for shellquote()
Matt Harbison <matt_harbison@yahoo.com>
parents: 24885
diff changeset
   505
    '"C:\\Users\\xyz"'
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34040
diff changeset
   506
    >>> shellquote(br'C:\Users\xyz/mixed')
24908
30b910fea244 windows: add doctest for shellquote()
Matt Harbison <matt_harbison@yahoo.com>
parents: 24885
diff changeset
   507
    '"C:\\Users\\xyz/mixed"'
30b910fea244 windows: add doctest for shellquote()
Matt Harbison <matt_harbison@yahoo.com>
parents: 24885
diff changeset
   508
    >>> # Would be safe not to quote too, since it is all double backslashes
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34040
diff changeset
   509
    >>> shellquote(br'C:\\Users\\xyz')
24908
30b910fea244 windows: add doctest for shellquote()
Matt Harbison <matt_harbison@yahoo.com>
parents: 24885
diff changeset
   510
    '"C:\\\\Users\\\\xyz"'
30b910fea244 windows: add doctest for shellquote()
Matt Harbison <matt_harbison@yahoo.com>
parents: 24885
diff changeset
   511
    >>> # But this must be quoted
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34040
diff changeset
   512
    >>> shellquote(br'C:\\Users\\xyz/abc')
24908
30b910fea244 windows: add doctest for shellquote()
Matt Harbison <matt_harbison@yahoo.com>
parents: 24885
diff changeset
   513
    '"C:\\\\Users\\\\xyz/abc"'
30b910fea244 windows: add doctest for shellquote()
Matt Harbison <matt_harbison@yahoo.com>
parents: 24885
diff changeset
   514
    """
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   515
    global _quotere
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   516
    if _quotere is None:
39660
3b421154d2ca py3: fix str vs bytes in enough places to run `hg version` on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39659
diff changeset
   517
        _quotere = re.compile(br'(\\*)("|\\$)')
23682
1642eb429536 windows: quote the specified string only when it has to be quoted
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22245
diff changeset
   518
    global _needsshellquote
1642eb429536 windows: quote the specified string only when it has to be quoted
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22245
diff changeset
   519
    if _needsshellquote is None:
24885
eea3977e6fca windows: make shellquote() quote any path containing '\' (issue4629)
Matt Harbison <matt_harbison@yahoo.com>
parents: 24692
diff changeset
   520
        # ":" is also treated as "safe character", because it is used as a part
eea3977e6fca windows: make shellquote() quote any path containing '\' (issue4629)
Matt Harbison <matt_harbison@yahoo.com>
parents: 24692
diff changeset
   521
        # of path name on Windows.  "\" is also part of a path name, but isn't
eea3977e6fca windows: make shellquote() quote any path containing '\' (issue4629)
Matt Harbison <matt_harbison@yahoo.com>
parents: 24692
diff changeset
   522
        # safe because shlex.split() (kind of) treats it as an escape char and
eea3977e6fca windows: make shellquote() quote any path containing '\' (issue4629)
Matt Harbison <matt_harbison@yahoo.com>
parents: 24692
diff changeset
   523
        # drops it.  It will leave the next character, even if it is another
eea3977e6fca windows: make shellquote() quote any path containing '\' (issue4629)
Matt Harbison <matt_harbison@yahoo.com>
parents: 24692
diff changeset
   524
        # "\".
39660
3b421154d2ca py3: fix str vs bytes in enough places to run `hg version` on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39659
diff changeset
   525
        _needsshellquote = re.compile(br'[^a-zA-Z0-9._:/-]').search
24108
d65ecb814fc0 shellquote: fix missing quotes for empty string
Yuya Nishihara <yuya@tcha.org>
parents: 23682
diff changeset
   526
    if s and not _needsshellquote(s) and not _quotere.search(s):
23682
1642eb429536 windows: quote the specified string only when it has to be quoted
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22245
diff changeset
   527
        # "s" shouldn't have to be quoted
1642eb429536 windows: quote the specified string only when it has to be quoted
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22245
diff changeset
   528
        return s
39660
3b421154d2ca py3: fix str vs bytes in enough places to run `hg version` on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39659
diff changeset
   529
    return b'"%s"' % _quotere.sub(br'\1\1\\\2', s)
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   530
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   531
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   532
def _unquote(s: bytes) -> bytes:
36445
0cb09c322647 util: factor out shellsplit() function
Yuya Nishihara <yuya@tcha.org>
parents: 35517
diff changeset
   533
    if s.startswith(b'"') and s.endswith(b'"'):
0cb09c322647 util: factor out shellsplit() function
Yuya Nishihara <yuya@tcha.org>
parents: 35517
diff changeset
   534
        return s[1:-1]
0cb09c322647 util: factor out shellsplit() function
Yuya Nishihara <yuya@tcha.org>
parents: 35517
diff changeset
   535
    return s
0cb09c322647 util: factor out shellsplit() function
Yuya Nishihara <yuya@tcha.org>
parents: 35517
diff changeset
   536
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   537
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   538
def shellsplit(s: bytes) -> List[bytes]:
36445
0cb09c322647 util: factor out shellsplit() function
Yuya Nishihara <yuya@tcha.org>
parents: 35517
diff changeset
   539
    """Parse a command string in cmd.exe way (best-effort)"""
0cb09c322647 util: factor out shellsplit() function
Yuya Nishihara <yuya@tcha.org>
parents: 35517
diff changeset
   540
    return pycompat.maplist(_unquote, pycompat.shlexsplit(s, posix=False))
0cb09c322647 util: factor out shellsplit() function
Yuya Nishihara <yuya@tcha.org>
parents: 35517
diff changeset
   541
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   542
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   543
# if you change this stub into a real check, please try to implement the
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   544
# username and groupname functions above, too.
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   545
def isowner(st: os.stat_result) -> bool:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   546
    return True
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   547
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   548
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   549
def findexe(command: bytes) -> Optional[bytes]:
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45158
diff changeset
   550
    """Find executable for command searching like cmd.exe does.
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   551
    If command is a basename then PATH is searched for command.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   552
    PATH isn't searched if command is an absolute or relative path.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   553
    An extension from PATHEXT is found and added if not present.
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45158
diff changeset
   554
    If command isn't found None is returned."""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   555
    pathext = encoding.environ.get(b'PATHEXT', b'.COM;.EXE;.BAT;.CMD')
30617
d623cc6b3742 py3: replace os.pathsep with pycompat.ospathsep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30483
diff changeset
   556
    pathexts = [ext for ext in pathext.lower().split(pycompat.ospathsep)]
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   557
    if os.path.splitext(command)[1].lower() in pathexts:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   558
        pathexts = [b'']
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   559
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   560
    def findexisting(pathcommand: bytes) -> Optional[bytes]:
43807
be8552f25cab cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents: 43788
diff changeset
   561
        """Will append extension (if needed) and return existing file"""
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   562
        for ext in pathexts:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   563
            executable = pathcommand + ext
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   564
            if os.path.exists(executable):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   565
                return executable
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   566
        return None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   567
30620
bb77654dc7ae py3: replace os.sep with pycompat.ossep (part 3 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30617
diff changeset
   568
    if pycompat.ossep in command:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   569
        return findexisting(command)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   570
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   571
    for path in encoding.environ.get(b'PATH', b'').split(pycompat.ospathsep):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   572
        executable = findexisting(os.path.join(path, command))
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   573
        if executable is not None:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   574
            return executable
10156
c31ac3f7fd8f windows: expand environment vars in find_exe
Steve Borho <steve@borho.org>
parents: 9594
diff changeset
   575
    return findexisting(os.path.expanduser(os.path.expandvars(command)))
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   576
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   577
32331
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 32248
diff changeset
   578
_wantedkinds = {stat.S_IFREG, stat.S_IFLNK}
18017
74912fe3d718 dirstate: move file type filtering to its source
Bryan O'Sullivan <bryano@fb.com>
parents: 17560
diff changeset
   579
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   580
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   581
def statfiles(files: Sequence[bytes]) -> Iterator[Optional[os.stat_result]]:
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45158
diff changeset
   582
    """Stat each file in files. Yield each stat, or None if a file
18017
74912fe3d718 dirstate: move file type filtering to its source
Bryan O'Sullivan <bryano@fb.com>
parents: 17560
diff changeset
   583
    does not exist or has a type we don't care about.
74912fe3d718 dirstate: move file type filtering to its source
Bryan O'Sullivan <bryano@fb.com>
parents: 17560
diff changeset
   584
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45158
diff changeset
   585
    Cluster and cache stat per directory to minimize number of OS stat calls."""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   586
    dircache = {}  # dirname -> filename -> status | None if file does not exist
18017
74912fe3d718 dirstate: move file type filtering to its source
Bryan O'Sullivan <bryano@fb.com>
parents: 17560
diff changeset
   587
    getkind = stat.S_IFMT
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   588
    for nf in files:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   589
        nf = normcase(nf)
9099
3d456bf32f18 Use os.path.split() for MBCS with win32mbcs extension.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 8951
diff changeset
   590
        dir, base = os.path.split(nf)
3d456bf32f18 Use os.path.split() for MBCS with win32mbcs extension.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 8951
diff changeset
   591
        if not dir:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   592
            dir = b'.'
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   593
        cache = dircache.get(dir, None)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   594
        if cache is None:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   595
            try:
44470
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43928
diff changeset
   596
                dmap = {
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43928
diff changeset
   597
                    normcase(n): s
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43928
diff changeset
   598
                    for n, k, s in listdir(dir, True)
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43928
diff changeset
   599
                    if getkind(s.st_mode) in _wantedkinds
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43928
diff changeset
   600
                }
49319
defc369d705e py3: catch specific OSError subclasses instead of checking errno
Manuel Jacob <me@manueljacob.de>
parents: 49313
diff changeset
   601
            except (FileNotFoundError, NotADirectoryError):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   602
                dmap = {}
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   603
            cache = dircache.setdefault(dir, dmap)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   604
        yield cache.get(base, None)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   605
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   606
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   607
def username(uid: Optional[int] = None) -> Optional[bytes]:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   608
    """Return the name of the user with the given uid.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   609
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   610
    If uid is None, return the name of the current user."""
43910
1b26cb044097 windows: if username(uid=None) is loaded, just use getpass
Augie Fackler <augie@google.com>
parents: 43807
diff changeset
   611
    if not uid:
49426
805419729e11 windows: gracefully handle when the username cannot be determined
Matt Harbison <matt_harbison@yahoo.com>
parents: 49325
diff changeset
   612
        try:
805419729e11 windows: gracefully handle when the username cannot be determined
Matt Harbison <matt_harbison@yahoo.com>
parents: 49325
diff changeset
   613
            return pycompat.fsencode(getpass.getuser())
805419729e11 windows: gracefully handle when the username cannot be determined
Matt Harbison <matt_harbison@yahoo.com>
parents: 49325
diff changeset
   614
        except ModuleNotFoundError:
805419729e11 windows: gracefully handle when the username cannot be determined
Matt Harbison <matt_harbison@yahoo.com>
parents: 49325
diff changeset
   615
            # getpass.getuser() checks for a few environment variables first,
805419729e11 windows: gracefully handle when the username cannot be determined
Matt Harbison <matt_harbison@yahoo.com>
parents: 49325
diff changeset
   616
            # but if those aren't set, imports pwd and calls getpwuid(), none of
805419729e11 windows: gracefully handle when the username cannot be determined
Matt Harbison <matt_harbison@yahoo.com>
parents: 49325
diff changeset
   617
            # which exists on Windows.
805419729e11 windows: gracefully handle when the username cannot be determined
Matt Harbison <matt_harbison@yahoo.com>
parents: 49325
diff changeset
   618
            pass
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   619
    return None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   620
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   621
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   622
def groupname(gid: Optional[int] = None) -> Optional[bytes]:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   623
    """Return the name of the group with the given gid.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   624
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   625
    If gid is None, return the name of the current group."""
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   626
    return None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   627
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   628
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   629
def readlink(pathname: bytes) -> bytes:
47858
4162f6b40f2c windows: degrade to py2 behavior when reading a non-symlink as a symlink
Matt Harbison <matt_harbison@yahoo.com>
parents: 47788
diff changeset
   630
    path = pycompat.fsdecode(pathname)
4162f6b40f2c windows: degrade to py2 behavior when reading a non-symlink as a symlink
Matt Harbison <matt_harbison@yahoo.com>
parents: 47788
diff changeset
   631
    try:
4162f6b40f2c windows: degrade to py2 behavior when reading a non-symlink as a symlink
Matt Harbison <matt_harbison@yahoo.com>
parents: 47788
diff changeset
   632
        link = os.readlink(path)
4162f6b40f2c windows: degrade to py2 behavior when reading a non-symlink as a symlink
Matt Harbison <matt_harbison@yahoo.com>
parents: 47788
diff changeset
   633
    except ValueError as e:
4162f6b40f2c windows: degrade to py2 behavior when reading a non-symlink as a symlink
Matt Harbison <matt_harbison@yahoo.com>
parents: 47788
diff changeset
   634
        # On py2, os.readlink() raises an AttributeError since it is
4162f6b40f2c windows: degrade to py2 behavior when reading a non-symlink as a symlink
Matt Harbison <matt_harbison@yahoo.com>
parents: 47788
diff changeset
   635
        # unsupported.  On py3, reading a non-link raises a ValueError.  Simply
4162f6b40f2c windows: degrade to py2 behavior when reading a non-symlink as a symlink
Matt Harbison <matt_harbison@yahoo.com>
parents: 47788
diff changeset
   636
        # treat this as the error the locking code has been expecting up to now
4162f6b40f2c windows: degrade to py2 behavior when reading a non-symlink as a symlink
Matt Harbison <matt_harbison@yahoo.com>
parents: 47788
diff changeset
   637
        # until an effort can be made to enable symlink support on Windows.
4162f6b40f2c windows: degrade to py2 behavior when reading a non-symlink as a symlink
Matt Harbison <matt_harbison@yahoo.com>
parents: 47788
diff changeset
   638
        raise AttributeError(e)
4162f6b40f2c windows: degrade to py2 behavior when reading a non-symlink as a symlink
Matt Harbison <matt_harbison@yahoo.com>
parents: 47788
diff changeset
   639
    return pycompat.fsencode(link)
39909
5fe0b880200e py3: convert os.readlink() path to native strings on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39888
diff changeset
   640
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   641
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   642
def removedirs(name: bytes) -> None:
8364
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
   643
    """special version of os.removedirs that does not remove symlinked
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
   644
    directories or junction points if they actually contain files"""
32248
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31891
diff changeset
   645
    if listdir(name):
8364
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
   646
        return
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
   647
    os.rmdir(name)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
   648
    head, tail = os.path.split(name)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
   649
    if not tail:
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
   650
        head, tail = os.path.split(head)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
   651
    while head and tail:
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
   652
        try:
32248
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31891
diff changeset
   653
            if listdir(head):
8364
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
   654
                return
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
   655
            os.rmdir(head)
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13986
diff changeset
   656
        except (ValueError, OSError):
8364
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
   657
            break
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
   658
        head, tail = os.path.split(head)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
   659
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   660
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   661
def rename(src: bytes, dst: bytes) -> None:
9549
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
   662
    '''atomically rename file src to dst, replacing dst if it exists'''
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
   663
    try:
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
   664
        os.rename(src, dst)
49313
53e9422a9b45 py3: catch FileExistsError instead of checking errno == EEXIST
Manuel Jacob <me@manueljacob.de>
parents: 49065
diff changeset
   665
    except FileExistsError:
13280
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
   666
        unlink(dst)
9549
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
   667
        os.rename(src, dst)
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
   668
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   669
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   670
def gethgcmd() -> List[bytes]:
39735
255d1885c7f8 py3: resolve Unicode issues around `hg serve` on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39660
diff changeset
   671
    return [encoding.strtolocal(arg) for arg in [sys.executable] + sys.argv[:1]]
10239
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10237
diff changeset
   672
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   673
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   674
def groupmembers(name: bytes) -> List[bytes]:
11138
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11010
diff changeset
   675
    # Don't support groups on Windows for now
16687
e34106fa0dc3 cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents: 16076
diff changeset
   676
    raise KeyError
11138
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11010
diff changeset
   677
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   678
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   679
def isexec(f: bytes) -> bool:
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14892
diff changeset
   680
    return False
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14892
diff changeset
   681
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   682
49037
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48990
diff changeset
   683
class cachestat:
49910
464fe8b8f474 typing: add type hints to the platform `cachestat` classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 49907
diff changeset
   684
    def __init__(self, path: bytes) -> None:
14927
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   685
        pass
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   686
49910
464fe8b8f474 typing: add type hints to the platform `cachestat` classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 49907
diff changeset
   687
    def cacheable(self) -> bool:
14927
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   688
        return False
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   689
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   690
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   691
def lookupreg(
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   692
    key: bytes,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   693
    valname: Optional[bytes] = None,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   694
    scope: Optional[Union[int, Iterable[int]]] = None,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   695
) -> Optional[bytes]:
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45158
diff changeset
   696
    """Look up a key/value name in the Windows registry.
16807
80142f385af9 win32: move lookupreg() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 16687
diff changeset
   697
80142f385af9 win32: move lookupreg() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 16687
diff changeset
   698
    valname: value name. If unspecified, the default value for the key
80142f385af9 win32: move lookupreg() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 16687
diff changeset
   699
    is used.
80142f385af9 win32: move lookupreg() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 16687
diff changeset
   700
    scope: optionally specify scope for registry lookup, this can be
80142f385af9 win32: move lookupreg() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 16687
diff changeset
   701
    a sequence of scopes to look up in order. Default (CURRENT_USER,
80142f385af9 win32: move lookupreg() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 16687
diff changeset
   702
    LOCAL_MACHINE).
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45158
diff changeset
   703
    """
16807
80142f385af9 win32: move lookupreg() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 16687
diff changeset
   704
    if scope is None:
49065
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 49037
diff changeset
   705
        # pytype: disable=module-attr
29772
3df9f780c90e py3: conditionalize _winreg import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29530
diff changeset
   706
        scope = (winreg.HKEY_CURRENT_USER, winreg.HKEY_LOCAL_MACHINE)
49065
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 49037
diff changeset
   707
        # pytype: enable=module-attr
16807
80142f385af9 win32: move lookupreg() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 16687
diff changeset
   708
    elif not isinstance(scope, (list, tuple)):
80142f385af9 win32: move lookupreg() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 16687
diff changeset
   709
        scope = (scope,)
80142f385af9 win32: move lookupreg() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 16687
diff changeset
   710
    for s in scope:
80142f385af9 win32: move lookupreg() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 16687
diff changeset
   711
        try:
49065
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 49037
diff changeset
   712
            # pytype: disable=module-attr
39659
47ac5d93d708 windows: open registry keys using unicode names
Matt Harbison <matt_harbison@yahoo.com>
parents: 38725
diff changeset
   713
            with winreg.OpenKey(s, encoding.strfromlocal(key)) as hkey:
49065
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 49037
diff changeset
   714
                # pytype: enable=module-attr
49323
709e5f7eec1f windows: prevent bytes from being passed to registry APIs
Matt Harbison <matt_harbison@yahoo.com>
parents: 49319
diff changeset
   715
                name = None
709e5f7eec1f windows: prevent bytes from being passed to registry APIs
Matt Harbison <matt_harbison@yahoo.com>
parents: 49319
diff changeset
   716
                if valname is not None:
709e5f7eec1f windows: prevent bytes from being passed to registry APIs
Matt Harbison <matt_harbison@yahoo.com>
parents: 49319
diff changeset
   717
                    name = encoding.strfromlocal(valname)
49065
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 49037
diff changeset
   718
                # pytype: disable=module-attr
40266
ab04ce6f0674 py3: use str to query registry values on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39915
diff changeset
   719
                val = winreg.QueryValueEx(hkey, name)[0]
49065
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 49037
diff changeset
   720
                # pytype: enable=module-attr
d500df2e8034 pytype: disable a few errors about Windows specific module attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 49037
diff changeset
   721
39659
47ac5d93d708 windows: open registry keys using unicode names
Matt Harbison <matt_harbison@yahoo.com>
parents: 38725
diff changeset
   722
                # never let a Unicode string escape into the wild
47ac5d93d708 windows: open registry keys using unicode names
Matt Harbison <matt_harbison@yahoo.com>
parents: 38725
diff changeset
   723
                return encoding.unitolocal(val)
16807
80142f385af9 win32: move lookupreg() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 16687
diff changeset
   724
        except EnvironmentError:
80142f385af9 win32: move lookupreg() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 16687
diff changeset
   725
            pass
80142f385af9 win32: move lookupreg() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 16687
diff changeset
   726
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   727
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   728
expandglobs: bool = True
18868
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18143
diff changeset
   729
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   730
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   731
def statislink(st: Optional[os.stat_result]) -> bool:
18868
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18143
diff changeset
   732
    '''check whether a stat result is a symlink'''
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18143
diff changeset
   733
    return False
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18143
diff changeset
   734
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   735
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   736
def statisexec(st: Optional[os.stat_result]) -> bool:
18868
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18143
diff changeset
   737
    '''check whether a stat result is an executable file'''
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18143
diff changeset
   738
    return False
22245
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   739
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   740
49912
2b1476714849 typing: add trivial type hints to rest of the windows platform module
Matt Harbison <matt_harbison@yahoo.com>
parents: 49910
diff changeset
   741
def poll(fds) -> List:
25420
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25204
diff changeset
   742
    # see posix.py for description
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25204
diff changeset
   743
    raise NotImplementedError()
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25204
diff changeset
   744
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   745
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   746
def readpipe(pipe) -> bytes:
22245
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   747
    """Read all available data from a pipe."""
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   748
    chunks = []
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   749
    while True:
24653
83f6c4733ecc windows: allow readpipe() to actually read data out of the pipe
Matt Harbison <matt_harbison@yahoo.com>
parents: 24598
diff changeset
   750
        size = win32.peekpipe(pipe)
22245
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   751
        if not size:
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   752
            break
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   753
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   754
        s = pipe.read(size)
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   755
        if not s:
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   756
            break
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   757
        chunks.append(s)
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   758
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   759
    return b''.join(chunks)
29530
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27436
diff changeset
   760
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41289
diff changeset
   761
49907
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49895
diff changeset
   762
def bindunixsocket(sock, path: bytes) -> NoReturn:
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
   763
    raise NotImplementedError('unsupported platform')