#!/bin/bash/python
# -*-coding:utf-8-*-
#svn统计不同url代码行数变更脚本,过滤空行,不过滤注释。
import subprocess,os,sys,time,re,shutil
from optparse import OptionParser #初始化temp文件:
FOLDER = "/tmp/temp_cm_svnrtagdiff"
#初始化设置私密配置文件:
PRIVATE_FILE = "/home/wwl/conf/wwl_private.conf"
#Exclude条件:
EXCLUDE = r"\.(txt|dic|properties|xml|config|log|key|pem|crt|per|sql|prefs|ver|gif|png|jpg|war|jar|swf|)$" #清理temp文件夹
def clean():
if os.path.exists(FOLDER):
shutil.rmtree(FOLDER)
print "清理temp文件夹成功。"
else:
print "temp文件夹不存在。" #创建temp文件夹
def mkdir():
#os.mkdir(FOLDER)
os.makedirs(FOLDER)
print "创建temp文件夹成功。" #读取配置文件,私密信息
def get_conf_private():
if os.path.isfile(PRIVATE_FILE):
with open(PRIVATE_FILE,'r') as private:
for line in private:
if line.startswith('SVN_USERNAME'):
username = line.split('=')[1]
elif line.startswith('SVN_PASSWORD'):
passwd = line.split('=')[1]
return (username,passwd)
else:
print "svn配置文件不存在,联系值班CM!!!"
sys.exit(1) #检验svn的用户名、密码和url是否正确
def svn_check_url_u_p(uname,pword,url,temp_svninfo):
cmd = "svn info --no-auth-cache --non-interactive --username='%s' --password='%s' %s >%s" %(uname,pword,url,temp_svninfo)
p = subprocess.Popen(cmd,shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE)
(stderr_test,stdout_test) = p.communicate()
#p.wait() 使用wait()容易造成死锁。
#stderr_test = p.stderr.read()
if len(stderr_test) == 0:
print "url正确,svn账号密码正确:",url
elif 'authorization failed' in stderr_test:
print "svn账号密码不正确,请联系值班CM!!!"
sys.exit(1)
elif 'Not a valid URL' in stderr_test:
print "url错误,请检查配置:",url
sys.exit(1) #比较两个url之间的差异:
def svn_diff_url_o_n(old_url,new_url,uname,pword,temp_svndiff):
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)
p = subprocess.Popen(cmd,shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE)
(stderr_test,stdout_test) = p.communicate()
#p.wait()
#stderr_test = p.stderr.read()
if len(stderr_test) == 0:
print "svn diff Sucess!!!"
else:
print "svn diff Error,请联系值班CM!!!"
sys.exit(1) #判断过滤条件:
def is_ignore_svn(file_name):
ignore_file_pattern_svn = EXCLUDE
match = re.search(ignore_file_pattern_svn,file_name)
if match == None:
return False
else:
return True #判断是否为二进制文件:
def is_binary(uname,pword,newuf,olduf=None):
cmd = "svn blame --no-auth-cache --non-interactive --username='%s' --password='%s' %s" %(uname,pword,newuf)
p = subprocess.Popen(cmd,shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE)
(stderr_test,stdout_test) = p.communicate()
#p.wait()
#stderr_test = p.stderr.read()
if stderr_test.startswith("Skipping binary file"):
return True
elif stderr_test.startswith("svn: warning: W160017"):
return is_binary(uname,pword,olduf)
else:
return False def main():
#获取当前时间戳:
print "####******Begin testing at: ",time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())," ********####"
now_time = time.strftime("%Y%m%d%H%M%S",time.localtime())
clean()
mkdir()
temp_svninfo = os.path.join(FOLDER,"temp_svninfo."+now_time)
temp_svndiff = os.path.join(FOLDER,"temp_svndiff."+now_time) #获取命令行参数并赋值给变量
parser = OptionParser()
parser.add_option("-o",dest="old_url",default="",help="-o old_SVN_REPOSITORY_URL 旧的svn URL地址")
parser.add_option("-n",dest="new_url",default="",help="-n new_SVN_REPOSITORY_URL 新的svn URL地址")
parser.add_option("-u",dest="username",default=get_conf_private()[0].strip(),help="-u USER_NAME svn服务器用户名")
parser.add_option("-p",dest="passwd",default=get_conf_private()[1].strip(),help="-p PASSWD svn服务器密码")
parser.add_option("-f",dest="judge",default="N",help="-f yes|YES|Y|y 是否打印文件列表") (options,args)=parser.parse_args() old_url = options.old_url.strip()
new_url = options.new_url.strip()
#判断old_url和new_url参数是否赋值
if len(old_url) == 0:
print "请输入old_SVN_REPOSITORY_URL:"
sys.exit (1)
if len(new_url) == 0:
print "请输入new_SVN_REPOSITORY_URL:"
sys.exit (1) #检查url是否正确,svn账号密码是否正确
svn_check_url_u_p(options.username,options.passwd,old_url,temp_svninfo)
svn_check_url_u_p(options.username,options.passwd,new_url,temp_svninfo) #比较两个url之间的差异:
svn_diff_url_o_n(old_url,new_url,options.username,options.passwd,temp_svndiff) #初始化参数:
AddLineNum = 0
DelLineNum = 0
ModLineNum = 0
TotalLineNum = 0
ModFileNum = 0
ExcludeFileNum = 0
TotalFileNum = 0 #处理temp_svndiff文件
#判断diff文件是否为空:
if len(open(temp_svndiff,'r').read()) == 0:
print "没有变更!!!"
else:
dict = {}
with open(temp_svndiff,'r') as svndiff:
for line in svndiff:
if line.startswith("Index:"):
key = line.split(':')[-1].strip()
if key not in dict:
dict[key] = [0,0]
if line.startswith('+') and len(line.strip()) > 1:
dict[key][0] += 1
if line.startswith('+++'):
dict[key][0] -= 1
if line.startswith('-') and len(line.strip()) > 1:
dict[key][1] += 1
if line.startswith('---'):
dict[key][1] -= 1 #判断是否显示本次所有的变更文件:
if options.judge in ['Y','y','YES','yes']:
print "本次变更的文件:"
for line in dict.keys():
print line
else:
print "本次跳过的文件:" TotalFileNum = len(dict.keys())
for file in dict.keys():
olduf = os.path.join(old_url,file)
newuf = os.path.join(new_url,file)
if file == '.':
TotalFileNum -= 1
elif is_ignore_svn(file):
print "Skipping file : ",file
ExcludeFileNum += 1
elif is_binary(options.username,options.passwd,newuf,olduf):
print "Skipping binary file : ",file
ExcludeFileNum += 1
else:
AddLineNum += dict[file][0]
DelLineNum += dict[file][1]
TotalLineNum = AddLineNum + DelLineNum clean() print "===============代码行差异为:=================\n"
print "新增的代码行 = ",AddLineNum," 行"
print "删除的代码行 = ",DelLineNum," 行\n"
print "代码行变更总计 = ",TotalLineNum," 行\n"
print "变更文件总数 = ",TotalFileNum," 个\n"
print "排除文件总数 = ",ExcludeFileNum," 个\n"
print "=============代码行统计完成!================="
print "####******End of testing at: ",time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())," **********####"
196
if __name__ == "__main__":
main()
wwl_private.conf文件用于存放默认的svn账号密码:(如果执行python的时候没有输入-u -p 脚本调用此私密配置)
#(username)
SVN_USERNAME=wwl
#(password)
SVN_PASSWORD=wwl

