On Mercurial API

Steve Borho steve at ageia.com
Tue Jul 31 11:55:13 CDT 2007


On Tuesday 31 July 2007 6:23:36 am Thomas Arendsen Hein wrote:
> contrib/hg-ssh uses:
>
> from mercurial import commands
> commands.dispatch(['-R', repo, 'serve', '--stdio'])

This was intriguing to me so on a lark I tried to change Qct
to use this interface when it runs as an extension.  
Here's the Qct function in question:

    def hgcmd(self, args, input = None, okresults=[0]):
        class IOStream:
            def __init__(self, inp):
                self.output = ''
                self.input = inp
            def write(self, text):
                self.output += text
            def read(self):
                data = self.input
                self.input = None
                return data
            def closed(self):
                if self.input:
                    return False
                else:
                    return True

        if self.commands: # We have Mercurial entry point
            stream = IOStream(input)
            ret = None
            try:
                sys.stdout = stream
                sys.stdin = stream
                ret = self.commands.dispatch(args)
            finally:
                sys.stdout = sys.__stdout__
                sys.stdin = sys.__stdin__
            if ret and ret not in okresults:
                print "Cmd: hg", ' '.join(args), 'failed with code', ret
            return stream.output
        else:
            return runProgram([self.hg_exe] + args, input, expectedexits=okresults)


And this actually works pretty well until I try to commit files.
Qct dispatches the following command line:  hg commit -l - <file list>
and then puts the log message on stdin.

This approach worked when I called mercurial externally, but using the
internal interface causes a back-trace:

transaction abort!
rollback completed
** unknown exception encountered, details follow
** report bug details to http://www.selenic.com/mercurial/bts
** or mercurial at selenic.com
** Mercurial Distributed SCM (version 48ebd6a83994+20070731)
Traceback (most recent call last):
  File "/home/steve/lib/python/qctlib/gui_logic.py", line 754, in commitSelected
    self.vcs.commitFiles(checkedItemList, msg)
  File "/home/steve/lib/python/qctlib/vcs/hg.py", line 448, in commitFiles
    self.hgcmd(['commit', '-l', '-'] + commitFileNames, logMsgText)
  File "/home/steve/lib/python/qctlib/vcs/hg.py", line 108, in hgcmd
    ret = self.commands.dispatch(args)
  File "/home/steve/lib/python/mercurial/commands.py", line 3174, in dispatch
    return cmdutil.runcatch(u, args, argv0=argv0)
  File "/home/steve/lib/python/mercurial/cmdutil.py", line 37, in runcatch
    return dispatch(ui, args, argv0=argv0)
  File "/home/steve/lib/python/mercurial/cmdutil.py", line 378, in dispatch
    ret = runcommand(ui, options, cmd, d)
  File "/home/steve/lib/python/mercurial/cmdutil.py", line 431, in runcommand
    return checkargs()
  File "/home/steve/lib/python/mercurial/cmdutil.py", line 387, in checkargs
    return cmdfunc()
  File "/home/steve/lib/python/mercurial/cmdutil.py", line 370, in <lambda>
    d = lambda: func(ui, repo, *args, **cmdoptions)
  File "/home/steve/lib/python/mercurial/commands.py", line 468, in commit
    force_editor=opts.get('force_editor'))
  File "/home/steve/lib/python/hgext/mq.py", line 2066, in commit
    return super(mqrepo, self).commit(*args, **opts)
  File "/home/steve/lib/python/mercurial/localrepo.py", line 796, in commit
    lines = [line.rstrip() for line in text.rstrip().splitlines()]
AttributeError: rstrip


Should I use an alternate interface for commit, or is my quick hack just
insufficient?  One option is to use a temporary file for the log message,
but I would like to avoid that if possible.

-- 
Steve Borho (steve at ageia.com)
http://www.borho.org/~steve/steveAgeia.asc
Key fingerprint = 3D9C 67D5 F426 4322 075B  0795 C9B2 C3A0 97D0 C090


More information about the Mercurial-devel mailing list