Hi all,

This worked out really well for us. We use the Apache SVN server on
Windows, so we never managed to use the SVN Python modules (my
coworker who did most of this work never managed to find a
Windows-compatible distribution for Python 3.x.)

Instead, we inspected the transaction file and parsed it manually. I
don't generally like this, but a pure-Python solution was far
preferable to us at this stage.

One snag is that it seems like authorization happens before the
precommit hook, so we can't lock users out of Subversion without also
locking them out of the gated commit. Now that we're aware of this, we
can figure out ways of countering it.

Thanks for your excellent suggestions!

Here's the little module we use (transcribed, I might have made syntax
mistakes):

----
import os


def parse_revprops(revprop_data):
    revprops = {}
    for index, line in enumerate(revprop_data):
        if line == "END" or line == "":
            continue

        if (index % 4) == 1:
            current_key = line
        elif (index % 4) == 3:
            revprops[current_key] = line

    return revprops


def serialize_revprops(revprops):
    output = ""
    for key, value in revprops.items():
        output += "K %d\n" % len(key)
        output += "%s\n" % key
        output += "V %d\n" % len(value)
        output += "%s\n" % value
    return output + "END\n"


def rewrite_author(subversion_folder, transaction_id):
    # Read revprops transaction file directly.
    props_file = os.path.join(subversion_folder, "db",
                              "transactions", transaction_id + ".txn",
                              "props")
    with open(props_file, "r") as fd:
        revprops = parse_revprops(fd.read().splitlines())

    # Only rewrite author for bot commits
    if revprops["svn:author"] != "bot":
        return True

    # If there's no on-behalf-of specified, just commit as bot directly.
    if "on-behalf-of" not in revprops:
        return True

    # Move svn:author to committed-by property, and on-behalf-of to svn:author.
    revprops["committed-by"] = revprops["svn:author"]
    revprops["svn:author"] = revprops["on-behalf-of"]
    del revprops["on-behalf-of"]

    # Write back.
    with open(props_file, "w", newline="\n") as fd:
        fd.write(serialize_revprops(revprops))

    return True
----

- Kim

Reply via email to