zoukankan      html  css  js  c++  java
  • 关于SVN Hooks(钩子)的使用 (1) .

    tags:svn,hooks,svn钩子,Tortoisesvn钩子

    由于工作需要,在svn中经常需要使用到svn hooks,把一些常用的记录在这里。

    1.什么是svn hooks?

    服务器钩子:

    经常提到的svn hooks是一组“外挂”脚本程序,是svn提供的一组由svn事件触发的特别有用的程序。这些程序在服务器端执行,可以提供svn之外的一些附加功能。钩子可以调用批处理文件、可执行文件或者一些类似于perl、python等的脚本。


    客户端钩子:

    如果使用tortoise svn(海龟svn,常用的svn客户端),它也提供钩子机制,这些和svn hooks有本质区别,它是在本地(客户端)执行的。


    2.svn hooks有哪些?

    服务器钩子:

    svn服务端有9种钩子,分别是:

    A.关于锁定的2种

    a1.pre-lock

    a2.post-lock

    B.关于解锁的2种

    b1.pre-unlock

    b2.post-unlock

    C.关于提交的3种

    c1.start-commit

    c2.pre-commit

    c3.post-commit

    D.关于属性的2种

    d1.pre-revprop-change

    d2.post-revprop-change

    客户端钩子:

    tortoise svn客户端有6中钩子,分别是:

    A.关于提交的

    a1.start commit hook

    a2.pre-commit hook

    a3.post-commit hook

    B.关于更新的

    b1.start update hook

    b2.pre-update hook

    b3.post-update hook

    编写hooks可以使用多种语言和脚本,我对vb比较熟悉,所以选择VBscript,即简单又功能强大。

    对于上一次说到的多个客户端和服务器钩子,不熟悉的可能已经晕了,在这篇里面我们先关注几个问题:

    1.对于客户端hooks来说,关于commit的(其实关于update的一样)三个钩子时序是如何的?

    2.对于客户端hooks,如何让他运行VBSctript脚本。

    现在开始回答问题:

    对于pre-commit和post-commit的时序来说还是比较明显的。但是start-commit发生在什么时间?它和pre-commit的发生关系到底如何?这几个问题可能很困惑。我们不妨添加一些脚本来让tortoisesvn自己来告诉我们。

    1.我在D盘新建了三个脚本文件,分别是:

    start-commit-hook.vbs

    pre-commit-hook.vbs

    post-commit-hook.vbs

    其中的内容为如下所示,其主要目的是在D盘生成三个以事件时间为名称的文件夹,三个脚本中唯一的不同是红色标志出的内容,主要区别事件:

    dim fs,s,t

    set fs=wscript.createobject("scripting.filesystemobject")
    t="StartCommit "+cstr(hour(time))+"-"+cstr(minute(time))+"-"+cstr(second(time))
    set s=fs.createfolder("d:/"+t)

    set fs=nothing

    2.鼠标右键--->TortoiseSVN--->设置,打开的对话框中选择Hook脚本,设置如下:

    特别提醒:对于vbs脚本,调用命令中必须使用wsctript,否则脚本无法运行。

    3.依次设定pre-commit和post-commit脚本

    4.执行一次提交,结果如下


    发现先执行start-commit,然后是pre-commit,最后是post-commit

    另外如果感兴趣可以再进行深入一步的分析,你可以发现:

    start-commit是在通过菜单触发“提交”活动后,弹出“提交”对话框前执行;

    pre-commit是在点击“提交”对话框上的“确定”时执行,即真正的提交活动时执行;

    post-commit是在提交活动结束时执行。

    在第一篇中提到过,服务器钩子有9种,客户端钩子有6中,但是细心的人会发现其中服务器和客户端都有关于commit的钩子,那就会引出几个问题:

    1.他们一样吗?

    2.他们之间有什么关系?

    3.客户端和服务器端触发序列如何?

    为了回答清楚这些问题,必须先看看服务器端的钩子如何运作的,然后再想办法进行研究。

    服务器端的钩子需要运行的话,需要将原有的×.tmpl改成对应的.bat或者.exe或者其他可执行文件,这个时候svn会识别出可运行的钩子,自动运行。

    每个tmpl文件其实都是一个文本文件,使用记事本或者notepad++等打开后,可以看到里面的注释和详细的说明,这些是我们可以使用的第一手的帮助文件,当然网上也有大量关于hook的说明和用法,大家可以认真研究。

    在这里只是为了研究时序,所以我对于大部分的内容先忽略,只是简单的使用来进行信息沟通。

    1.在hooks目录下,新建三个文本文件,改名为:

    start-commit.bat

    pre-commit.bat

    post-commit.bat

    2.分别在这三个文件中输入:

    echo "Start-Commit!" 1>&2
    exit 1

    每个文件中只有红色字体不同,

    使用echo将提示信息返回给客户端,在Windows平台下,必须使用“1>&2”作为结尾,

    exit 0表示结果正确,exit 1或者其他非零数值,表示结果错误,svn只将错误结果返回给客户端

    3.保存

    4.按照start,pre和post的顺序依次将exit 1改为exit 0进行提交实验,可以发现服务器和客户端的信息交互大概顺序为如下图片所示

    1.他们一样吗?

    很显然,客户端和服务端的这些钩子不一样,只是名称一样而已。 

    2.他们之间有什么关系?

    他们之间没有特别大的关系,但是依靠消息的传递互相协作工作。 

    3.客户端和服务器端触发序列如何?

    如下图。

    说句实话,对于服务器svn钩子,Windows平台下选择vbs并不是最佳解决方案,但是我对vbs的熟悉程度远大于其他脚本语言,如python,perl等,所以选择并不多:要么是vbs,要么是bat,bat实现钩子的例子网上有很多,但是对于vbs实现的,却很少,决定使用vbs试试看。

    对于vbs有几个问题,需要特别注意:

    1.对于svn 钩子而言,最好的钩子程序是.bat、.exe、.cmd这样的可执行程序。

    2.Windows平台上,由于vbs本身就是解释性语言,由于Windows版本和vbs版本问题,存在一些调用问题,比如Windows xp和vista调用就可能存在不一致的问题。我办公使用的是xp,其解释器的路径为:C:/WINDOWS/system32/cscript.exe.

    但事情都是辩证的,vbs存在很多问题,但是他简单方便,而且基本上Windows标配有其解释器,不需要其他的编译器和解释器。但是它只能在Windows平台上运行,运行平台比较单一。

    python和perl流行,但是需要附加的编译器等以及另外的学习成本,但是其具有跨平台的特性。

    3.对于vbs,无法在hooks目录中直接同名调用,而需要借助同名的.bat进行调用。

     

    举例:

    如果pre-lock hook,需要在hooks目录中建立pre-lock.bat文件,其内容类似于:


    cscript.exe d:/pre-lock.vbs %1 %2 %3 %4 %5

    其中:

    cscript.exe 为解释器名称,最好是全路径,不行的话,也可以增加其路径到环境变量中;

    d:/pre-lock.vbs 为vbs脚本文件所在路径

     %1 %2 %3 %4 %5 为传入的参数,具体的脚本对应的不同参数和含义,后面的文章会介绍到。

     

    对应的pre-lock.vbs中需要强调的是对于传入参数的处理,其内容类似于如下:

    Set   Args   =   WScript.Arguments  
      For   I   =   0   to   Args.Count   -   1  
            t=t+Args(I) 
      Next

    利用VBS实现pre-commit对提交注释的检查(样例实现的是对长度的检查)。

    1.钩子调用脚本内容

        cscript.exe d:/pre-commit.vbs %1 %2

    2.钩子处理脚本内容


    '*******************************************************************************
    '* NAME       : pre-lock.vbs
    '* AUTHOR     : 杨瑞(OscarYang)
    '* CREATED    : 2010-3-19
    '*
    '* PURPOSE    : 实现提交日志检查
    '*
    '*
    '*              pre-commit hook arguments:
    '*              [1] REPOS-PATH   (the path to this repository)
    '*              [2] TXN-NAME     (the name of the txn about to be committed)
    '*******************************************************************************

    '必须显式声明变量
    Option Explicit

    Private Args
    Public wshShell,logExec

    Set wshShell = WScript.CreateObject("WScript.Shell")
    Set Args = WScript.Arguments

    Dim MaxArgs
    MaxArgs = 2

    '调用主要处理流程
    Call Main

    '*******************************************************************************
    'Main()过程定义
    '*******************************************************************************
    Private Sub Main()

      Call ArgsErr
     
      Call CheckLog

    End Sub 'Main()


    '*******************************************************************************
    '出错退出函数,统一进行资源释放
    '*******************************************************************************
    private sub ErrExit()
     
      Set Args = Nothing
      Set wshShell = Nothing
      Set logExec =Nothing
     
      '错误返回
      WScript.Quit (1)

    end sub 'ErrExit()


    '*******************************************************************************
    '参数出错处理
    '*******************************************************************************
    Private Sub ArgsErr()

        If (Args.Count < MaxArgs) Then

            '在系统信息中记录此错误信息(事件查看器)
            wshShell.LogEvent 1, "缺少参数个数!"
       
            '错误信息输出到客户端
            WScript.StdErr.WriteLine ("缺少参数个数!")

            '错误返回
            Call ErrExit()
        End If

    End Sub 'ArgsErr()

    '*******************************************************************************
    '日志检查
    '*******************************************************************************
    Private Sub CheckLog()

      Dim sReposPath, sRevision, sCommand, sLog
     
      sReposPath = cstr(Args(0))
      sRevision = cstr(Args(1))
     
      '合成svnlook 命令
      sCommand = "svnlook log " + sReposPath + " -t " + sRevision
     
      Set logExec = wshShell.Exec(sCommand)
     
      '读取svnlook log命令返回结果
      Do While Not logExec.StdOut.AtEndOfStream
         sLog = logExec.StdOut.ReadAll()
      loop
     
      if len(sLog)<=10 then
         WScript.StdErr.WriteLine ("日志信息不足!")
         Call ErrExit()
      end if
    End Sub

  • 相关阅读:
    redis_03 _ 高性能IO模型:为什么单线程Redis能那么快
    redis_02 _ 数据结构:快速的Redis有哪些慢操作?
    redis-01 _ 基本架构:一个键值数据库包含什么?
    mysql_28 _ 读写分离有哪些坑
    mysql_27 _ 主库出问题了,从库怎么办
    小程序的转发功能
    简单几何(求交点) UVA 11178 Morley's Theorem
    测试开发CICD——Docker——windows8上环境安装
    测试开发进阶——spring boot——MVC——MyBatis初步了解(转载)
    BZOJ 2226 [Spoj 5971] LCMSum
  • 原文地址:https://www.cnblogs.com/aaa6818162/p/2612606.html
Copyright © 2011-2022 走看看