mercurial/vfs.py
author Anton Shestakov <av6@dwimlabs.net>
Sun, 11 Dec 2022 16:46:29 +0400
branchstable
changeset 49783 3bbf1ad850f0
parent 49306 2e726c934fcd
child 49573 cc9a60050a07
permissions -rw-r--r--
hghave: we might need py310 and py311 at some point Some tests are already showing slightly different results on Python 3.11. The better idea would be to make them more portable, but if that's not possible, now we can use hghave detection for certain lines. I wonder if there will ever be Python 31.0 and 31.1 though.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
31217
0f31830fbfc4 vfs: extract 'vfs' class and related code to a new 'vfs' module (API)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31025
diff changeset
     1
# vfs.py - Mercurial 'vfs' classes
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     2
#
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 45942
diff changeset
     3
#  Copyright Olivia Mackall <olivia@selenic.com>
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     4
#
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
27482
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
     7
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
     8
import contextlib
27482
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
     9
import os
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    10
import shutil
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    11
import stat
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
    12
import threading
27482
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    13
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    14
from .i18n import _
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43087
diff changeset
    15
from .pycompat import (
43090
1f339b503a40 py3: manually import pycompat.delattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43089
diff changeset
    16
    delattr,
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43087
diff changeset
    17
    getattr,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43087
diff changeset
    18
    setattr,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43087
diff changeset
    19
)
27482
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    20
from . import (
34022
d5b2beca16c0 python3: wrap all uses of <exception>.strerror with strtolocal
Augie Fackler <raf@durin42.com>
parents: 33649
diff changeset
    21
    encoding,
27482
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    22
    error,
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    23
    pathutil,
30305
af7c60988f6e py3: make scmutil.rcpath() return bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30109
diff changeset
    24
    pycompat,
27482
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    25
    util,
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    26
)
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents: 18678
diff changeset
    27
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
    28
33280
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    29
def _avoidambig(path, oldstat):
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    30
    """Avoid file stat ambiguity forcibly
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    31
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    32
    This function causes copying ``path`` file, if it is owned by
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    33
    another (see issue5418 and issue5584 for detail).
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    34
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
    35
33280
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    36
    def checkandavoid():
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    37
        newstat = util.filestat.frompath(path)
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    38
        # return whether file stat ambiguity is (already) avoided
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
    39
        return not newstat.isambig(oldstat) or newstat.avoidambig(path, oldstat)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
    40
33280
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    41
    if not checkandavoid():
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    42
        # simply copy to change owner of path to get privilege to
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    43
        # advance mtime (see issue5418)
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    44
        util.rename(util.mktempcopy(path), path)
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    45
        checkandavoid()
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    46
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
    47
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
    48
class abstractvfs:
14089
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
    49
    """Abstract base class; cannot be instantiated"""
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
    50
47809
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
    51
    # default directory separator for vfs
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
    52
    #
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
    53
    # Other vfs code always use `/` and this works fine because python file API
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
    54
    # abstract the use of `/` and make it work transparently. For consistency
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
    55
    # vfs will always use `/` when joining. This avoid some confusion in
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
    56
    # encoded vfs (see issue6546)
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
    57
    _dir_sep = b'/'
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
    58
14089
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
    59
    def __init__(self, *args, **kwargs):
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
    60
        '''Prevent instantiation; don't call this from subclasses.'''
43466
2dcd4e773193 vfs: fix erroneous bytes constants
Augie Fackler <augie@google.com>
parents: 43462
diff changeset
    61
        raise NotImplementedError('attempted instantiating ' + str(type(self)))
14089
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
    62
43467
b16912f8c07c vfs: add a NotImplementedError implementation of __call__
Augie Fackler <augie@google.com>
parents: 43466
diff changeset
    63
    def __call__(self, path, mode=b'rb', **kwargs):
b16912f8c07c vfs: add a NotImplementedError implementation of __call__
Augie Fackler <augie@google.com>
parents: 43466
diff changeset
    64
        raise NotImplementedError
b16912f8c07c vfs: add a NotImplementedError implementation of __call__
Augie Fackler <augie@google.com>
parents: 43466
diff changeset
    65
41091
d9b6b9ed96d8 vfs: add a `_auditpath` to abstract vfs
Boris Feld <boris.feld@octobus.net>
parents: 41090
diff changeset
    66
    def _auditpath(self, path, mode):
41095
e0d00ec2d614 vfs: raise NotImplementedError in abstractvfs._auditvfs
Boris Feld <boris.feld@octobus.net>
parents: 41094
diff changeset
    67
        raise NotImplementedError
41091
d9b6b9ed96d8 vfs: add a `_auditpath` to abstract vfs
Boris Feld <boris.feld@octobus.net>
parents: 41090
diff changeset
    68
43468
8b0fa4de0064 vfs: add NotImplementedError version of join
Augie Fackler <augie@google.com>
parents: 43467
diff changeset
    69
    def join(self, path, *insidef):
8b0fa4de0064 vfs: add NotImplementedError version of join
Augie Fackler <augie@google.com>
parents: 43467
diff changeset
    70
        raise NotImplementedError
8b0fa4de0064 vfs: add NotImplementedError version of join
Augie Fackler <augie@google.com>
parents: 43467
diff changeset
    71
16455
154219f3a6a4 opener: introduce tryread helper
Matt Mackall <mpm@selenic.com>
parents: 16436
diff changeset
    72
    def tryread(self, path):
16479
fc04698fa778 opener: coding style, use triple quotes for doc string
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16455
diff changeset
    73
        '''gracefully return an empty string for missing files'''
16455
154219f3a6a4 opener: introduce tryread helper
Matt Mackall <mpm@selenic.com>
parents: 16436
diff changeset
    74
        try:
154219f3a6a4 opener: introduce tryread helper
Matt Mackall <mpm@selenic.com>
parents: 16436
diff changeset
    75
            return self.read(path)
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
    76
        except FileNotFoundError:
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
    77
            pass
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    78
        return b""
16455
154219f3a6a4 opener: introduce tryread helper
Matt Mackall <mpm@selenic.com>
parents: 16436
diff changeset
    79
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    80
    def tryreadlines(self, path, mode=b'rb'):
23368
bf8c3172255c vfs: add "readlines" and "tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23259
diff changeset
    81
        '''gracefully return an empty array for missing files'''
bf8c3172255c vfs: add "readlines" and "tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23259
diff changeset
    82
        try:
bf8c3172255c vfs: add "readlines" and "tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23259
diff changeset
    83
            return self.readlines(path, mode=mode)
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
    84
        except FileNotFoundError:
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
    85
            pass
23368
bf8c3172255c vfs: add "readlines" and "tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23259
diff changeset
    86
        return []
bf8c3172255c vfs: add "readlines" and "tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23259
diff changeset
    87
29718
2dd8c225e94c vfs: use propertycache for open
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29714
diff changeset
    88
    @util.propertycache
2dd8c225e94c vfs: use propertycache for open
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29714
diff changeset
    89
    def open(self):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
    90
        """Open ``path`` file, which is relative to vfs root.
23370
46265d0f0c7b vfs: add "notindexed" argument to invoke "ensuredir" with it in write mode
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23368
diff changeset
    91
