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 "===============代码行差异为:=================\n"
188 print "新增的代码行 = ",AddLineNum," 行"
189 print "删除的代码行 = ",DelLineNum," 行\n"
190 print "代码行变更总计 = ",TotalLineNum," 行\n"
191 print "变更文件总数 = ",TotalFileNum," 个\n"
192 print "排除文件总数 = ",ExcludeFileNum," 个\n"
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)

Python-统计svn变更代码行数的更多相关文章

  1. 代码管理_Git中获取两个标签之间的变更代码行数

    操作步骤: 1.先进入git的服务器,定位到 repositories 目录 2.再定位到具体的项目目录(登录bitbucket查看项目属性可以看到项目的存放目录),如下图: 3.浏览项目的标签,命令 ...

  2. VS里统计整个解决方案代码行数的方法

    VS里统计整个解决方案代码行数,在查找里输入正则表达式:b*[^:b#/]+.*$.如下图所示: 结果如下图所示:

  3. Android Stduio统计项目的代码行数

    android studio统计项目的代码行数的步骤如下: 1)按住Ctrl+Shift+A,在弹出的框输入‘find’,然后选择Find in Path.(或者使用快捷键Ctrl+Shift+F) ...

  4. 统计C/C++代码行数

    近日在写一个统计项目中C/C++文件(后缀名:C/CPP/CC/H/HPP文件)代码行数的小程序.给定包含C/C++代码的目录,统计目录里所有C/C++文件的总代码行数.有效代码行数.注释行数.空白行 ...

  5. Python实现代码行数统计工具

    我们经常想要统计项目的代码行数,但是如果想统计功能比较完善可能就不是那么简单了, 今天我们来看一下如何用python来实现一个代码行统计工具. 思路:首先获取所有文件,然后统计每个文件中代码的行数,最 ...

  6. VS 统计整个项目总的代码行数

    vs如何快速统计项目总代码行数呢,如下: vs编辑 | 查找和替换 | 在文件中查找 查找选项选 选择正则表达式 ^b*[^:b#/]+.*$ 设置如下:  结果在查找结果的最后一行,如下 

  7. Xcode 统计项目代码行数及常用快捷键

    1.统计Xcode项目代码行数 1   打开终端. 2  用ls和cd进到你项目的路径. 3   输入下面的指令: grep -r "\n" classes | wc -l (cl ...

  8. python 脚本(获取指定文件夹、指定文件格式、的代码行数、注释行数)

    1.代码的运行结果: 获取 指定文件夹下.指定文件格式 文件的: 总代码行数.总注释行数(需指定注释格式).总空行数: #coding: utf-8 import os, re # 代码所在目录 FI ...

  9. Git代码行数统计命令

    统计zhangsan在某个时间段内的git新增删除代码行数 git log --author=zhangsan--since=2018-01-01 --until=2019-04-01 --forma ...

随机推荐

  1. Unity Shader _Time 的单位

    名称 类型 说明 _Time float4 t 是自该场景加载开始所经过的时间,4个分量分别是 (t/20, t, t*2, t*3) _SinTime float4 t 是时间的正弦值,4个分量分别 ...

  2. Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out

    问题: java连接不上redis. 异常信息: Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.ne ...

  3. C#泛型委托Predicate、Action、Func

    Predicate Predicate泛型委托:表示定义一组条件并确定指定对象是否符合这些条件的方法.此委托由 Array 和 List 类的几种方法使用,用于在集合中搜索元素.通过查看源码发现 Pr ...

  4. Library drmframework_jni not found

    http://piotrbuda.eu/2012/06/trying-to-solve-error-491-in-play-store-on-android-emulator.html http:// ...

  5. 详细解读Volley(五)—— 通过源码来分析业务流程

    一.初始化请求队列并运行 我们用Volley时,最先开始的就是初始化请求队列,一种常见的写法如下: public class MyApplication extends Application { p ...

  6. Leetcode刷题记录:编码并解码短网址

    题目要求 编写一个类,提供两个方法.一个可以将普通的网址编码成短网址,一个可以将短网址还原为普通网址. 参考题解 # 使用随机函数,生成短网址,保存在dict中,避免重复 import random ...

  7. CountDownLatch使用场景及分析

    JDk1.5提供了一个非常有用的包,Concurrent包,这个包主要用来操作一些并发操作,提供一些并发类,可以方便在项目当中傻瓜式应用. JDK1.5以前,使用并发操作,都是通过Thread,Run ...

  8. Docker 常用命令与操作

    介绍 此命令集合版本为 1.11.1 及以上 基础类 查看docker信息 # 查看docker版本 docker version # 显示docker系统的信息 docker info # 日志信息 ...

  9. JavaScript-手机中访问页面判断

    最近在做微信服务号开发,其中遇到一个问题是微信服务号查看的个人的消息,如果点击在浏览器中查看(iOS中是在Safari中打开)应该是跳转到登录页面,因为页面需要从后台获取,因为需要服务端判断,如果是存 ...

  10. 手动建库时一个错误:Error accessing PRODUCT_USER_PROFILE

    首先感谢前辈的文章:http://space.itpub.net/14184018/viewspace-691502 手动创建数据库完成后,创建新用户,并用新用户登陆到数据库时,报错如下: SYS@ ...