zoukankan      html  css  js  c++  java
  • Python-统计svn变更代码行数

    1 #!/bin/bash/python
      2 # -*-coding:utf-8-*-
      3 #svn统计不同url代码行数变更脚本,过滤空行,不过滤注释。
      4 import subprocess,os,sys,time,re,shutil
      5 from optparse import OptionParser
      6 
      7 #初始化temp文件:
      8 FOLDER = "/tmp/temp_cm_svnrtagdiff"
      9 #初始化设置私密配置文件:
     10 PRIVATE_FILE = "/home/wwl/conf/wwl_private.conf"
     11 #Exclude条件:
     12 EXCLUDE = r".(txt|dic|properties|xml|config|log|key|pem|crt|per|sql|prefs|ver|gif|png|jpg|war|jar|swf|)$"
     13 
     14 #清理temp文件夹    
     15 def clean():
     16     if os.path.exists(FOLDER):
     17         shutil.rmtree(FOLDER)
     18         print "清理temp文件夹成功。"
     19     else:
     20         print "temp文件夹不存在。"
     21         
     22 #创建temp文件夹
     23 def mkdir():
     24     #os.mkdir(FOLDER)
     25     os.makedirs(FOLDER)
     26     print "创建temp文件夹成功。"
     27 
     28 #读取配置文件,私密信息 
     29 def get_conf_private():
     30     if os.path.isfile(PRIVATE_FILE):
     31         with open(PRIVATE_FILE,'r') as private:
     32             for line in private:
     33                 if line.startswith('SVN_USERNAME'):
     34                     username = line.split('=')[1]
     35                 elif line.startswith('SVN_PASSWORD'):
     36                     passwd = line.split('=')[1]
     37             return (username,passwd)
     38     else:
     39         print "svn配置文件不存在,联系值班CM!!!"
     40         sys.exit(1)
     41 
     42 #检验svn的用户名、密码和url是否正确
     43 def svn_check_url_u_p(uname,pword,url,temp_svninfo):
     44     cmd = "svn info --no-auth-cache --non-interactive --username='%s' --password='%s' %s >%s" %(uname,pword,url,temp_svninfo)
     45     p = subprocess.Popen(cmd,shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE)
     46     (stderr_test,stdout_test) = p.communicate()
     47     #p.wait()   使用wait()容易造成死锁。
     48     #stderr_test = p.stderr.read()
     49     if len(stderr_test) == 0:
     50         print "url正确,svn账号密码正确:",url
     51     elif 'authorization failed' in stderr_test:
     52         print "svn账号密码不正确,请联系值班CM!!!"
     53         sys.exit(1) 
     54     elif 'Not a valid URL' in stderr_test:
     55         print "url错误,请检查配置:",url
     56         sys.exit(1)
     57 
     58 #比较两个url之间的差异:
     59 def svn_diff_url_o_n(old_url,new_url,uname,pword,temp_svndiff):
     60     cmd = "svn  diff --no-auth-cache --non-interactive --old=%s --new=%s --username='%s' --password='%s' >%s" %(old_url,new_url,uname,pword,temp_svndiff)
     61     p = subprocess.Popen(cmd,shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE)
     62     (stderr_test,stdout_test) = p.communicate()
     63     #p.wait()
     64     #stderr_test = p.stderr.read()
     65     if len(stderr_test) == 0:
     66         print "svn diff Sucess!!!"
     67     else:
     68         print "svn diff Error,请联系值班CM!!!"
     69         sys.exit(1)
     70 
     71 #判断过滤条件:        
     72 def is_ignore_svn(file_name):
     73     ignore_file_pattern_svn = EXCLUDE
     74     match = re.search(ignore_file_pattern_svn,file_name)
     75     if match == None:
     76         return False
     77     else:
     78         return True
     79         
     80 #判断是否为二进制文件:
     81 def is_binary(uname,pword,newuf,olduf=None):
     82     cmd = "svn  blame --no-auth-cache --non-interactive --username='%s' --password='%s' %s" %(uname,pword,newuf)
     83     p = subprocess.Popen(cmd,shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE)
     84     (stderr_test,stdout_test) = p.communicate()
     85     #p.wait()
     86     #stderr_test = p.stderr.read()
     87     if stderr_test.startswith("Skipping binary file"):
     88         return True
     89     elif stderr_test.startswith("svn: warning: W160017"):
     90         return is_binary(uname,pword,olduf)
     91     else:
     92         return False
     93 
     94 def main():
     95     #获取当前时间戳:
     96     print "####******Begin testing at: ",time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())," ********####"
     97     now_time = time.strftime("%Y%m%d%H%M%S",time.localtime())
     98     clean()
     99     mkdir()
    100     temp_svninfo = os.path.join(FOLDER,"temp_svninfo."+now_time)
    101     temp_svndiff = os.path.join(FOLDER,"temp_svndiff."+now_time)
    102 
    103     #获取命令行参数并赋值给变量
    104     parser = OptionParser()
    105     parser.add_option("-o",dest="old_url",default="",help="-o  old_SVN_REPOSITORY_URL  旧的svn URL地址")
    106     parser.add_option("-n",dest="new_url",default="",help="-n  new_SVN_REPOSITORY_URL  新的svn URL地址")
    107     parser.add_option("-u",dest="username",default=get_conf_private()[0].strip(),help="-u  USER_NAME   svn服务器用户名")
    108     parser.add_option("-p",dest="passwd",default=get_conf_private()[1].strip(),help="-p  PASSWD  svn服务器密码")
    109     parser.add_option("-f",dest="judge",default="N",help="-f  yes|YES|Y|y             是否打印文件列表")
    110     
    111     (options,args)=parser.parse_args()
    112     
    113     old_url = options.old_url.strip()
    114     new_url = options.new_url.strip()
    115     #判断old_url和new_url参数是否赋值
    116     if len(old_url) == 0:
    117         print "请输入old_SVN_REPOSITORY_URL:"
    118         sys.exit (1)
    119     if len(new_url) == 0:
    120         print "请输入new_SVN_REPOSITORY_URL:"
    121         sys.exit (1)
    122 
    123     #检查url是否正确,svn账号密码是否正确
    124     svn_check_url_u_p(options.username,options.passwd,old_url,temp_svninfo)
    125     svn_check_url_u_p(options.username,options.passwd,new_url,temp_svninfo)
    126     
    127     #比较两个url之间的差异:
    128     svn_diff_url_o_n(old_url,new_url,options.username,options.passwd,temp_svndiff)
    129     
    130     #初始化参数:
    131     AddLineNum = 0
    132     DelLineNum = 0
    133     ModLineNum = 0
    134     TotalLineNum = 0
    135     ModFileNum = 0
    136     ExcludeFileNum = 0
    137     TotalFileNum = 0
    138     
    139     #处理temp_svndiff文件
    140     #判断diff文件是否为空:
    141     if len(open(temp_svndiff,'r').read()) == 0:
    142         print "没有变更!!!"
    143     else:
    144         dict = {}
    145         with open(temp_svndiff,'r') as svndiff:
    146             for line in svndiff:
    147                 if line.startswith("Index:"):
    148                     key = line.split(':')[-1].strip()
    149                     if key not in dict:
    150                         dict[key] = [0,0]
    151                 if line.startswith('+') and len(line.strip()) > 1:
    152                     dict[key][0] += 1
    153                 if line.startswith('+++'):
    154                     dict[key][0] -= 1
    155                 if line.startswith('-') and len(line.strip()) > 1:
    156                     dict[key][1] += 1
    157                 if line.startswith('---'):
    158                     dict[key][1] -= 1
    159         
    160         #判断是否显示本次所有的变更文件:
    161         if options.judge in ['Y','y','YES','yes']:
    162             print "本次变更的文件:"
    163             for line in dict.keys():
    164                 print line
    165         else:
    166             print "本次跳过的文件:"
    167             
    168         TotalFileNum = len(dict.keys())
    169         for file in dict.keys():
    170             olduf = os.path.join(old_url,file)
    171             newuf = os.path.join(new_url,file)
    172             if file == '.':
    173                 TotalFileNum -= 1
    174             elif is_ignore_svn(file):
    175                 print "Skipping file : ",file
    176                 ExcludeFileNum += 1
    177             elif is_binary(options.username,options.passwd,newuf,olduf):
    178                 print "Skipping binary file : ",file
    179                 ExcludeFileNum += 1
    180             else:
    181                 AddLineNum += dict[file][0]
    182                 DelLineNum += dict[file][1]
    183         TotalLineNum = AddLineNum + DelLineNum
    184     
    185     clean()
    186     
    187     print "===============代码行差异为:=================
    "
    188     print "新增的代码行 = ",AddLineNum," 行"
    189     print "删除的代码行 = ",DelLineNum," 行
    "
    190     print "代码行变更总计 = ",TotalLineNum," 行
    "
    191     print "变更文件总数 = ",TotalFileNum," 个
    "
    192     print "排除文件总数 = ",ExcludeFileNum," 个
    "
    193     print "=============代码行统计完成!================="
    194     print "####******End of testing at: ",time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())," **********####"
    195
    196 197 if __name__ == "__main__": 198 main()
    复制代码
    wwl_private.conf文件用于存放默认的svn账号密码:(如果执行python的时候没有输入-u -p 脚本调用此私密配置)
    #(username)
    SVN_USERNAME=wwl
    #(password)
    SVN_PASSWORD=wwl

    使用环境:python2.7、svn1.6、Ubuntu13.04

    使用命令:python xxx.py -o "old_url" -n "new_url" -f y -u "name" -p "password"

    脚本解析:使用svn info 命令判断url是否正确,svn用户名、密码是否正确;

           使用svn diff 对比2个svn-url输出结果到temp文件,然后解析temp文件;

                  使用svn blame 判断文件是否是二进制文件;

                  设置过滤器EXCLUDE,过滤指定文件不统计;

                  过滤空行增删,不过滤注释。

    弊端:svn diff 命令对一个代码行的修改算成+1行和-1行,此脚本没有另行统计修改的行数。

    改进方案:使用svn diff --diff-cmd /usr/bin/diff 命令调用linux的diff来对比。linux的diff使用(a - 增)(c - 改)(d - 删),比较方便分别计算增删改代码行,后期尝试修改。

     PS:如果使用的是svn1.7版本:检验svn用户名、密码和url替换成下面代码

    复制代码
     1 #检验svn的用户名、密码和url是否正确
     2 def svn_check_url_u_p(uname,pword,url,temp_svninfo):
     3     cmd = "svn info --no-auth-cache --non-interactive --username='%s' --password='%s' %s >%s" %(uname,pword,url,temp_svninfo)
     4     p = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
     5     (stderr_test,stdout_test) = p.communicate()
     6     if len(stderr_test) == 0:
     7         print "url正确,svn账号密码正确:",url
     8     elif 'E170001' in stderr_test:
     9         print "svn账号密码不正确,请联系值班CM!!!"
    10         sys.exit(1) 
    11     elif 'E000002' in stderr_test:
    12         print "url错误,请检查配置:",url
    13         sys.exit(1)
  • 相关阅读:
    我的知识库(4) java获取页面编码(Z)
    知识库(3)JAVA 正则表达式 (超详细)
    The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the associated filter. Struts
    某人总结的《英语听力的技巧 》,挺搞的
    我的知识库(5)java单例模式详解
    构建可扩展程序
    SerialPort (RS232 Serial COM Port) in C# .NET
    Python学习笔记——String、Sequences
    UI题目我的答案
    jQuery学习系列学会操纵Form表单元素(1)
  • 原文地址:https://www.cnblogs.com/hushaojun/p/4277643.html
Copyright © 2011-2022 走看看