46265d0f0c7b vfs: add "notindexed" argument to invoke "ensuredir" with it in write mode
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23368
diff changeset
    92
        Newly created directories are marked as "not to be indexed by
46265d0f0c7b vfs: add "notindexed" argument to invoke "ensuredir" with it in write mode
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23368
diff changeset
    93
        the content indexing service", if ``notindexed`` is specified
46265d0f0c7b vfs: add "notindexed" argument to invoke "ensuredir" with it in write mode
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23368
diff changeset
    94
        for "write" mode access.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
    95
        """
29718
2dd8c225e94c vfs: use propertycache for open
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29714
diff changeset
    96
        return self.__call__
19897
896a4568def7 vfs: add "open()" for newly added code paths which open files via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19896
diff changeset
    97
14167
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
    98
    def read(self, path):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    99
        with self(path, b'rb') as fp:
14097
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   100
            return fp.read()
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   101
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   102
    def readlines(self, path, mode=b'rb'):
27706
22e362da27cf scmutil: use context managers for file handles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27651
diff changeset
   103
        with self(path, mode=mode) as fp:
23368
bf8c3172255c vfs: add "readlines" and "tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23259
diff changeset
   104
            return fp.readlines()
bf8c3172255c vfs: add "readlines" and "tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23259
diff changeset
   105
35725
2a7e777c9eed write: add the possibility to pass keyword argument from batchget to vfs
Boris Feld <boris.feld@octobus.net>
parents: 35625
diff changeset
   106
    def write(self, path, data, backgroundclose=False, **kwargs):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   107
        with self(path, b'wb', backgroundclose=backgroundclose, **kwargs) as fp:
14167
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   108
            return fp.write(data)
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   109
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   110
    def writelines(self, path, data, mode=b'wb', notindexed=False):
27706
22e362da27cf scmutil: use context managers for file handles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27651
diff changeset
   111
        with self(path, mode=mode, notindexed=notindexed) as fp:
23371
1df6519eb3ab vfs: add "writelines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23370
diff changeset
   112
            return fp.writelines(data)
1df6519eb3ab vfs: add "writelines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23370
diff changeset
   113
14167
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   114
    def append(self, path, data):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   115
        with self(path, b'ab') as fp:
14097
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   116
            return fp.write(data)
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   117
25770
39de2e9cc6f4 vfs: add basename
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25739
diff changeset
   118
    def basename(self, path):
39de2e9cc6f4 vfs: add basename
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25739
diff changeset
   119
        """return base element of a path (as os.path.basename would do)
39de2e9cc6f4 vfs: add basename
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25739
diff changeset
   120
39de2e9cc6f4 vfs: add basename
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25739
diff changeset
   121
        This exists to allow handling of strange encoding if needed."""
39de2e9cc6f4 vfs: add basename
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25739
diff changeset
   122
        return os.path.basename(path)
39de2e9cc6f4 vfs: add basename
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25739
diff changeset
   123
20086
f3df2612f3c3 vfs: add "chmod()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20085
diff changeset
   124
    def chmod(self, path, mode):
f3df2612f3c3 vfs: add "chmod()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20085
diff changeset
   125
        return os.chmod(self.join(path), mode)
f3df2612f3c3 vfs: add "chmod()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20085
diff changeset
   126
25772
5471965af5cb vfs: add dirname
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25770
diff changeset
   127
    def dirname(self, path):
5471965af5cb vfs: add dirname
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25770
diff changeset
   128
        """return dirname element of a path (as os.path.dirname would do)
5471965af5cb vfs: add dirname
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25770
diff changeset
   129
5471965af5cb vfs: add dirname
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25770
diff changeset
   130
        This exists to allow handling of strange encoding if needed."""
5471965af5cb vfs: add dirname
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25770
diff changeset
   131
        return os.path.dirname(path)
5471965af5cb vfs: add dirname
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25770
diff changeset
   132
17161
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   133
    def exists(self, path=None):
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   134
        return os.path.exists(self.join(path))
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   135
19899
8c3dcbbfb5de changelog: use "vfs.fstat()" instead of "util.fstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19897
diff changeset
   136
    def fstat(self, fp):
8c3dcbbfb5de changelog: use "vfs.fstat()" instead of "util.fstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19897
diff changeset
   137
        return util.fstat(fp)
8c3dcbbfb5de changelog: use "vfs.fstat()" instead of "util.fstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19897
diff changeset
   138
17161
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   139
    def isdir(self, path=None):
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   140
        return os.path.isdir(self.join(path))
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   141
20085
589d6bb5b18d vfs: add "isfile()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20045
diff changeset
   142
    def isfile(self, path=None):
589d6bb5b18d vfs: add "isfile()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20045
diff changeset
   143
        return os.path.isfile(self.join(path))
589d6bb5b18d vfs: add "isfile()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20045
diff changeset
   144
18949
138978f20180 localrepo: use "vfs.islink()" instead of "os.path.islink()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18948
diff changeset
   145
    def islink(self, path=None):
138978f20180 localrepo: use "vfs.islink()" instead of "os.path.islink()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18948
diff changeset
   146
        return os.path.islink(self.join(path))
138978f20180 localrepo: use "vfs.islink()" instead of "os.path.islink()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18948
diff changeset
   147
27571
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   148
    def isfileorlink(self, path=None):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   149
        """return whether path is a regular file or a symlink
27571
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   150
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   151
        Unlike isfile, this doesn't follow symlinks."""
27571
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   152
        try:
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   153
            st = self.lstat(path)
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   154
        except OSError:
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   155
            return False
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   156
        mode = st.st_mode
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   157
        return stat.S_ISREG(mode) or stat.S_ISLNK(mode)
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   158
47809
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   159
    def _join(self, *paths):
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   160
        root_idx = 0
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   161
        for idx, p in enumerate(paths):
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   162
            if os.path.isabs(p) or p.startswith(self._dir_sep):
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   163
                root_idx = idx
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   164
        if root_idx != 0:
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   165
            paths = paths[root_idx:]
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   166
        paths = [p for p in paths if p]
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   167
        return self._dir_sep.join(paths)
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   168
23581
aed981c7bebf vfs: add a 'reljoin' function for joining relative paths
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23539
diff changeset
   169
    def reljoin(self, *paths):
aed981c7bebf vfs: add a 'reljoin' function for joining relative paths
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23539
diff changeset
   170
        """join various elements of a path together (as os.path.join would do)
aed981c7bebf vfs: add a 'reljoin' function for joining relative paths
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23539
diff changeset
   171
aed981c7bebf vfs: add a 'reljoin' function for joining relative paths
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23539
diff changeset
   172
        The vfs base is not injected so that path stay relative. This exists
aed981c7bebf vfs: add a 'reljoin' function for joining relative paths
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23539
diff changeset
   173
        to allow handling of strange encoding if needed."""
47809
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   174
        return self._join(*paths)
23581
aed981c7bebf vfs: add a 'reljoin' function for joining relative paths
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23539
diff changeset
   175
23582
7559dc8c4238 vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23581
diff changeset
   176
    def split(self, path):