如果找不到wwl_private.conf私密文件,可以修改代码,直接返回你知道的原文密码

使用环境: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替换成下面代码

#检验svn的用户名、密码和url是否正确
def svn_check_url_u_p(uname,pword,url,temp_svninfo):
cmd = "svn info --no-auth-cache --non-interactive --username='%s' --password='%s' %s >%s" %(uname,pword,url,temp_svninfo)
p = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
(stderr_test,stdout_test) = p.communicate()
if len(stderr_test) == 0:
print "url正确,svn账号密码正确:",url
elif 'E170001' in stderr_test:
print "svn账号密码不正确,请联系值班CM!!!"
sys.exit(1)
elif 'E000002' in stderr_test:
print "url错误,请检查配置:",url
sys.exit(1)

Python 统计不同url svn代码变更数的更多相关文章

  1. python统计一个文本中重复行数的方法

    python统计一个文本中重复行数的方法 这篇文章主要介绍了python统计一个文本中重复行数的方法,涉及针对Python中dict对象的使用及相关本文的操作,具有一定的借鉴价值,需要的朋友可以参考下 ...

  2. Python-统计svn代码总行数

    1 #!/bin/bash/python 2 # -*-coding:utf-8-*- 3 #svn统计url代码行数脚本,过滤空行,不过滤注释. 4 5 import subprocess,os,s ...

  3. 【Python基础】计算项目代码行数

    统计代码行数 # coding: utf-8 import os import sys import time def get_line_count(file_path): ""& ...

  4. linux下shell统计文件目录下所有代码行数

    功能,统计某一目录下所有文件代码行数: 例如统计某一目录下所有.c结尾的文件代码行数:find . -name "*.c"|xargs cat|grep -v ^$|wc -l ^ ...

  5. vs2010 vs2013等vs中如何统计整个项目的代码行数

    在一个大工程中有很多的源文件和头文件,我如何快速统计总行数? ------解决方案--------------------b*[^:b#/]+.*$^b*[^:b#/]+.*$ ctrl + shif ...

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

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

  7. 使用vs的查找功能,简单大概的统计vs中的代码行数

    VS强大的查找功能,可以使用正则表达式来进行查找,这里统计代码行数的原理就是: 在所有指定文件中进行搜索,统计匹配的文本行数. 但是匹配的行需要满足:非注释.非空等特殊非代码行. 使用Ctrl+Shi ...

  8. Linux统计文件个数或是代码行数

    统计指定后缀名的文件总个数命令: find . -name *.cpp | wc -l 统计一个目录下代码总行数以及单个文件行数: find . -name *.h | xargs wc -l lin ...

  9. vs2017 vs2013等vs中如何统计整个项目的代码行数

    在一个大工程中有很多的源文件和头文件,我如何快速统计总行数? ------解决方案--------------------b*[^:b#/]+.*$^b*[^:b#/]+.*$ ctrl + shif ...

随机推荐

  1. 使用Myeclipse导入IDEA项目

    问题描述:使用Myeclipse导入IDEA创建的Web项目,成功导入,但是显示的是一个普通的JAVA项目,无法加载到tomcat下. 解决方案:右键项目Properties,选择Myeclipse- ...

  2. VS 快速插入无参构造器

    输入ctor后 点击两次Tab键,即可快速插入无参构造器.

  3. ssh RSA key变化后处理

    root@localhost:/# scp -r root@172.19.47.30:/home/linux-4.16.2-devm.1.2.aarch64.dongbo ./@@@@@@@@@@@@ ...

  4. [转]用JS获取地址栏参数的方法(超级简单)

    本文转自:http://www.cnblogs.com/fishtreeyu/archive/2011/02/27/1966178.html 方法一:采用正则表达式获取地址栏参数:( 强烈推荐,既实用 ...

  5. Windows Server 2012 R2

    Windows Server 2012 R2 历史上的Server有2003 server, 2008 server, 2012 server windows server 2012 r2对计算机的消 ...

  6. tck/tl 以及expect脚本

    最近有用到,利用expcet脚本自动登录到远程服务器并提权执行脚本. 搜集的知识如下: tcl/tk参考——列表操作lindex expect脚本解释 代码如下 #!/usr/bin/expect - ...

  7. Hibernate课程 初探多对多映射3-1 课程总结

    如何通过添加中间表实现多对多? 1 在双方实体中添加一个保存对方的集合. 2 在双方映射文件中 使用<set>和<many-to-many>元素进行关联关系配置(注意此处)

  8. IDEA中使用spring官方模板+@Controller

    视图层处理http请求用@Controller时,要配合模板的使用,模板类似javaweb中的jsp,但是模板的引擎用的是 thymeleaf ,但是并不推荐. 现在的开发模式都是前后端分离,做后端只 ...

  9. Java类与对象初始化的过程(一道经典的面试题)

    本文不再以ClassLoader的视角解释这些问题. 首先,Java代码有个特点,就是成员变量可以在前面的方法中使用,在后面定义.这一特性,很多人说Java了不起,可是为什么呢?Java为何能够这样呢 ...

  10. API:Sign签名的执行流程

    Sign签名存在目的:为了防止不法分子修改参数数据,进而攻击服务器,导致数据泄露或从中获得利益    例如:一个接口是用户把积分转帐给他的朋友,修改后,变为转帐到攻击者的帐户,这样,攻击者就能得到利益 ...