contrib/debugshell.py
author Simon Heimberg <simohe@besonet.ch>
Sat, 08 Feb 2014 14:35:07 +0100
changeset 20425 ca6aa8362f33
parent 19794 cccc44304b2c
child 21243 8b5c039f2b4f
permissions -rw-r--r--
win32: spawndetached returns pid of detached process and not of cmd.exe win32.spawndetached starts the detached process by `cmd.exe` (or COMSPEC). The pid it returned was the one of cmd.exe and not the one of the detached process. When this pid is used to kill the process, the detached process is not killed, but only cmd.exe. With this patch the pid of the detached process is written to the pid file. Killing the process works as expected. The pid is only evaluated on writing the pid file. It is unnecessary to search the pid when it is not needed. And more important, it probably does not yet exist right after the cmd.exe process was started. When the pid is written to the file, waiting for the start of the detached process has already happened. Use this functionality instead of writing a 2nd wait function. Many tests on windows will not fail anymore, all those with the first failing line "abort: child process failed to start". (The processes still hanging around from previous test runs have to be killed first. They still block a tcp port.) A good test for the functionality of this patch is test-treediscovery.t, because it starts and kills `hg serve -d` several times.

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

import sys
import mercurial
import code

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

    code.interact(msg, local=objects)

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

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

    IPython.embed()

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:
        __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)

cmdtable = {
    "debugshell|dbsh": (debugshell, [])
}