7559dc8c4238 vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23581
diff changeset
   177
        """split top-most element of a path (as os.path.split would do)
7559dc8c4238 vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23581
diff changeset
   178
7559dc8c4238 vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23581
diff changeset
   179
        This exists to allow handling of strange encoding if needed."""
7559dc8c4238 vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23581
diff changeset
   180
        return os.path.split(path)
7559dc8c4238 vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23581
diff changeset
   181
21563
764b691b8bda vfs: add lexists() in current api
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21111
diff changeset
   182
    def lexists(self, path=None):
764b691b8bda vfs: add lexists() in current api
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21111
diff changeset
   183
        return os.path.lexists(self.join(path))
764b691b8bda vfs: add lexists() in current api
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21111
diff changeset
   184
19900
7c21e3398931 context: use "vfs.lstat()" instead of "os.lstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19899
diff changeset
   185
    def lstat(self, path=None):
7c21e3398931 context: use "vfs.lstat()" instead of "os.lstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19899
diff changeset
   186
        return os.lstat(self.join(path))
7c21e3398931 context: use "vfs.lstat()" instead of "os.lstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19899
diff changeset
   187
21799
dfacdd6a111e vfs: add listdir for os.listdir in vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21716
diff changeset
   188
    def listdir(self, path=None):
dfacdd6a111e vfs: add listdir for os.listdir in vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21716
diff changeset
   189
        return os.listdir(self.join(path))
dfacdd6a111e vfs: add listdir for os.listdir in vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21716
diff changeset
   190
17161
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   191
    def makedir(self, path=None, notindexed=True):
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   192
        return util.makedir(self.join(path), notindexed)
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   193
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   194
    def makedirs(self, path=None, mode=None):
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   195
        return util.makedirs(self.join(path), mode)
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   196
20090
88d8e568add1 vfs: add "makelock()" and "readlock()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20086
diff changeset
   197
    def makelock(self, info, path):
88d8e568add1 vfs: add "makelock()" and "readlock()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20086
diff changeset
   198
        return util.makelock(info, self.join(path))
88d8e568add1 vfs: add "makelock()" and "readlock()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20086
diff changeset
   199
17723
ab23768746fd scmutil: reorder newly added functions for vfs support in dictionary order
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17681
diff changeset
   200
    def mkdir(self, path=None):
ab23768746fd scmutil: reorder newly added functions for vfs support in dictionary order
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17681
diff changeset
   201
        return os.mkdir(self.join(path))
ab23768746fd scmutil: reorder newly added functions for vfs support in dictionary order
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17681
diff changeset
   202
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   203
    def mkstemp(self, suffix=b'', prefix=b'tmp', dir=None):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   204
        fd, name = pycompat.mkstemp(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   205
            suffix=suffix, prefix=prefix, dir=self.join(dir)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   206
        )
20980
6fb4c94ae300 vfs: add "mkstemp()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20862
diff changeset
   207
        dname, fname = util.split(name)
6fb4c94ae300 vfs: add "mkstemp()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20862
diff changeset
   208
        if dir:
6fb4c94ae300 vfs: add "mkstemp()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20862
diff changeset
   209
            return fd, os.path.join(dir, fname)
6fb4c94ae300 vfs: add "mkstemp()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20862
diff changeset
   210
        else:
6fb4c94ae300 vfs: add "mkstemp()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20862
diff changeset
   211
            return fd, fname
6fb4c94ae300 vfs: add "mkstemp()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20862
diff changeset
   212
17747
aad3bce98f76 store: invoke "osutil.listdir()" via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17726
diff changeset
   213
    def readdir(self, path=None, stat=None, skip=None):
32208
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31644
diff changeset
   214
        return util.listdir(self.join(path), stat, skip)
17747
aad3bce98f76 store: invoke "osutil.listdir()" via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17726
diff changeset
   215
20090
88d8e568add1 vfs: add "makelock()" and "readlock()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20086
diff changeset
   216
    def readlock(self, path):
88d8e568add1 vfs: add "makelock()" and "readlock()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20086
diff changeset
   217
        return util.readlock(self.join(path))
88d8e568add1 vfs: add "makelock()" and "readlock()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20086
diff changeset
   218
29203
731ced087a4b vfs: make rename avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29202
diff changeset
   219
    def rename(self, src, dst, checkambig=False):
29367
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   220
        """Rename from src to dst
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   221
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   222
        checkambig argument is used with util.filestat, and is useful
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   223
        only if destination file is guarded by any lock
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   224
        (e.g. repo.lock or repo.wlock).
33282
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   225
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   226
        To avoid file stat ambiguity forcibly, checkambig=True involves
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   227
        copying ``src`` file, if it is owned by another. Therefore, use
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   228
        checkambig=True only in limited cases (see also issue5418 and
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   229
        issue5584 for detail).
29367
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   230
        """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   231
        self._auditpath(dst, b'w')
32748
ed66ec39933f vfs: create copy at renaming to avoid file stat ambiguity if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32747
diff changeset
   232
        srcpath = self.join(src)
29203
731ced087a4b vfs: make rename avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29202
diff changeset
   233
        dstpath = self.join(dst)
32772
7ad95626f6a7 filestat: move __init__ to frompath constructor
Siddharth Agarwal <sid0@fb.com>
parents: 32748
diff changeset
   234
        oldstat = checkambig and util.filestat.frompath(dstpath)
29203
731ced087a4b vfs: make rename avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29202
diff changeset
   235
        if oldstat and oldstat.stat:
33281
6af0f023d014 vfs: replace avoiding ambiguity in abstractvfs.rename with _avoidambig
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33280
diff changeset
   236
            ret = util.rename(srcpath, dstpath)
6af0f023d014 vfs: replace avoiding ambiguity in abstractvfs.rename with _avoidambig
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33280
diff changeset
   237
            _avoidambig(dstpath, oldstat)
29203
731ced087a4b vfs: make rename avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29202
diff changeset
   238
            return ret
32748
ed66ec39933f vfs: create copy at renaming to avoid file stat ambiguity if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32747
diff changeset
   239
        return util.rename(srcpath, dstpath)
18948
2f05fa162316 localrepo: use "vfs.rename()" instead of "util.rename()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18945
diff changeset
   240
18950
647e3b0c8751 localrepo: use "vfs.readlink()" instead of "os.readlink()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18949
diff changeset
   241
    def readlink(self, path):
39904
5fe0b880200e py3: convert os.readlink() path to native strings on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39464
diff changeset
   242
        return util.readlink(self.join(path))
18950
647e3b0c8751 localrepo: use "vfs.readlink()" instead of "os.readlink()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18949
diff changeset
   243
24693
0d28b0df77ea vfs: add removedirs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24689
diff changeset
   244
    def removedirs(self, path=None):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   245
        """Remove a leaf directory and all empty intermediate ones"""
24693
0d28b0df77ea vfs: add removedirs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24689
diff changeset
   246
        return util.removedirs(self.join(path))
0d28b0df77ea vfs: add removedirs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24689
diff changeset
   247
39464
3dd34b401bc2 merge: use vfs methods for I/O
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38493
diff changeset
   248
    def rmdir(self, path=None):
3dd34b401bc2 merge: use vfs methods for I/O
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38493
diff changeset
   249
        """Remove an empty directory."""
