SVN+HOOK -- 配置管理钩子

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys , os

#lockFlag = False
'''
@summary: 错误码定义
'''
class errorCode:
    Successed       =0000           #成功
    InteralFailed   = 0001          #内部错误
    LogLengthError  = 0002          #日志长度错误
    DirectoryChangeError = 0003     #目录管理错误
    fileTypeError = 0004            #文件类型错误
    fileTooLarge = 0005             #文件大小错误
    SvnLock = 9999                  #SVN配置库已加锁
'''
@summary: 提交时更改类型
'''
class svnChange:
    addDirectory = 0001
    addFile          = 0002
    removeDirectory = 0003
    removeFile = 0004
    modiFile = 0005
    normal = 0006

class constValue:
    commitLogLength = 10
    maxFileLength       = 1024*1024*100
    lockFlag = False
    superUser = ('cshuang','manageruser')
    fliterFile = ('ZIP','EXE','TAR','RAR','GZ','RPM')
    managerIp = '192.168.4.50'

class userInfo:
    def __init__(self,name,aliasName):
        self.name=name
        self.Alias = aliasName
    @staticmethod
    def initAllUser():
        usrList = list()
        return usrList

class svnCommitHook:
    '''
    classdocs
    '''

    svnLookPath=r'/usr/local/subversion/bin/svnlook '
    svnAdminPath=r''
    def __init__(self):
        '''
        Constructor
        '''
        self.DeposityLocation = None
        self.RTNS = None
        self.logerMinLength = 10
        self.fileList = list()
        
    
    '''
    @summary: 检查提交时日志信息,日志长度必须大于 MIN-LOG-LENGTH
    '''
    def checkLogsLength (self):
        cmd = svnCommitHook.svnLookPath + ' log -t "%s" "%s"'% (self.RTNS, self.DeposityLocation)
        
        logmessage = ''#!/usr/bin/env python

        
        for line in os.popen(cmd,'r').readlines():
            logmessage = logmessage + line.replace('\n','')

        if(len(logmessage) > 10):
            return errorCode.Successed
        else:
            return errorCode.LogLengthError
        
        return errorCode.Successed
    
    def isSpecialFile(self,filename):
        if filename == None:
            return False
        splitStrList = filename.split('.')
        if len(splitStrList) < 2:
            return False
        
        if splitStrList[-1] in constValue.fliterFile:
            return True
        return False
    def checkChange(self):
        cmd1 = svnCommitHook.svnLookPath + ' author -t "%s" "%s"'% (self.RTNS, self.DeposityLocation)
        p1 = os.popen(cmd1,'r')
        author = p1.read()
        author = author.lstrip()
        author = author.rstrip()
        
        if author in constValue.superUser:
            return errorCode.Successed
        
        cmd2 = svnCommitHook.svnLookPath + ' changed -t "%s" "%s"'% (self.RTNS, self.DeposityLocation)
        p2 = os.popen(cmd2,'r')
        
        changeList = list()
        for one in p2.readlines():
            changeT,filename = self.getChangeType(one)
            
            if changeT == svnChange.addDirectory or changeT == svnChange.removeDirectory:
                return errorCode.DirectoryChangeError
            
            if changeT == svnChange.addFile:
                strFilename = filename.upper()
                if self.isSpecialFile(strFilename):
                    return errorCode.fileTypeError
            #continue
            if changeT == svnChange.addFile or changeT == svnChange.modiFile:
                cmd1 = svnCommitHook.svnLookPath + ' cat -t %s %s %s' % (self.RTNS, self.DeposityLocation,filename)
                pChange = os.popen(cmd1,'r')
                result = len(pChange.read())
                
                if result > constValue.maxFileLength:
                    return errorCode.fileTooLarge
        return errorCode.Successed   

    def packetBlanck(self,src,str = ' '):
        rtn = None
        if src == None:
            return rtn
        
        
        rtn = src.lstrip()
        rtn = rtn.rstrip()
        
        ilen = 0
        ilenEx = len(rtn)
        while ilen != ilenEx:
            ilen = ilenEx
            rtn = rtn.replace(str*2 ,str)
            ilenEx = len(rtn)
        return rtn
             
    '''
    @summary: 获取当前svn提交类型
    '''
    def getChangeType(self,oneChange):
        oneChange = self.packetBlanck(oneChange, ' ')
        splitStr = oneChange.split(' ')

        if len(splitStr) <> 2:
            return svnChange.normal,None
        
        #添加
        if splitStr[0] == 'A':
            if splitStr[1][-1] == '/' or splitStr[1][-1] == '\\':
                return svnChange.addDirectory,splitStr[1]
            else :
                self.fileList.append(splitStr[1])
                return svnChange.addFile,splitStr[1]
        #修改可以不判断
        if splitStr[0] == 'U':
            self.fileList.append(splitStr[1])
            return svnChange.modiFile,splitStr[1]
        
        #删除
        if splitStr[0] == 'D':
            if splitStr[1][-1] == '/' or splitStr[1][-1] == '\\':
                return svnChange.removeDirectory,splitStr[1]
            else :
                return svnChange.removeFile,splitStr[1]
                
    '''
    @summary: 获取提交文件的信息
    '''
    def checkFileInfo(self):
        return errorCode.Successed
    
    '''
    @summary:锁定svn
    '''
    def lockSvn(self):
        #global lockFlag
        if constValue.lockFlag:
            return errorCode.SvnLock
        return errorCode.Successed
    
def main():  
    svnHook = svnCommitHook()
    svnHook.DeposityLocation = sys.argv[1]
    svnHook.RTNS = sys.argv[2]

    if svnHook.checkLogsLength() <> errorCode.Successed:
        sys.stderr.write("强制写日志提示:签入文档或代码必须提供相关说明,并且至少10个字符以上,请补充后重试")
        exit(1)
    
    result = svnHook.checkChange()
    if result <> errorCode.Successed:
        if result == errorCode.DirectoryChangeError:
            sys.stderr.write("目录变更错误:代码库添加、删除、修改目录必须向产品经理申请,申请后,由配置管理员统一添加,并对目录进行权限重新配置。谢谢!")
        elif result == errorCode.fileTypeError:
            sys.stderr.write("签入错误:你签入的文件不符合规定,不能签入可执行文件和任何压缩文件!")
        elif result == errorCode.fileTooLarge:
            sys.stderr.write("签入错误:您签入的文件超过了最大尺寸限制---100兆!")
        exit(1)
    
    if svnHook.lockSvn() <> errorCode.Successed:
        sys.stderr.write("SVN锁定提示:代码库已加锁,暂无法签入任何文档代码,请联系管理员。谢谢!")
        exit(1)
    
    '''fileTooLarge
    @summary: 该函数调用必须在checkChange调用之后
    '''
    #if svnHook.checkFileInfo() <> errorCode.Successed:
        #sys.stderr.write("SVN锁定提示:代码库已加锁,暂无法签入任何文档代码,请联系管理员。谢谢!")
    #    exit(1)
                
    exit(0)
if __name__ == '__main__':  
    main()  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值