1 #!/bin/bash 2 # -*-coding:utf-8-*- 3 #svn统计url代码行数脚本,过滤空行,不过滤注释。 4 5 import subprocess,os,sys,time,re,shutil 6 from optparse import OptionParser 7 8 #初始化temp文件: 9 FOLDER = "/tmp/temp_cm_svn_resource_total/" 10 #初始化设置私密配置文件: 11 PRIVATE_FILE = "/home/wwl/conf/wwl_private.conf" 12 #Exclude条件: 13 EXCLUDE = r"\.(txt|dic|properties|xml|config|log|key|pem|crt|per|sql|prefs|ver|gif|png|jpg|war|jar|swf|)$" 14 15 #清理temp文件夹 16 def clean(): 17 if os.path.exists(FOLDER): 18 shutil.rmtree(FOLDER) 19 print "清理temp文件夹成功。" 20 else: 21 print "temp文件夹不存在。" 22 23 #创建temp文件夹 24 def mkdir(): 25 #os.mkdir(FOLDER) 26 os.makedirs(FOLDER) 27 print "创建temp文件夹成功。" 28 29 #读取配置文件,私密信息 30 def get_conf_private(): 31 if os.path.isfile(PRIVATE_FILE): 32 with open(PRIVATE_FILE,‘r‘) as private: 33 for line in private: 34 if line.startswith(‘SVN_USERNAME‘): 35 username = line.split(‘=‘)[1] 36 elif line.startswith(‘SVN_PASSWORD‘): 37 passwd = line.split(‘=‘)[1] 38 return (username,passwd) 39 else: 40 print "svn配置文件不存在,联系值班CM!!!" 41 sys.exit(1) 42 43 #检验svn的用户名、密码和url是否正确 44 def svn_check_url_u_p(uname,pword,url,temp_svninfo): 45 cmd = "svn info --no-auth-cache --non-interactive --username=‘%s‘ --password=‘%s‘ %s >%s" %(uname,pword,url,temp_svninfo) 46 p = subprocess.Popen(cmd,shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE) 47 (stderr_test,stdout_test) = p.communicate() 48 if len(stderr_test) == 0: 49 print "url正确,svn账号密码正确:",url 50 elif ‘authorization failed‘ in stderr_test: 51 print "svn账号密码不正确,请联系值班CM!!!" 52 sys.exit(1) 53 elif ‘Not a valid URL‘ in stderr_test: 54 print "url错误,请检查配置:",url 55 sys.exit(1) 56 57 #获取svn list url文件 并处理目录文件: 58 def svn_list(uname,pword,url,temp_svnlist): 59 cmd = "svn list -R --no-auth-cache --non-interactive --username=‘%s‘ --password=‘%s‘ %s |grep -v ‘\/$‘ >>%s" %(uname,pword,url,temp_svnlist) 60 p = subprocess.Popen(cmd,shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE) 61 (stderr_test,stdout_test) = p.communicate() 62 if len(stderr_test) == 0: 63 print "svn list Success..." 64 else: 65 print "svn list Error...请联系值班CM!!!" 66 sys.exit(1) 67 68 #处理svn list文件: 69 def deal_with_svnlist(uname,pword,ufile): 70 cmd = "svn blame --no-auth-cache --non-interactive --username=‘%s‘ --password=‘%s‘ %s |awk ‘NF>2‘ |wc -l" %(uname,pword,ufile) 71 p = subprocess.Popen(cmd,shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE) 72 (stderr_test,stdout_test) = p.communicate() 73 if stdout_test.startswith("Skipping binary file"): 74 print "Skipping binary file : ",ufile 75 return 0 76 else: 77 return int(stdout_test) 78 79 #判断过滤条件: 80 def is_ignore_svn(file_name): 81 ignore_file_pattern_svn = EXCLUDE 82 match = re.search(ignore_file_pattern_svn,file_name) 83 if match == None: 84 return False 85 else: 86 return True 87 88 def main(): 89 #获取当前时间戳: 90 print "####******Begin testing at: ",time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())," ********####" 91 now_time = time.strftime("%Y%m%d%H%M%S",time.localtime()) 92 clean() 93 mkdir() 94 temp_svninfo = os.path.join(FOLDER,"temp_svninfo."+now_time) 95 temp_svnlist = os.path.join(FOLDER,"temp_svnlist."+now_time) 96 97 #获取命令行参数并赋值给变量 98 parser = OptionParser() 99 parser.add_option("-o",dest="url",default="",help="-o URL svn URL地址") 100 parser.add_option("-u",dest="username",default=get_conf_private()[0].strip(),help="-u USER_NAME svn服务器用户名") 101 parser.add_option("-p",dest="passwd",default=get_conf_private()[1].strip(),help="-p PASSWD svn服务器密码") 102 parser.add_option("-f",dest="judge",default="N",help="-f yes|YES|Y|y 是否打印文件列表") 103 104 (options,args)=parser.parse_args() 105 106 url = options.url.strip() 107 #判断url参数是否赋值: 108 if len(url) == 0: 109 print "url不能为空,请检查输入!!!" 110 sys.exit(1) 111 112 #检查url是否正确,svn账号密码是否正确 113 svn_check_url_u_p(options.username,options.passwd,url,temp_svninfo) 114 115 #获取svn list url文件 并处理目录文件: 116 svn_list(options.username,options.passwd,url,temp_svnlist) 117 118 #初始化赋值: 119 AddedLineNum = 0 120 AddFileNum = 0 121 ExcludeFileNum = 0 122 123 #是否显示增加文件: 124 if options.judge in [‘Y‘,‘YES‘,‘y‘,‘yes‘]: 125 with open(temp_svnlist,‘r‘) as svnlist: 126 print "本次增加的文件:" 127 for file in svnlist: 128 print file 129 else: 130 print "本次跳过的文件:" 131 132 #处理svnlist文件: 133 with open(temp_svnlist,‘r‘) as svnlist: 134 for file in svnlist: 135 AddFileNum += 1 136 if is_ignore_svn(file): 137 print "Skipping file : ",file 138 ExcludeFileNum += 1 139 else: 140 ufile = os.path.join(url,file).strip() 141 AddedLineNum += deal_with_svnlist(options.username,options.passwd,ufile) 142 143 clean() 144 145 print "===============代码行差异为:=================\n" 146 print "代码行总数 = ",AddedLineNum," 行" 147 print "全部文件总数 = ",AddFileNum," 个\n" 148 print "排除文件总数 = ",ExcludeFileNum," 个\n" 149 print "=============代码行统计完成!=================" 150 print "####******End of testing at: ",time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())," **********####" 151 print "%s%d" %(‘a‘,AddedLineNum) 152 153 if __name__ == "__main__": 154 main()
wwl_private.conf文件用于存放默认的svn账号密码:(如果执行python的时候没有输入-u -p 脚本调用此私密配置)
#(username) SVN_USERNAME=wwl #(password) SVN_PASSWORD=wwl
使用环境:python2.7、svn2.6、Ubuntu13.04
使用命令:python xxx.py -o "url" -f y -u "name" -p "password"
背景说明:统计一个svn的url代码总行数其实也可以使用前面那个diff脚本,其中old_url设置为一个空url。
但是有2点不足:
1.svn diff只能在同一个物理库中进行,如果有多个物理库需要对应建多个空url;
2.如果url里面包含的代码非常多,使用diff脚本生成的temp文件将会很庞大,解析temp文件很慢甚至卡死。
脚本解析:使用svn info 命令判断url是否正确,svn用户名、密码是否正确;
使用svn list 输出此url包含的所有文件名到temp文件并排除以‘/‘结尾的文件夹;
使用svn blame 遍历所有文件并计算非空行数,排除二进制文件;
设置过滤器EXCLUDE,过滤指定文件不统计;
过滤空行增删,不过滤注释;
PS:如果使用的是svn2.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)