3dd34b401bc2 merge: use vfs methods for I/O
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38493
diff changeset
   250
        return os.rmdir(self.join(path))
3dd34b401bc2 merge: use vfs methods for I/O
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38493
diff changeset
   251
24689
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   252
    def rmtree(self, path=None, ignore_errors=False, forcibly=False):
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   253
        """Remove a directory tree recursively
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   254
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   255
        If ``forcibly``, this tries to remove READ-ONLY files, too.
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   256
        """
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   257
        if forcibly:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   258
24689
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   259
            def onerror(function, path, excinfo):
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   260
                if function is not os.remove:
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   261
                    raise
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   262
                # read-only files cannot be unlinked under Windows
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   263
                s = os.stat(path)
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   264
                if (s.st_mode & stat.S_IWRITE) != 0:
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   265
                    raise
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   266
                os.chmod(path, stat.S_IMODE(s.st_mode) | stat.S_IWRITE)
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   267
                os.remove(path)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   268
24689
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   269
        else:
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   270
            onerror = None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   271
        return shutil.rmtree(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   272
            self.join(path), ignore_errors=ignore_errors, onerror=onerror
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   273
        )
24689
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   274
18951
d13916a00b7e localrepo: use "vfs.setflags()" instead of "util.setflags()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18950
diff changeset
   275
    def setflags(self, path, l, x):
d13916a00b7e localrepo: use "vfs.setflags()" instead of "util.setflags()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18950
diff changeset
   276
        return util.setflags(self.join(path), l, x)
d13916a00b7e localrepo: use "vfs.setflags()" instead of "util.setflags()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18950
diff changeset
   277
17726
7cb7e17c23b2 store: invoke "os.stat()" for "createmode" initialization via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17725
diff changeset
   278
    def stat(self, path=None):
7cb7e17c23b2 store: invoke "os.stat()" for "createmode" initialization via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17725
diff changeset
   279
        return os.stat(self.join(path))
7cb7e17c23b2 store: invoke "os.stat()" for "createmode" initialization via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17725
diff changeset
   280
19895
37c0d93fb166 bookmarks: use "vfs.unlink()" instead of "util.unlink()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19655
diff changeset
   281
    def unlink(self, path=None):
37c0d93fb166 bookmarks: use "vfs.unlink()" instead of "util.unlink()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19655
diff changeset
   282
        return util.unlink(self.join(path))
37c0d93fb166 bookmarks: use "vfs.unlink()" instead of "util.unlink()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19655
diff changeset
   283
31542
fad440db3565 vfs: add tryunlink method
Ryan McElroy <rmcelroy@fb.com>
parents: 31309
diff changeset
   284
    def tryunlink(self, path=None):
fad440db3565 vfs: add tryunlink method
Ryan McElroy <rmcelroy@fb.com>
parents: 31309
diff changeset
   285
        """Attempt to remove a file, ignoring missing file errors."""
fad440db3565 vfs: add tryunlink method
Ryan McElroy <rmcelroy@fb.com>
parents: 31309
diff changeset
   286
        util.tryunlink(self.join(path))
fad440db3565 vfs: add tryunlink method
Ryan McElroy <rmcelroy@fb.com>
parents: 31309
diff changeset
   287
38493
da2a7d8354b2 unlinkpath: make empty directory removal optional (issue5901) (issue5826)
Kyle Lippincott <spectral@google.com>
parents: 38164
diff changeset
   288
    def unlinkpath(self, path=None, ignoremissing=False, rmdir=True):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   289
        return util.unlinkpath(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   290
            self.join(path), ignoremissing=ignoremissing, rmdir=rmdir
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   291
        )
21716
90f9be5adade vfs: add unlinkpath to vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21563
diff changeset
   292
19896
af03279c766a bookmarks: use "vfs.utime()" instead of "os.utime()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19895
diff changeset
   293
    def utime(self, path=None, t=None):
af03279c766a bookmarks: use "vfs.utime()" instead of "os.utime()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19895
diff changeset
   294
        return os.utime(self.join(path), t)
af03279c766a bookmarks: use "vfs.utime()" instead of "os.utime()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19895
diff changeset
   295
24725
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   296
    def walk(self, path=None, onerror=None):
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   297
        """Yield (dirpath, dirs, files) tuple for each directories under path
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   298
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   299
        ``dirpath`` is relative one from the root of this vfs. This
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   300
        uses ``os.sep`` as path separator, even you specify POSIX
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   301
        style ``path``.
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   302
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   303
        "The root of this vfs" is represented as empty ``dirpath``.
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   304
        """
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   305
        root = os.path.normpath(self.join(None))
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   306
        # when dirpath == root, dirpath[prefixlen:] becomes empty
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   307
        # because len(dirpath) < prefixlen.
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   308
        prefixlen = len(pathutil.normasprefix(root))
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   309
        for dirpath, dirs, files in os.walk(self.join(path), onerror=onerror):
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   310
            yield (dirpath[prefixlen:], dirs, files)
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   311
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   312
    @contextlib.contextmanager
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   313
    def backgroundclosing(self, ui, expectedcount=-1):
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   314
        """Allow files to be closed asynchronously.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   315
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   316
        When this context manager is active, ``backgroundclose`` can be passed
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   317
        to ``__call__``/``open`` to result in the file possibly being closed
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   318
        asynchronously, on a background thread.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   319
        """
35426
60f2a215faa7 workers: don't use backgroundfilecloser in threads
Wojciech Lis <wlis@fb.com>
parents: 34645
diff changeset
   320
        # Sharing backgroundfilecloser between threads is complex and using
60f2a215faa7 workers: don't use backgroundfilecloser in threads
Wojciech Lis <wlis@fb.com>
parents: 34645
diff changeset
   321
        # multiple instances puts us at risk of running out of file descriptors
60f2a215faa7 workers: don't use backgroundfilecloser in threads
Wojciech Lis <wlis@fb.com>
parents: 34645
diff changeset
   322
        # only allow to use backgroundfilecloser when in main thread.
43482
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   323
        if not isinstance(
47178
63286e0886a6 vfs: Fix deprecation warning in Python 3.10 (issue6520)
Karthikeyan Singaravelan <tir.karthi@gmail.com>
parents: 46819
diff changeset
   324
            threading.current_thread(),
43482
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   325
            threading._MainThread,  # pytype: disable=module-attr
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   326
        ):
35426
60f2a215faa7 workers: don't use backgroundfilecloser in threads
Wojciech Lis <wlis@fb.com>
parents: 34645
diff changeset
   327
            yield
60f2a215faa7 workers: don't use backgroundfilecloser in threads
Wojciech Lis <wlis@fb.com>
parents: 34645
diff changeset
   328
            return
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   329
        vfs = getattr(self, 'vfs', self)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   330
        if getattr(vfs, '_backgroundfilecloser', None):
29389
98e8313dcd9e i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents: 29373
diff changeset
   331
            raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   332
                _(b'can only have 1 active background file closer')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   333
            )
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   334
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   335
        with backgroundfilecloser(ui, expectedcount=expectedcount) as bfc:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   336
            try:
