hgext/fastannotate/support.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Fri, 01 Sep 2023 00:09:55 +0200
changeset 50929 18c8c18993f0
parent 50777 8dc2724d0304
permissions -rw-r--r--
pycompat: drop usage of hasattr/getattr/setattr/delatt proxy The function remains to ease extensions transition, but we no longer use them in core.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     1
# Copyright 2016-present Facebook. All Rights Reserved.
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     2
#
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     3
# support: fastannotate support for hgweb, and filectx
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     4
#
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     7
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     8
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     9
from mercurial import (
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    10
    context as hgcontext,
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    11
    dagop,
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    12
    extensions,
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    13
    hgweb,
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    14
    patch,
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    15
    util,
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    16
)
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    17
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    18
from . import (
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    19
    context,
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    20
    revmap,
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    21
)
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    22
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
    23
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
    24
class _lazyfctx:
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    25
    """delegates to fctx but do not construct fctx when unnecessary"""
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    26
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    27
    def __init__(self, repo, node, path):
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    28
        self._node = node
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    29
        self._path = path
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    30
        self._repo = repo
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    31
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    32
    def node(self):
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    33
        return self._node
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    34
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    35
    def path(self):
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    36
        return self._path
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    37
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    38
    @util.propertycache
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    39
    def _fctx(self):
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    40
        return context.resolvefctx(self._repo, self._node, self._path)
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    41
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    42
    def __getattr__(self, name):
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    43
        return getattr(self._fctx, name)
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    44
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
    45
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    46
def _convertoutputs(repo, annotated, contents):
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    47
    """convert fastannotate outputs to vanilla annotate format"""
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    48
    # fastannotate returns: [(nodeid, linenum, path)], [linecontent]
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    49
    # convert to what fctx.annotate returns: [annotateline]
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    50
    results = []
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    51
    fctxmap = {}
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    52
    annotateline = dagop.annotateline
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    53
    for i, (hsh, linenum, path) in enumerate(annotated):
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    54
        if (hsh, path) not in fctxmap:
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    55
            fctxmap[(hsh, path)] = _lazyfctx(repo, hsh, path)
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    56
        # linenum: the user wants 1-based, we have 0-based.
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    57
        lineno = linenum + 1
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    58
        fctx = fctxmap[(hsh, path)]
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    59
        line = contents[i]
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    60
        results.append(annotateline(fctx=fctx, lineno=lineno, text=line))
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    61
    return results
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    62
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
    63
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    64
def _getmaster(fctx):
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    65
    """(fctx) -> str"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    66
    return fctx._repo.ui.config(b'fastannotate', b'mainbranch') or b'default'
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    67
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
    68
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    69
def _doannotate(fctx, follow=True, diffopts=None):
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    70
    """like the vanilla fctx.annotate, but do it via fastannotate, and make
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    71
    the output format compatible with the vanilla fctx.annotate.
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    72
    may raise Exception, and always return line numbers.
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    73
    """
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    74
    master = _getmaster(fctx)
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    75
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    76
    with context.fctxannotatecontext(fctx, follow, diffopts) as ac:
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    77
        try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
    78
            annotated, contents = ac.annotate(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
    79
                fctx.rev(), master=master, showpath=True, showlines=True
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
    80
            )
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    81
        except Exception:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
    82
            ac.rebuild()  # try rebuild once
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
    83
            fctx._repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    84
                b'fastannotate: %s: rebuilding broken cache\n' % fctx._path
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
    85
            )
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    86
            try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
    87
                annotated, contents = ac.annotate(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
    88
                    fctx.rev(), master=master, showpath=True, showlines=True
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
    89
                )
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    90
            except Exception:
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    91
                raise
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    92
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    93
    assert annotated and contents
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    94
    return _convertoutputs(fctx._repo, annotated, contents)
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    95
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
    96
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    97
def _hgwebannotate(orig, fctx, ui):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
    98
    diffopts = patch.difffeatureopts(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    99
        ui, untrusted=True, section=b'annotate', whitespace=True
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   100
    )
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   101
    return _doannotate(fctx, diffopts=diffopts)
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   102
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   103
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   104
def _fctxannotate(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   105
    orig, self, follow=False, linenumber=False, skiprevs=None, diffopts=None
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   106
):
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   107
    if skiprevs:
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   108
        # skiprevs is not supported yet
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   109
        return orig(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   110
            self, follow, linenumber, skiprevs=skiprevs, diffopts=diffopts
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   111
        )
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   112
    try:
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   113
        return _doannotate(self, follow, diffopts)
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   114
    except Exception as ex:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   115
        self._repo.ui.debug(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43089
diff changeset
   116
            b'fastannotate: falling back to the vanilla annotate: %r\n' % ex
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   117
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   118
        return orig(self, follow=follow, skiprevs=skiprevs, diffopts=diffopts)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   119
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   120
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   121
def _remotefctxannotate(orig, self, follow=False, skiprevs=None, diffopts=None):
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   122
    # skipset: a set-like used to test if a fctx needs to be downloaded
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   123
    with context.fctxannotatecontext(self, follow, diffopts) as ac:
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   124
        skipset = revmap.revmap(ac.revmappath)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   125
    return orig(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   126
        self, follow, skiprevs=skiprevs, diffopts=diffopts, prefetchskip=skipset
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   127
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   128
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   129
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   130
def replacehgwebannotate():
50777
8dc2724d0304 wrapfunction: use sysstr instead of bytes as argument in "fastannotate"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   131
    extensions.wrapfunction(hgweb.webutil, 'annotate', _hgwebannotate)
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   132
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41365
diff changeset
   133
39210
1ddb296e0dee fastannotate: initial import from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   134
def replacefctxannotate():
50777
8dc2724d0304 wrapfunction: use sysstr instead of bytes as argument in "fastannotate"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   135
    extensions.wrapfunction(hgcontext.basefilectx, 'annotate', _fctxannotate)