任务要求:用户给出一个时间起点和一个终点, 检出此时间段内每天的svn库中的源代码进行代码行变化分析。
pysvn方案
pysvn检出特定日期源代码需要在checkout(或者export)方法中的revision 参数中设置日期值,此参数是一个pysvn.Revision对象, 构造此对象需要提供一个float型的参数(从epoch到指定日期的秒数), 因此将一个可指定偏移量的日期时间对象转换为这个float对象是程序的难点,具体方法是:
利用date(或者datetime)对象和timedelta得到区间内每天的date对象 => 转换为字符串 => 用time.strptime()方法将其转换为struct_time对象 => 用time.mktime()方法将其转换为float时间。
源代码:
from datetime import datetime, timedelta
theDay = datetime.strptime('2011-4-1', "%Y-%m-%d")
yesterday = theDay - timedelta(days=1)
yesterdayStr = yesterday.strftime("%Y-%m-%d")
print yesterdayStr
或者转换为float时间:
import os, sys, commands, shutil, time
from datetime import date, timedelta
sys.path.append('E:/BVT/Hudson/jobs/GODU/workspace/GODU_BVT/tools')
os.environ['Path'] = 'E:/BVT/Hudson/jobs/GODU/workspace/GODU_BVT/tools;'+os.getenv('Path')
proj_list = ['GODU_SERVER', 'GAPI', 'GODU_WEB']
src_path = os.path.join(os.getcwd(),'checkoutSrc')
svn_root = 'http://10.0.2.59:8118/svn/godu/Development-Area/3-SCL/Trunk/'
svn_path_list = ['GODU_SERVER', 'GAPI', 'GODU_Web/goduDS']
def createReport(startYear, startMon, startDay, endYear, endMon, endDay):
try:
resultFile = open('diffcountReport.txt','wt')
import pysvn
svn_client = pysvn.Client()
svn_client.set_default_username('bvt')
svn_client.set_default_password('bvt')
startDate = date(startYear, startMon, startDay)
endDate = date(endYear, endMon, endDay)
timeSpan = (endDate - startDate).days + 1
for i in range(timeSpan):
theDay = startDate+timedelta(days=i)
yesterday = theDay - timedelta(days=1)
dayStr = str(theDay)
timeStruct = time.strptime(dayStr,"%Y-%m-%d")
# if dayStr is a datetime object, the format string should be "%Y-%m-%d %H:%M:%S"
timeFloat = time.mktime(timeStruct)
revdate = pysvn.Revision(pysvn.opt_revision_kind.date, timeFloat)
resultFile.write(dayStr+':\n\n')
try:
for i in range(3):
svn_client.export(svn_root+svn_path_list[i], os.path.join(src_path, dayStr,proj_list[i]),revision=revdate)
oldCodePath = os.path.join(src_path, str(yesterday), proj_list[i])
newCodePath = os.path.join(src_path, dayStr, proj_list[i])
resultFile.write(proj_list[i]+':\n')
resultFile.write(os.popen('diffcount ' + oldCodePath +' '+ newCodePath).read())
except Exception,e:
print e
oldSumCodePath = os.path.join(src_path, str(yesterday))
newSumCodePath = os.path.join(src_path, dayStr)
resultFile.write('Summary:\n')
resultFile.write(os.popen('diffcount ' + oldSumCodePath +' '+ newSumCodePath).read())
return True
finally:
resultFile.close()
if __name__ == '__main__':
createReport(2011, 1, 26, 2011, 3, 30)
svnant方案
svnant中指定时间相对比较简单,因为它的
安装svnant的方法比较简单,将svnant.jar、svnClientAdapter.jar、svnjavahl.jar、svnkit.jar共4个jar包copy到$ANT_HOME/lib下,在build.xml里添加一个taskdef就OK了,见下面的源代码:
<?xml version="1.0" encoding="UTF-8"?>
<project name="CheckoutSrc" basedir="./" default="checkout">
<property name="proj.root.url" value="http://10.0.2.59:8118/svn/godu/Development-Area/3-SCL/Trunk/GAPI/doc"/>
<property name="src.dir" value="${basedir}/checkouts"/>
<typedef classpath="svnant.jar" resource="org/tigris/subversion/svnant/svnantlib.xml"/>
<target name="checkout">
<svn username="bvt" password="bvt" dateFormatter="yyyy-MM-DD">
<export srcUrl="${proj.root.url}" destPath="${src.dir}" revision="2011-01-27"/>
</svn>
</target>
</project>
参考文献:
python中解析日期时间字符串为struct_time对象
pysvn和svnant中取svn的旧版本
不加说明时,pysvn和svnant都是取最新版本(Head版本)的svn数据,但也可以取指定的版本,二者都支持根据版本号或者版本日期两种方式确定export的内容。
pysvn
svn_client.export(config.get('svn','test_proj_path'), config.get('local','build_folder_name'),revision=pysvn.Revision(pysvn.opt_revision_kind.number, 4712)) 详细说明见pysvn文档中对pysvn.Revision对象的说明。
svnant
<export srcUrl="${proj.root.url}/@{projName}" destPath="${build.tmp.dir}" revision="4712"/>
详细说明见svnant中对export的解释:http://subclipse.tigris.org/svnant/svn.html#export