43482
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   337
                vfs._backgroundfilecloser = (
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   338
                    bfc  # pytype: disable=attribute-error
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   339
                )
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   340
                yield bfc
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   341
            finally:
43482
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   342
                vfs._backgroundfilecloser = (
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   343
                    None  # pytype: disable=attribute-error
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   344
                )
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   345
47443
9ab54aa56982 vfs: add a `register_file` method on the vfs class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47178
diff changeset
   346
    def register_file(self, path):
9ab54aa56982 vfs: add a `register_file` method on the vfs class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47178
diff changeset
   347
        """generic hook point to lets fncache steer its stew"""
9ab54aa56982 vfs: add a `register_file` method on the vfs class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47178
diff changeset
   348
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   349
17649
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   350
class vfs(abstractvfs):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   351
    """Operate files relative to a base directory
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   352
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   353
    This class is used to hide the details of COW semantics and
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   354
    remote file access from higher level code.
33649
377e8ddaebef pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents: 33435
diff changeset
   355
377e8ddaebef pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents: 33435
diff changeset
   356
    'cacheaudited' should be enabled only if (a) vfs object is short-lived, or
377e8ddaebef pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents: 33435
diff changeset
   357
    (b) the base directory is managed by hg and considered sort-of append-only.
377e8ddaebef pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents: 33435
diff changeset
   358
    See pathutil.pathauditor() for details.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   359
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   360
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   361
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   362
        self,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   363
        base,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   364
        audit=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   365
        cacheaudited=False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   366
        expandpath=False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   367
        realpath=False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   368
    ):
18945
e75b72fffdfe vfs: split "expand" into "realpath"/"expandpath" to apply each separately
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18900
diff changeset
   369
        if expandpath:
e75b72fffdfe vfs: split "expand" into "realpath"/"expandpath" to apply each separately
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18900
diff changeset
   370
            base = util.expandpath(base)
e75b72fffdfe vfs: split "expand" into "realpath"/"expandpath" to apply each separately
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18900
diff changeset
   371
        if realpath:
e75b72fffdfe vfs: split "expand" into "realpath"/"expandpath" to apply each separately
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18900
diff changeset
   372
            base = os.path.realpath(base)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   373
        self.base = base
33259
6fb5c5096887 vfs: drop the 'mustaudit' API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33257
diff changeset
   374
        self._audit = audit
6fb5c5096887 vfs: drop the 'mustaudit' API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33257
diff changeset
   375
        if audit:
33649
377e8ddaebef pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents: 33435
diff changeset
   376
            self.audit = pathutil.pathauditor(self.base, cached=cacheaudited)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   377
        else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   378
            self.audit = lambda path, mode=None: True
33259
6fb5c5096887 vfs: drop the 'mustaudit' API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33257
diff changeset
   379
        self.createmode = None
6fb5c5096887 vfs: drop the 'mustaudit' API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33257
diff changeset
   380
        self._trustnlink = None
43025
3518da504303 vfs: give all vfs an options attribute by default
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 41095
diff changeset
   381
        self.options = {}
17554
5450c8ad9d98 scmutil: turn opener._audit into a property, mustaudit
Bryan O'Sullivan <bryano@fb.com>
parents: 17248
diff changeset
   382
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   383
    @util.propertycache
14261
e3649bcca3f6 opener: rename _can_symlink to _cansymlink
Adrian Buehlmann <adrian@cadifra.com>
parents: 14236
diff changeset
   384
    def _cansymlink(self):
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   385
        return util.checklink(self.base)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   386
18192
f9a89bdd64a6 scmutil: don't try to match modes on filesystems without modes (issue3740)
Matt Mackall <mpm@selenic.com>
parents: 17850
diff changeset
   387
    @util.propertycache
f9a89bdd64a6 scmutil: don't try to match modes on filesystems without modes (issue3740)
Matt Mackall <mpm@selenic.com>
parents: 17850
diff changeset
   388
    def _chmod(self):
f9a89bdd64a6 scmutil: don't try to match modes on filesystems without modes (issue3740)
Matt Mackall <mpm@selenic.com>
parents: 17850
diff changeset
   389
        return util.checkexec(self.base)
f9a89bdd64a6 scmutil: don't try to match modes on filesystems without modes (issue3740)
Matt Mackall <mpm@selenic.com>
parents: 17850
diff changeset
   390
17763
13070de77c86 vfs: backout fchmod change from 76b73ce0ffac
Matt Mackall <mpm@selenic.com>
parents: 17752
diff changeset
   391
    def _fixfilemode(self, name):
18192
f9a89bdd64a6 scmutil: don't try to match modes on filesystems without modes (issue3740)
Matt Mackall <mpm@selenic.com>
parents: 17850
diff changeset
   392
        if self.createmode is None or not self._chmod:
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   393
            return
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25629
diff changeset
   394
        os.chmod(name, self.createmode & 0o666)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   395
40754
34f15db81cf0 vfs: extract the audit path logic into a submethod
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   396
    def _auditpath(self, path, mode):
34f15db81cf0 vfs: extract the audit path logic into a submethod
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   397
        if self._audit:
41090
c8006a25b845 vfs: makes all audited path relative
Boris Feld <boris.feld@octobus.net>
parents: 40989
diff changeset
   398
            if os.path.isabs(path) and path.startswith(self.base):
c8006a25b845 vfs: makes all audited path relative
Boris Feld <boris.feld@octobus.net>
parents: 40989
diff changeset
   399
                path = os.path.relpath(path, self.base)
40754
34f15db81cf0 vfs: extract the audit path logic into a submethod
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   400
            r = util.checkosfilename(path)
34f15db81cf0 vfs: extract the audit path logic into a submethod
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   401
            if r:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   402
                raise error.Abort(b"%s: %r" % (r, path))
40754
34f15db81cf0 vfs: extract the audit path logic into a submethod
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   403
            self.audit(path, mode=mode)
34f15db81cf0 vfs: extract the audit path logic into a submethod
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   404
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   405
    def __call__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   406
        self,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   407
        path,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   408
        mode=b"r",
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   409
        atomictemp=False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   410
        notindexed=False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   411
        backgroundclose=False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   412
        checkambig=False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   413
        auditpath=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   414
        makeparentdirs=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   415
    ):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   416
        """Open ``path`` file, which is relative to vfs root.
23370
46265d0f0c7b vfs: add "notindexed" argument to invoke "ensuredir" with it in write mode
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23368
diff changeset
   417
