[Svnmerge] svnmerge rewritten in Python

Giovanni Bajo rasky at develer.com
Thu Sep 22 10:05:18 PDT 2005


Jim Fulton <jim at zope.com> wrote:

>> - It's a straightforward conversion. It's *almost* 1:1 with the shell
>> version, the only big difference being that revision lists are handled by
>> a class RevisionList. At this point, I did not bother refactoring code or
>> changing structure too much, it can be done in followups if there is
>> interest to maintain and work on this Python version.
>
> I don't think a shell-based version can be robust and portable to windows.
> In particular, there's no portable way to run a process and get both
output
> and a return code.

It works for me, so I don't see where the problem is. I wrote many tools in
python which parses shell outputs, and they all work under both Linux and
Windows. If I wanted to use a 2.4-ism, I could even have imported
subprocess, which was created exactly for this purpose.

> This means you can't get output of svn commands and
> get detect errors cleanly.

It works already. Not in the version I posted, but this is the updated
version

def launch(cmd):
    """Launch a sub-process. Return its output (lines) and exit code."""
    if os.name == 'posix':
        p = popen2.Popen4(cmd)
        p.tochild.close()
        out = p.fromchild.readlines()
        ret = p.wait()
        if ret == 0:
            ret = None
        else:
            ret >>= 8
    else:
        i,k = os.popen4(cmd)
        i.close()
        out = k.readlines()
        ret = k.close()

    if ret is None:
        return out
    raise LaunchError(ret, cmd, out)

This works correctly under both Linux and Windows:

Python 2.4.1 (#1, May 16 2005, 15:19:29)
[GCC 4.0.0 20050512 (Red Hat 4.0.0-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import svnmerge
>>> svnmerge.launch("svn")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "svnmerge.py", line 195, in launch
    raise LaunchError(ret, cmd, out)
svnmerge.LaunchError: (1, 'svn', ["Type 'svn help' for usage.\n"])


Python 2.3.3 (#51, Dec 18 2003, 20:22:39) [MSC v.1200 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import svnmerge
>>> svnmerge.launch("svn")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "svnmerge.py", line 195, in launch
    raise LaunchError(ret, cmd, out)
svnmerge.LaunchError: (1, 'svn', ["Type 'svn help' for usage.\n"])


Yes, it's basically two different functions, but I can't see how this is a
problem.


> This is why I ultimately decided to use the
> Python subversion bindings.  Using these is not easy though do to the
> extremely sparse documentation.  I do think the result would be cleaner in
> the long run.  For example, there is no need to parse svn command output.
> The svn api returns real data.

I thought about it as well. My opinion is that svnmerge is too simple a tool
at the moment to use the bindings. I don't see how they can solve problem.
Do you believe the code is going to get smaller or easier to follow? I fear
it is going to be quite the opposite...

I think there is a gain in using small, self-contained scripts which spawn
external processes, especially when those processes have been designed to be
run like that. This is the case of almost anything under UNIX, and
Subversion lists its "machine-parsable output" amongs its features. The fact
that the script was born as a shell script tells everything.

Can you show us your working-in-progress script?


>> - It's lightly tested. Testing and bugreports are welcome :)
>
> Right, my intent was to include fairly extensive doctests.

Yeah, I did some basic testing of all the low-level functions, but I was
thikning of testing the whole program. I can't see a way to do it without
setting up a test repository, ecc, which is unfortunate. Anyway, having
doctests for the simple functions is fine.


>> - It's supposedly feature-complete, there is only one thing missing which
>> has to do with old svnmerge versions (see "TODO" in the code).
>
> I would hope we don't have to support these.  How long ago did
> svnmerge switch to the new format?

No clue. As I said, mine was a straightforward conversion. In fact, I plan
to reimplement this feature too. I want to be 100% compatible with the old
shell version of svnmerge, so that people don't have think about switching.

>> - I purposedly avoid newest Python features. Theoritically it should work
>> on any Python 2.0+, but I haven't tested it. I believe it is important
for
>> such a tool to work on as many systems as possible. And really, for 600
>> lines of code, I can live without generators or a decorators.
>
> I think the other svn python scripts require 2.2.  I don't see any
> point in supporting older versions.

I have had many support headaches with versions of Python. One thing I
learnt is that there is absolutely no need to raise the compatibility level
for Python. People can have all sort of good reasons to use an older Python
version, and they will not want to install another version of Python just so
they can run a simple script to do merging. So, for instance, if we end up
*needing* subprocess, it might make sense to upgrade to 2.4. Until then, I
see no reason to force newer versions. I can live without a couple of
syntactic sugar for 600 lines of code (really, it's not more than a couple).

In fact, I *might* have an immediate need for this, since I will be working
on a project running a subversion server on an OpenBSD machine, with Python
2.0.1 installed. I could go through the hassle of asking the administrator
to upgrade Python and install the SVN bindings, or install Python in my home
dir, but *why*? So that I can use @ for decorators?
-- 
Giovanni Bajo




More information about the Svnmerge mailing list