SVN与ReviewBoard联动(1)

公司的SVN服务器是在Windows上的,ReviewBoard是在Linux虚拟服务器上的。
好吧,主要是历史原因了哦。。。

解决思路是,利用SVN的post-commit钩子,在提交后,将版本号存到一个文件中。
在Linux服务器中,定时去扫描这些文件,有变动的话,则利用RBTools提交请求。

1、Windows中用post-commit钩子获取版本号
post-commit.bat

@echo off
SET REPOS=%1%
SET REV=%2%
SET RPATH=PATH_TO_STORE_FILE

CALL :getfilename %REPOS%

echo %REV% >> %RPATH%\%FNAME%.txt

:success
exit 0

:getfilename
set FNAME=%~nx1

2、Linux中用python脚本扫描文件变动
runme.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

'''
Created on 2016-11-24
@author: Hansen
遍历监视文件夹下所有的txt文件
当文件多余两行时,对于每一行,调用rbt生成review请求
最后,只保留最后一行
'''

import os
import sys
import datetime
import nsvnutils

#记录日志
def nlog(logpath,msg):
    fo = open(logpath,'a+')
    try:
        fo.write(msg)
    finally:
        fo.close()

#创建rbt命令,并调用命令
def create_rbt_command(repo, revision1, revision2, logpath):
    title = repo+"_Rev"+revision1
    comment = nsvnutils.get_svn_log(revision1)
    commiter = nsvnutils.get_svn_commiter(revision1)
    #rbt好像不支持utf8参数,因此用更新db的方式添加注释
    cmd = 'rbt post -p --repository ' +repo+" --repository-type svn --server http://127.0.0.1 --api-token API_TOKEN --summary "+title+' '+revision1 
    fo = open(logpath,'a+')
    try:
        fo.write('adding rbt job on '+datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')+'\n')
	fo.write('PWD is '+os.getcwd()+'\n')
	fo.write('CMD is '+cmd+'\n')
	logs = os.popen(cmd.encode('UTF8')).readlines()
        for log in logs:
	   fo.write(log+'\n')
	fo.write('\n')
    finally:
        fo.close()

#写回最后一行
def write_last_line(txtpath,line):
    fo = open(txtpath,'w+')
    try:
	fo.write(line)
    finally:
        fo.close()

#遍历行
#多于两行则自动生成post review
def enum_line(txtpath,logpath,repo):
    nlog('/mnt/rb/rb.log','Trying repositor '+repo+'\n')
    fi = open(txtpath)
    try:
	lines=fi.readlines()
	linesize=len(lines)
	if linesize <= 1:
            nlog('/mnt/rb/rb.log','Skiping repositor '+repo+'\n')
            return

        for i in range(0, linesize):
            if i+1<linesize:
		rbRepo = nsvnutils.get_repo_name(repo)
                if len(rbRepo)==0 :
                    nlog('/mnt/rb/rb.log','Skiping repositor '+repo+'\n')
                    return

                nlog('/mnt/rb/rb.log','Parsing repository '+rbRepo+'\n')
		create_rbt_command(rbRepo,lines[i].replace('\n','').replace('\r',''),lines[i+1].replace('\n','').replace('\r',''),logpath)
    except Exception as ex:
        nlog('/mnt/rb/rb.log',str(ex))
    finally:
        fi.close()

    write_last_line(txtpath,lines[linesize-1])

#递归遍历文件
def enum_file(targetdir,sufix,logpath):
    for root, dirs, files in os.walk(targetdir, True):
        for fname in files:
            fsufix = os.path.splitext(fname)[1][1:]
	    repo = os.path.splitext(fname)[0]
            if sufix == fsufix:
                txtpath = root+"/"+fname
                #txtpath = root+"\\"+fname
		enum_line(txtpath,logpath,repo)


#start here
nlog("/mnt/rb/rb.log", 'Starting job on '+datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')+'\n')
enum_file("/mnt/rb","txt", "/mnt/rb/rb.log")
#enum_file("D:/MyProducts/Python/ReviewBoard/rb","txt", "D:/MyProducts/Python/ReviewBoard/rb/rb.log")
nlog("/mnt/rb/rb.log", 'Ending job on '+datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')+'\n')

nsvnutils.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

'''
Created on 2016-11-24
@author: Hansen
获取指定svn文件夹下,指定svn版本的注释
'''

import os
import sys

#切换路径,并获取repository名称
def get_repo_name(repo):
    mydict = {'REPO1':'REPO1','REPO2':'REPO2'}
    if not mydict.get(repo):
        return '' 
    os.chdir('/home/neohope/repository/'+mydict.get(repo))
    #os.chdir('D:/MyProducts/Python/ReviewBoard/repo/'+mydict(repo))
    return mydict[repo]

#获取指定svn版本的注释
def get_svn_log(revision):
    cmd = 'svn log -r '+revision
    logs = os.popen(cmd).readlines()
    #for log in logs:
    #    print(log)
    if len(logs)>3:
        print(logs[3].replace('\r','').replace('\n',''))
        return logs[3].replace('\r','').replace('\n','')
    else:
        print('no svn comment') 
        return 'no svn comment'

#获取指定svn版本的提交者
def get_svn_commiter(revision):
    cmd = 'svn log -r '+revision
    logs = os.popen(cmd).readlines()
    if len(logs)>2:
        ss=logs[1].split('|')
        if len(ss)>2:
            print(ss[1].strip().replace('\r','').replace('\n',''))
            return ss[1].strip().replace('\r','').replace('\n','')
        else:
            #print('no svn commiter') 
            return 'no svn commiter'
    else:
        #print('no svn commiter') 
        return 'no svn commiter'

#start here
#get_svn_log('193')
#get_svn_commiter('193')

3、建立定时任务,执行脚本

crontab -l

#半小时运行一次
*/30 * * * * /home/neohope/scripts/runme.py

比较麻烦的是,仍需要在Linux下面,先把SVN的repository检出才可以。
同时要注意,要做好SVN及ReviewBoard之间名称的映射。。。

Leave a Reply

Your email address will not be published. Required fields are marked *

*