40796
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   418
        By default, parent directories are created as needed. Newly created
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   419
        directories are marked as "not to be indexed by the content indexing
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   420
        service", if ``notindexed`` is specified for "write" mode access.
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   421
        Set ``makeparentdirs=False`` to not create directories implicitly.
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   422
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   423
        If ``backgroundclose`` is passed, the file may be closed asynchronously.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   424
        It can only be used if the ``self.backgroundclosing()`` context manager
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   425
        is active. This should only be specified if the following criteria hold:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   426
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   427
        1. There is a potential for writing thousands of files. Unless you
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   428
           are writing thousands of files, the performance benefits of
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   429
           asynchronously closing files is not realized.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   430
        2. Files are opened exactly once for the ``backgroundclosing``
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   431
           active duration and are therefore free of race conditions between
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   432
           closing a file on a background thread and reopening it. (If the
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   433
           file were opened multiple times, there could be unflushed data
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   434
           because the original file handle hasn't been flushed/closed yet.)
29202
76f1ea360c7e vfs: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29119
diff changeset
   435
44566
77d48738b8e0 vfs: fix typo in comment (remove extra "l")
Kyle Lippincott <spectral@google.com>
parents: 43506
diff changeset
   436
        ``checkambig`` argument is passed to atomictempfile (valid
29367
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   437
        only for writing), and is useful only if target file is
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   438
        guarded by any lock (e.g. repo.lock or repo.wlock).
33282
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   439
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   440
        To avoid file stat ambiguity forcibly, checkambig=True involves
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   441
        copying ``path`` file opened in "append" mode (e.g. for
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   442
        truncation), if it is owned by another. Therefore, use
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   443
        combination of append mode and checkambig=True only in limited
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   444
        cases (see also issue5418 and issue5584 for detail).
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   445
        """
33257
15e9cbe6ae49 vfs: simplify path audit disabling in stream clone
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33234
diff changeset
   446
        if auditpath:
40754
34f15db81cf0 vfs: extract the audit path logic into a submethod
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   447
            self._auditpath(path, mode)
16199
8181bd808dc5 scmutil: add join method to opener to construct path relative to base
Idan Kamara <idankk86@gmail.com>
parents: 16198
diff changeset
   448
        f = self.join(path)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   449
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   450
        if b"b" not in mode:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   451
            mode += b"b"  # for that other OS
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   452
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   453
        nlink = -1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   454
        if mode not in (b'r', b'rb'):
17937
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   455
            dirname, basename = util.split(f)
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   456
            # If basename is empty, then the path is malformed because it points
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   457
            # to a directory. Let the posixfile() call below raise IOError.
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   458
            if basename:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   459
                if atomictemp:
40796
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   460
                    if makeparentdirs:
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   461
                        util.makedirs(dirname, self.createmode, notindexed)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   462
                    return util.atomictempfile(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   463
                        f, mode, self.createmode, checkambig=checkambig
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   464
                    )
17937
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   465
                try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   466
                    if b'w' in mode:
17937
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   467
                        util.unlink(f)
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   468
                        nlink = 0
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   469
                    else:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   470
                        # nlinks() may behave differently for files on Windows
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   471
                        # shares if the file is open.
27706
22e362da27cf scmutil: use context managers for file handles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27651
diff changeset
   472
                        with util.posixfile(f):
22e362da27cf scmutil: use context managers for file handles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27651
diff changeset
   473
                            nlink = util.nlinks(f)
22e362da27cf scmutil: use context managers for file handles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27651
diff changeset
   474
                            if nlink < 1:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   475
                                nlink = 2  # force mktempcopy (issue1922)
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
   476
                except FileNotFoundError:
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   477
                    nlink = 0
40796
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   478
                    if makeparentdirs:
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   479
                        util.makedirs(dirname, self.createmode, notindexed)
17937
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   480
                if nlink > 0:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   481
                    if self._trustnlink is None:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   482
                        self._trustnlink = nlink > 1 or util.checknlink(f)
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   483
                    if nlink > 1 or not self._trustnlink:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   484
                        util.rename(util.mktempcopy(f), f)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   485
        fp = util.posixfile(f, mode)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   486
        if nlink == 0:
17763
13070de77c86 vfs: backout fchmod change from 76b73ce0ffac
Matt Mackall <mpm@selenic.com>
parents: 17752
diff changeset
   487
            self._fixfilemode(f)
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   488
29996
9766d88c2465 vfs: use checkambigatclosing in checkambig=True but atomictemp=False case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29995
diff changeset
   489
        if checkambig:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   490
            if mode in (b'r', b'rb'):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   491
                raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   492
                    _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   493
                        b'implementation error: mode %s is not'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   494
                        b' valid for checkambig=True'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   495
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   496
                    % mode
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   497
                )
29996
9766d88c2465 vfs: use checkambigatclosing in checkambig=True but atomictemp=False case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29995
diff changeset
   498
            fp = checkambigatclosing(fp)
9766d88c2465 vfs: use checkambigatclosing in checkambig=True but atomictemp=False case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29995
diff changeset
   499
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   500
        if backgroundclose and isinstance(
47178
63286e0886a6 vfs: Fix deprecation warning in Python 3.10 (issue6520)
Karthikeyan Singaravelan <tir.karthi@gmail.com>
parents: 46819
diff changeset
   501
            threading.current_thread(),
43482
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   502
            threading._MainThread,  # pytype: disable=module-attr
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   503
        ):
43484
da9ecbb10368 vfs: more attribute suppressions
Augie Fackler <augie@google.com>
parents: 43482
diff changeset
   504
            if (
da9ecbb10368 vfs: more attribute suppressions
Augie Fackler <augie@google.com>
parents: 43482
diff changeset
   505
                not self._backgroundfilecloser  # pytype: disable=attribute-error
da9ecbb10368 vfs: more attribute suppressions
Augie Fackler <augie@google.com>
parents: 43482
diff changeset
   506
            ):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   507
                raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   508
                    _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   509
                        b'backgroundclose can only be used when a '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   510
                        b'backgroundclosing context manager is active'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   511
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   512
                )
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   513
43484
da9ecbb10368 vfs: more attribute suppressions
Augie Fackler <augie@google.com>
parents: 43482
diff changeset
   514
            fp = delayclosedfile(
da9ecbb10368 vfs: more attribute suppressions
Augie Fackler <augie@google.com>
parents: 43482
diff changeset
   515
                fp,
da9ecbb10368 vfs: more attribute suppressions
Augie Fackler <augie@google.com>
parents: 43482
diff changeset
   516
                self._backgroundfilecloser,  # pytype: disable=attribute-error
da9ecbb10368 vfs: more attribute suppressions
Augie Fackler <augie@google.com>
parents: 43482
diff changeset
   517
            )
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   518
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   519
        return fp
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   520
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   521
    def symlink(self, src, dst):
18327
4aecdb91443c scmutil: simplify vfs.audit - drop wrapped vfs.auditor
Mads Kiilerich <mads@kiilerich.com>
parents: 18316
diff changeset
   522
        self.audit(dst)
16199
8181bd808dc5 scmutil: add join method to opener to construct path relative to base
Idan Kamara <idankk86@gmail.com>
parents: 16198
diff changeset
   523
        linkname = self.join(dst)
31549
18b9d9b95719 vfs: use tryunlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31542
diff changeset
   524
        util.tryunlink(linkname)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   525
29017
07be86828e79 util: fix race in makedirs()
Adam Simpkins <simpkins@fb.com>
parents: 28819
diff changeset
   526
        util.makedirs(os.path.dirname(linkname), self.createmode)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   527
14261
e3649bcca3f6 opener: rename _can_symlink to _cansymlink
Adrian Buehlmann <adrian@cadifra.com>
parents: 14236
diff changeset
   528
        if self._cansymlink:
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   529
            try:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   530
                os.symlink(src, linkname)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25658
diff changeset
   531
            except OSError as err:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   532
                raise OSError(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   533
                    err.errno,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   534
                    _(b'could not symlink to %r: %s')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   535
                    % (src, encoding.strtolocal(err.strerror)),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   536
                    linkname,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   537
                )
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   538
        else:
17768
9837cafc25b1 vfs: use self.write to write symlink placeholders
Matt Mackall <mpm@selenic.com>
parents: 17763
diff changeset
   539
            self.write(dst, src)
13971
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   540
24628
a0b47885a1c5 vfs: make it possible to pass multiple path elements to join
Matt Harbison <matt_harbison@yahoo.com>
parents: 24582
diff changeset
   541
    def join(self, path, *insidef):
17161
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   542
        if path:
47809
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   543
            parts = [self.base, path]
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   544
            parts.extend(insidef)
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   545
            return self._join(*parts)
17681
a41fd730f230 scmutil: backout 83785bb56062 (issue3643)
Matt Mackall <mpm@selenic.com>
parents: 17675
diff changeset
   546
        else:
a41fd730f230 scmutil: backout 83785bb56062 (issue3643)
Matt Mackall <mpm@selenic.com>
parents: 17675
diff changeset
   547
            return self.base
16199
8181bd808dc5 scmutil: add join method to opener to construct path relative to base
Idan Kamara <idankk86@gmail.com>
parents: 16198
diff changeset
   548
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   549
17649
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   550
opener = vfs
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   551
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   552
41093
6498f0e03526 vfs: fix proxyvfs inheritance
Boris Feld <boris.feld@octobus.net>
parents: 41092
diff changeset
   553
class proxyvfs(abstractvfs):
17845
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   554
    def __init__(self, vfs):
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   555
        self.vfs = vfs
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   556
41094
adee334d94cd vfs: handle _auditpath in proxyvfs
Boris Feld <boris.feld@octobus.net>
parents: 41093
diff changeset
   557
    def _auditpath(self, path, mode):
adee334d94cd vfs: handle _auditpath in proxyvfs
Boris Feld <boris.feld@octobus.net>
parents: 41093
diff changeset
   558
        return self.vfs._auditpath(path, mode)
adee334d94cd vfs: handle _auditpath in proxyvfs
Boris Feld <boris.feld@octobus.net>
parents: 41093
diff changeset
   559
27879
52a4ad62b006 cleanup: use modern @property/@foo.setter property specification
Augie Fackler <augie@google.com>
parents: 27851
diff changeset
   560
    @property
29714
69109052d9ac auditvfs: forward options property from nested vfs
Augie Fackler <augie@google.com>
parents: 29417
diff changeset
   561
    def options(self):
69109052d9ac auditvfs: forward options property from nested vfs
Augie Fackler <augie@google.com>
parents: 29417
diff changeset
   562
        return self.vfs.options
69109052d9ac auditvfs: forward options property from nested vfs
Augie Fackler <augie@google.com>
parents: 29417
diff changeset
   563
69109052d9ac auditvfs: forward options property from nested vfs
Augie Fackler <augie@google.com>
parents: 29417
diff changeset
   564
    @options.setter
69109052d9ac auditvfs: forward options property from nested vfs
Augie Fackler <augie@google.com>
parents: 29417
diff changeset
   565
    def options(self, value):
69109052d9ac auditvfs: forward options property from nested vfs
Augie Fackler <augie@google.com>
parents: 29417
diff changeset
   566
        self.vfs.options = value
69109052d9ac auditvfs: forward options property from nested vfs
Augie Fackler <augie@google.com>
parents: 29417
diff changeset
   567
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   568
41093
6498f0e03526 vfs: fix proxyvfs inheritance
Boris Feld <boris.feld@octobus.net>
parents: 41092
diff changeset
   569
class filtervfs(proxyvfs, abstractvfs):
17649
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   570
    '''Wrapper vfs for filtering filenames with a function.'''
14090
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
   571
17846
f42cf30873dc scmutil: add mustaudit delegation to filtervfs (issue3673)
Bryan O'Sullivan <bryano@fb.com>
parents: 17845
diff changeset
   572
    def __init__(self, vfs, filter):
33412
a42369e04aee vfs: rename auditvfs to proxyvfs
Yuya Nishihara <yuya@tcha.org>
parents: 33282
diff changeset
   573
        proxyvfs.__init__(self, vfs)
14090
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
   574
        self._filter = filter
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
   575
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
   576
    def __call__(self, path, *args, **kwargs):
17846
f42cf30873dc scmutil: add mustaudit delegation to filtervfs (issue3673)
Bryan O'Sullivan <bryano@fb.com>
parents: 17845
diff changeset
   577
        return self.vfs(self._filter(path), *args, **kwargs)
14090
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
   578
24628
a0b47885a1c5 vfs: make it possible to pass multiple path elements to join
Matt Harbison <matt_harbison@yahoo.com>
parents: 24582
diff changeset
   579
    def join(self, path, *insidef):
17725
ffd589d4b785 vfs: define "join()" in each classes derived from "abstractvfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17723
diff changeset
   580
        if path:
24628
a0b47885a1c5 vfs: make it possible to pass multiple path elements to join
Matt Harbison <matt_harbison@yahoo.com>
parents: 24582
diff changeset
   581
            return self.vfs.join(self._filter(self.vfs.reljoin(path, *insidef)))
17725
ffd589d4b785 vfs: define "join()" in each classes derived from "abstractvfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17723
diff changeset
   582
        else:
17846
f42cf30873dc scmutil: add mustaudit delegation to filtervfs (issue3673)
Bryan O'Sullivan <bryano@fb.com>
parents: 17845
diff changeset
   583
            return self.vfs.join(path)
17725
ffd589d4b785 vfs: define "join()" in each classes derived from "abstractvfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17723
diff changeset
   584
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   585
17649
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   586
filteropener = filtervfs
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   587
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   588
41093
6498f0e03526 vfs: fix proxyvfs inheritance
Boris Feld <boris.feld@octobus.net>
parents: 41092
diff changeset
   589
class readonlyvfs(proxyvfs):
18213
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   590
    '''Wrapper vfs preventing any writing.'''
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   591
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   592
    def __init__(self, vfs):
33412
a42369e04aee vfs: rename auditvfs to proxyvfs
Yuya Nishihara <yuya@tcha.org>
parents: 33282
diff changeset
   593
        proxyvfs.__init__(self, vfs)
18213
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   594
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   595
    def __call__(self, path, mode=b'r', *args, **kw):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   596
        if mode not in (b'r', b'rb'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   597
            raise error.Abort(_(b'this vfs is read only'))
18213
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   598
        return self.vfs(path, mode, *args, **kw)
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   599
26156
a112fffdb632 scmutil.readonlyvfs: implement join
Siddharth Agarwal <sid0@fb.com>
parents: 26098
diff changeset
   600
    def join(self, path, *insidef):
a112fffdb632 scmutil.readonlyvfs: implement join
Siddharth Agarwal <sid0@fb.com>
parents: 26098
diff changeset
   601
        return self.vfs.join(path, *insidef)
18213
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   602
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   603
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   604
class closewrapbase:
29994
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   605
    """Base class of wrapper, which hooks closing
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   606
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   607
    Do not instantiate outside of the vfs layer.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   608
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   609
29994
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   610
    def __init__(self, fh):
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43484
diff changeset
   611
        object.__setattr__(self, '_origfh', fh)
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   612
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   613
    def __getattr__(self, attr):
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   614
        return getattr(self._origfh, attr)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   615
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   616
    def __setattr__(self, attr, value):
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   617
        return setattr(self._origfh, attr, value)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   618
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   619
    def __delattr__(self, attr):
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   620
        return delattr(self._origfh, attr)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   621
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   622
    def __enter__(self):
40939
8d9f366b7f19 vfs: ensure closewrapbase fh doesn't escape by entering context manager
Matt Harbison <matt_harbison@yahoo.com>
parents: 39904
diff changeset
   623
        self._origfh.__enter__()
8d9f366b7f19 vfs: ensure closewrapbase fh doesn't escape by entering context manager
Matt Harbison <matt_harbison@yahoo.com>
parents: 39904
diff changeset
   624
        return self
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   625
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   626
    def __exit__(self, exc_type, exc_value, exc_tb):
43466
2dcd4e773193 vfs: fix erroneous bytes constants
Augie Fackler <augie@google.com>
parents: 43462
diff changeset
   627
        raise NotImplementedError('attempted instantiating ' + str(type(self)))
29994
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   628
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   629
    def close(self):
43466
2dcd4e773193 vfs: fix erroneous bytes constants
Augie Fackler <augie@google.com>
parents: 43462
diff changeset
   630
        raise NotImplementedError('attempted instantiating ' + str(type(self)))
29994
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   631
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   632
29994
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   633
class delayclosedfile(closewrapbase):
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   634
    """Proxy for a file object whose close is delayed.
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   635
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   636
    Do not instantiate outside of the vfs layer.
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   637
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   638
29994
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   639
    def __init__(self, fh, closer):
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   640
        super(delayclosedfile, self).__init__(fh)
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43484
diff changeset
   641
        object.__setattr__(self, '_closer', closer)
29994
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   642
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   643
    def __exit__(self, exc_type, exc_value, exc_tb):
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   644
        self._closer.close(self._origfh)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   645
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   646
    def close(self):
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   647
        self._closer.close(self._origfh)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   648
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   649
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   650
class backgroundfilecloser:
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   651
    """Coordinates background closing of file handles on multiple threads."""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   652
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   653
    def __init__(self, ui, expectedcount=-1):
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   654
        self._running = False
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   655
        self._entered = False
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   656
        self._threads = []
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   657
        self._threadexception = None
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   658
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   659
        # Only Windows/NTFS has slow file closing. So only enable by default
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   660
        # on that platform. But allow to be enabled elsewhere for testing.
34645
75979c8d4572 codemod: use pycompat.iswindows
Jun Wu <quark@fb.com>
parents: 34022
diff changeset
   661
        defaultenabled = pycompat.iswindows
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   662
        enabled = ui.configbool(b'worker', b'backgroundclose', defaultenabled)
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   663
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   664
        if not enabled:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   665
            return
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   666
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   667
        # There is overhead to starting and stopping the background threads.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   668
        # Don't do background processing unless the file count is large enough
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   669
        # to justify it.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   670
        minfilecount = ui.configint(b'worker', b'backgroundcloseminfilecount')
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   671
        # FUTURE dynamically start background threads after minfilecount closes.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   672
        # (We don't currently have any callers that don't know their file count)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   673
        if expectedcount > 0 and expectedcount < minfilecount:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   674
            return
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   675
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   676
        maxqueue = ui.configint(b'worker', b'backgroundclosemaxqueue')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   677
        threadcount = ui.configint(b'worker', b'backgroundclosethreadcount')
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   678
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   679
        ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   680
            b'starting %d threads for background file closing\n' % threadcount
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   681
        )
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   682
37844
8fb9985382be pycompat: export queue module instead of symbols in module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35725
diff changeset
   683
        self._queue = pycompat.queue.Queue(maxsize=maxqueue)
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   684
        self._running = True
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   685
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   686
        for i in range(threadcount):
43462
ffd632c224c3 vfs: another bytes-str confusion on thread name
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   687
            t = threading.Thread(target=self._worker, name='backgroundcloser')
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   688
            self._threads.append(t)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   689
            t.start()
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   690
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   691
    def __enter__(self):
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   692
        self._entered = True
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   693
        return self
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   694
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   695
    def __exit__(self, exc_type, exc_value, exc_tb):
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   696
        self._running = False
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   697
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   698
        # Wait for threads to finish closing so open files don't linger for
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   699
        # longer than lifetime of context manager.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   700
        for t in self._threads:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   701
            t.join()
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   702
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   703
    def _worker(self):
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   704
        """Main routine for worker thread."""
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   705
        while True:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   706
            try:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   707
                fh = self._queue.get(block=True, timeout=0.100)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   708
                # Need to catch or the thread will terminate and
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   709
                # we could orphan file descriptors.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   710
                try:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   711
                    fh.close()
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   712
                except Exception as e:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   713
                    # Stash so can re-raise from main thread later.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   714
                    self._threadexception = e
37844
8fb9985382be pycompat: export queue module instead of symbols in module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35725
diff changeset
   715
            except pycompat.queue.Empty:
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   716
                if not self._running:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   717
                    break
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   718
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   719
    def close(self, fh):
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   720
        """Schedule a file for closing."""
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   721
        if not self._entered:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   722
            raise error.Abort(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43090
diff changeset
   723
                _(b'can only call close() when context manager active')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   724
            )
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   725
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   726
        # If a background thread encountered an exception, raise now so we fail
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   727
        # fast. Otherwise we may potentially go on for minutes until the error
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   728
        # is acted on.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   729
        if self._threadexception:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   730
            e = self._threadexception
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   731
            self._threadexception = None
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   732
            raise e
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   733
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   734
        # If we're not actively running, close synchronously.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   735
        if not self._running:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   736
            fh.close()
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   737
            return
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   738
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   739
        self._queue.put(fh, block=True, timeout=None)
29995
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   740
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   741
29995
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   742
class checkambigatclosing(closewrapbase):
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   743
    """Proxy for a file object, to avoid ambiguity of file stat
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   744
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   745
    See also util.filestat for detail about "ambiguity of file stat".
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   746
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   747
    This proxy is useful only if the target file is guarded by any
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   748
    lock (e.g. repo.lock or repo.wlock)
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   749
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   750
    Do not instantiate outside of the vfs layer.
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   751
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   752
29995
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   753
    def __init__(self, fh):
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   754
        super(checkambigatclosing, self).__init__(fh)
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43484
diff changeset
   755
        object.__setattr__(self, '_oldstat', util.filestat.frompath(fh.name))
29995
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   756
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   757
    def _checkambig(self):
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   758
        oldstat = self._oldstat
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   759
        if oldstat.stat:
33280
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
   760
            _avoidambig(self._origfh.name, oldstat)
29995
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   761
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   762
    def __exit__(self, exc_type, exc_value, exc_tb):
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   763
        self._origfh.__exit__(exc_type, exc_value, exc_tb)
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   764
        self._checkambig()
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   765
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   766
    def close(self):
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   767
        self._origfh.close()
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   768
        self._checkambig()