Symfony World blog is not maintained anymore. Check new sys.exit() programming blog.

force to log message SVN python

Scene from "It Happened One Night" by Frank Capra (1934)

Another blog post about Subversion. Few days ago someone asked me if I know how to block commiting a subversion revision that has no log message defined. I didn't, but I thought it's a good idea, because it could help to track bugs, changes, etc. There's no such configuration, but it can be achieved using SVN hooks.

tried to do this in PHP...

There are many resources in the web giving examples to do this using a windows batch file - but I'm a linux user. At first, I wanted to do this in PHP. Although my final solution is not PHP, maybe someone will find following code snippets useful.

So I started searching through many pages on the web to find PHP shell scripts that could block committing a revision with no log message. The first step is, of course, to create an executable pre-commit file in the hooks directory of the repository. Then make the shell use the PHP parser to execute our script. Next, define path to svnlook binary and execute it:

#!/usr/local/bin/php -q
<?php
 
$SVNLOOK = '/usr/bin/svnlook';
exec("$SVNLOOK log -t {$argv[2]} {$argv[1]}", $output, $result);
We have the output and the result of the command available. So we may just check if the message (which revision a user is just trying to commit) is empty (I guess there is no other way than to use svnlook). If the log message is empty, the revision shall be stopped - and this happens, when exit status code is different than 0 (of course, a message explaining the cause is appreciated):
if (empty($result))
{
  fwrite(STDERR, "Commit blocked, need to pass the log message.");
  exit(1);
}
else
  exit(0);
This all should work, but 99,9% of all servers will have the exec function disabled by default (in both CLI and web server PHP configuration; along with other system functions):
disable_functions = exec,system,passthru,shell_exec,escapeshellarg,escapeshellcmd,proc_close,proc_open,dl,popen,show_source
Even if you manage to remove those functions from the configuration, you lower the server security, which may risk dangerous script injection. So I forgot about using PHP...

...and finally moved to python

Finally, I managed to succeed using python:

#!/usr/bin/python
 
import sys, os, string
 
SVNLOOK='/usr/bin/svnlook'
 
def main(repos, txn):
  log_cmd = '%s log -t "%s" "%s"' % (SVNLOOK, txn, repos)
  log_msg = os.popen(log_cmd, 'r').readline().rstrip('n')
  if len(log_msg) < 10:
    sys.stderr.write ("\n> Revision comment must be defined\n")
    sys.exit(1)
  else:
    sys.exit(0)
 
if __name__ == '__main__':
  if len(sys.argv) < 3:
    sys.stderr.write("\n> Usage: %s REPOS TXN\n" % (sys.argv[0]))
  else:
    main(sys.argv[1], sys.argv[2])

1 comment:

  1. Good article, here's another solution using Perl:

    https://injustfiveminutes.wordpress.com/2012/11/15/how-to-force-comments-on-subversion-commit-with-perl-hook-script/

    ReplyDelete