初学SVN之 用Python写SVN的钩子文件

    最近由于单位上一个工程,由于参与者来源众多,且软件经验都不足,而且由于硬件也在不断修改,结果弄得版本极度混乱,已经到不能忍受的地步了。于是只得寻找一个版本管理工具。经过一番搜索,图方便随大流的选择了VisualSVN Server和TortoiseSVN。经过几天的学习和熟悉操作后,我觉得我再也离不开版本控制了^o^。

    下一步当然是把它装到单位里推广了,理所当然的我也要先负起管理员的责任,于是就要好好研究一下服务器端的设置。第一步当然是学习钩子函数了,不过文档和帮助里的钩子函数例子都是在Unix和Linux下的,在Windows下面就没介绍了。经过几天的搜索,发现其实原来Windows下面的钩子脚本就是一个可执行的文件,可以是.bat,.cmd或.exe,.com,只要按照SVN的钩子函数的命名规范命名就可以了。

     这些钩子函数放在数据仓库的目录下的hook目录里,在一个事件发生后,SVN的服务器会在目录里面寻找名字对应的可执行文件,如果存在则调用它。每种事件调用的参数是不同的,在SVN的帮助里有详细的说明,比如pre-commit钩子的参数是1.repository path  2. Commit transaction name,你可以在钩子文件里根据参数、根据需要调用SVN的功能强大的管理程序或其它任何的程序,作一些动作和判断,最后可以返回一个值,如果是0则表示没有问题,SVN服务器会继续下一步的工作,如果是非0则表明出了问题,SVN服务器就会取消这一动作。如果你想要告诉用户错误的原因,你可以将错误提示输出到stderr里,这样服务器就会把这些信息反馈到用户端,让用户死个明白^.^。
      总之,写一个钩子文件的要点就是:
1 调用参数,由服务器调用,参数请查帮助
2 返回值,0为通过,非0为阻止
3 错误信息,输出到stderr中的信息会反馈给用户
 
    VisualSVN服务器缺省调用的钩子文件是.cmd文件,也就是windows的shell脚本文件。这个东西比dos下的.bat强那么一点点,不过也就只那么一点点,相信正常人类没人会认为写.bat是件轻松愉快的事情,特别是要完成复杂的操作的话。既然SVN服务器只看返回值和stderr,那又何必非要用bat呢,自己用最熟悉的语言写一个程序,在钩子文件里调用自己的这个程序不就行了?当然自己写程序也要追求越轻松越好,虽然我靠C/C++吃饭,不过自从学了Python后,我是能用Python的决不用c。从这个想法出发,用Python写了个测试脚本,找了一个便于测试的钩子pre-lock,这个动作在用户要求锁定一个文件前被调用,你可以随便加锁解锁,对项目没什么影响,要是你用pre-commit测试,就只能通过提交来触发了,这样会影响整个库的结构。
      好了,写到仓库目录下,找到hook目录,创建一个 pre-lock.cmd文件,写上两行:
  1. d:/pre-lock.py  %1 %2 %3
  2. exit errorlevel
    第一行就是调用我们自己的处理函数,路径要设定到你存放脚本的地方,缺省的路径是SVN/bin目录,将来你可以把脚本放到bin目录里,就不用写路径了。第二行将我们处理的结果返回,如果返回是0则通过,返回为1则阻止。
    接下来就是写我们自己的Python处理脚本了。在d盘下建立一个pre-lock.py文件,写上:
  1. #coding=gbk
  2. import sys
  3. count=0
  4. f=file(r'd:/argv.txt','w')
  5. for argument in sys.argv:
  6.     print "Argument %d is %s"%(count,argument)
  7.     f.write("Argument %d is: %s/n"%(count,argument))
  8.     count+=1
  9. f.close()
  10. sys.stderr.write('就不让你锁!')    #前面的都可以不看,关键是后面两行
  11. exit(1)    #返回1,表明阻止

    这个脚本把参数打印了出来,并存到了d:/argv.txt文件里,懒得查资料的话,你可以用这个脚本去看每个钩子的调用参数。好了,测试一下,找个文件获取一下锁定,服务器返回了如下的信息:

命令    锁定

错误    Lock blocked by pre-lock hook (exit code 1) with output:

错误    就不让你锁!

完成!

 

    锁定失败了。

    好了,将最后的exit(1)改成exit(0),再试试,成功锁定了。不过也没有返回'就不让你锁!'这个提示。

    用Python写SVN的钩子脚本就这么简单,接下来的工作就是充分发挥你的编程技巧和想象力了。当然,还要用好SVN提供的强大的管理软件,比如 svnlook , svnadmin 等。

 

最后略加说明一下任何在Python里面调用控制台程序并获得输出,这在使用Python进行操作的时候很重要。一种是使用os.popen,如:

import os

p=os.popen('dir d://*.*') #以dir指令来测试

print p.read()

 

    另外一种方式是使用subprocess.Popen,比如:

import subprocess as sub

p=sub.Popen(['dir','d://*.*'],shell=True,stdout=sub.PIPE,stderr=sub.PIPE)

out=p.communicate()[0]

print out

    第二种方法看起来要麻烦些,不过我觉得功能要灵活些。

你可能感兴趣的:(初学SVN之 用Python写SVN的钩子文件)