contrib/debugshell.py
author Gregory Szorc <gregory.szorc@gmail.com>
Fri, 06 Apr 2018 17:21:16 -0700
changeset 37536 2003da12f49b
parent 32376 46ba2cdda476
child 41768 aaad36b88298
permissions -rw-r--r--
wireproto: only expose "clonebundles" to version 1 transports This may make a comeback in wire protocol version 2. The feature definitely needs to be carried forward. But at this juncture, I'm flirting with the idea of implementing this via a "redirect" mechanism at the command response level itself rather than something that requires one-off client support for querying and handling. i.e. I want to make it so servers can say "fetch this first and then come back" and clients handle that automatically. This would not only support clone bundles, but would also support piece-meal "pull bundles." Whatever happens, we can deal with it down the road. Differential Revision: https://phab.mercurial-scm.org/D3203

# debugshell extension
"""a python shell with repo, changelog & manifest objects"""

from __future__ import absolute_import
import code
import mercurial
import sys
from mercurial import (
    demandimport,
    registrar,
)

cmdtable = {}
command = registrar.command(cmdtable)

def pdb(ui, repo, msg, **opts):
    objects = {
        'mercurial': mercurial,
        'repo': repo,
        'cl': repo.changelog,
        'mf': repo.manifestlog,
    }

    code.interact(msg, local=objects)

def ipdb(ui, repo, msg, **opts):
    import IPython

    cl = repo.changelog
    mf = repo.manifestlog
    cl, mf # use variables to appease pyflakes

    IPython.embed()

@command('debugshell|dbsh', [])
def debugshell(ui, repo, **opts):
    bannermsg = "loaded repo : %s\n" \
                "using source: %s" % (repo.root,
                                      mercurial.__path__[0])

    pdbmap = {
        'pdb'  : 'code',
        'ipdb' : 'IPython'
    }

    debugger = ui.config("ui", "debugger")
    if not debugger:
        debugger = 'pdb'

    # if IPython doesn't exist, fallback to code.interact
    try:
        with demandimport.deactivated():
            __import__(pdbmap[debugger])
    except ImportError:
        ui.warn(("%s debugger specified but %s module was not found\n")
                % (debugger, pdbmap[debugger]))
        debugger = 'pdb'

    getattr(sys.modules[__name__], debugger)(ui, repo, bannermsg, **opts)