DarkMatter in Cyberspace
  • Home
  • Categories
  • Tags
  • Archives

用pysvn和svnant检出某一日期的svn库中的源代码


任务要求:用户给出一个时间起点和一个终点, 检出此时间段内每天的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中指定时间相对比较简单,因为它的本身就接受字符串格式的日期,但ant中并没有提供日期偏移的方法,因此如果只检出1天(或几天)的代码,用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



Published

Mar 28, 2011

Last Updated

Mar 28, 2011

Category

Tech

Tags

  • 检出 1
  • pysvn 1
  • 日期 5
  • svnant 1

Contact

  • Powered by Pelican. Theme: Elegant by Talha Mansoor