1 #!/bin/bash/python
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 "===============代码行差异为:=================
"
146 print "代码行总数 = ",AddedLineNum," 行"
147 print "全部文件总数 = ",AddFileNum," 个
"
148 print "排除文件总数 = ",ExcludeFileNum," 个
"
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、svn1.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:如果使用的是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)
