tests/logexceptions.py
author Martin von Zweigbergk <martinvonz@google.com>
Tue, 18 Jan 2022 13:05:21 -0800
changeset 48981 f3aafd785e65
parent 48875 6000f5b25c9b
permissions -rw-r--r--
filemerge: add support for partial conflict resolution by external tool A common class of merge conflicts is in imports/#includes/etc. It's relatively easy to write a tool that can resolve these conflicts, perhaps by naively just unioning the statements and leaving any cleanup to other tools to do later [1]. Such specialized tools cannot generally resolve all conflicts in a file, of course. Let's therefore call them "partial merge tools". Note that the internal simplemerge algorithm is such a partial merge tool - one that only resolves trivial "conflicts" where one side is unchanged or both sides change in the same way. One can also imagine having smarter language-aware partial tools that merge the AST. It may be useful for such tools to interactively let the user resolve any conflicts it can't resolve itself. However, having the option of implementing it as a partial merge tool means that the developer doesn't *need* to create a UI for it. Instead, the user can resolve any remaining conflicts with their regular merge tool (e.g. `:merge3` or `meld). We don't currently have a way to let the user define such partial merge tools. That's what this patch addresses. It lets the user configure partial merge tools to run. Each tool can be configured to run only on files matching certain patterns (e.g. "*.py"). The tool takes three inputs (local, base, other) and resolves conflicts by updating these in place. For example, let's say the inputs are these: base: ``` import sys def main(): print('Hello') ``` local: ``` import os import sys def main(): print('Hi') ``` other: ``` import re import sys def main(): print('Howdy') ``` A partial merge tool could now resolve the conflicting imports by replacing the import statements in *all* files by the following snippet, while leaving the remainder of the files unchanged. ``` import os import re import sys ``` As a result, simplemerge and any regular merge tool that runs after the partial merge tool(s) will consider the imports to be non-conflicting and will only present the conflict in `main()` to the user. Differential Revision: https://phab.mercurial-scm.org/D12356
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
35190
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     1
# logexceptions.py - Write files containing info about Mercurial exceptions
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     2
#
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 43076
diff changeset
     3
# Copyright 2017 Olivia Mackall <olivia@selenic.com>
35190
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     4
#
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     7
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     8
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     9
import inspect
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    10
import os
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    11
import sys
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    12
import traceback
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    13
import uuid
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    14
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    15
from mercurial import (
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    16
    dispatch,
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    17
    extensions,
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    18
)
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    19
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 36037
diff changeset
    20
35190
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    21
def handleexception(orig, ui):
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    22
    res = orig(ui)
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    23
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    24
    if not ui.environ.get(b'HGEXCEPTIONSDIR'):
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    25
        return res
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    26
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 36037
diff changeset
    27
    dest = os.path.join(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 36037
diff changeset
    28
        ui.environ[b'HGEXCEPTIONSDIR'], str(uuid.uuid4()).encode('ascii')
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 36037
diff changeset
    29
    )
35190
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    30
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    31
    exc_type, exc_value, exc_tb = sys.exc_info()
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    32
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    33
    stack = []
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    34
    tb = exc_tb
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    35
    while tb:
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    36
        stack.append(tb)
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    37
        tb = tb.tb_next
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    38
    stack.reverse()
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    39
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    40
    hgframe = 'unknown'
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    41
    hgline = 'unknown'
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    42
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    43
    # Find the first Mercurial frame in the stack.
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    44
    for tb in stack:
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    45
        mod = inspect.getmodule(tb)
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    46
        if not mod.__name__.startswith(('hg', 'mercurial')):
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    47
            continue
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    48
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    49
        frame = tb.tb_frame
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    50
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    51
        try:
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    52
            with open(inspect.getsourcefile(tb), 'r') as fh:
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    53
                hgline = fh.readlines()[frame.f_lineno - 1].strip()
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    54
        except (IndexError, OSError):
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    55
            pass
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    56
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    57
        hgframe = '%s:%d' % (frame.f_code.co_filename, frame.f_lineno)
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    58
        break
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    59
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    60
    primary = traceback.extract_tb(exc_tb)[-1]
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    61
    primaryframe = '%s:%d' % (primary.filename, primary.lineno)
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    62
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    63
    with open(dest, 'wb') as fh:
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    64
        parts = [
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    65
            str(exc_value),
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    66
            primaryframe,
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    67
            hgframe,
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    68
            hgline,
36037
8de90e006c78 run-tests: report tests that exception occurred in
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35190
diff changeset
    69
            ui.environ[b'TESTNAME'].decode('utf-8', 'replace'),
35190
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    70
        ]
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    71
        fh.write(b'\0'.join(p.encode('utf-8', 'replace') for p in parts))
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    72
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 36037
diff changeset
    73
35190
bd8875b6473c run-tests: mechanism to report exceptions during test execution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    74
def extsetup(ui):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 36037
diff changeset
    75
    extensions.wrapfunction(dispatch, 'handlecommandexception', handleexception)