zoukankan      html  css  js  c++  java
  • 转:Windows下WSH/JS实现SVN服务器钩子脚本阻止提交空日志信息和垃圾文件

    http://blog.csdn.net/caikanxp/article/details/8279921

    如何强制用户在提交SVN时填写日志信息?

    如果用户使用的都是TortoiseSVN客户端,可以给文件夹加上“tsvn:logminsize”属性。当用户使用TSVN提交此文件夹内的改动时,若日志信息长度不够,提交确定按钮会保持灰色不可用。不过此法对于非TSVN客户端便无效了。

     

    作为更严格的限制,可以在Subversion服务器端强制必须填写日志信息,这时需用到pre-commit钩子脚本。

    代码如下:

    文件:pre-commit.bat

    [plain] view plaincopy
    1. svnlook log %1 -t %2 | CScript "%~dp0pre-commit.js"  
    2. EXIT %ERRORLEVEL%  

    文件:pre-commit.js

    [javascript] view plaincopy
    1. var log = WScript.StdIn.ReadAll();  
    2. log = log.replace(/^s+|s+$/g, '');  
    3. if (log.length < 1) {  
    4.     WScript.StdErr.WriteLine('【由于版本库管理员的设定,您必须输入非空的日志信息,用以描述本次提交的内容。】');  
    5.     WScript.Quit(1);  
    6. }  

    脚本说明:

    以上脚本文件都应该使用ANSI编码,将它们保存于版本库存放处的hooks文件夹中即可。

    Subversion在提交事务完成之前,会执行钩子脚本“pre-commit”,并根据其返回结果来决定是否提交事务。

    在Windows平台中,钩子脚本应该是一个Windows可执行程序,如“pre-commit.exe”或“pre-commit.bat”。

    当然可以通过某些程序语言编译生成一个程序,但实施起来过于复杂,实属小题大做。

    而批处理由于本身的不足,不借助其它工具来判断非空日志也不那么简单。

    网上有些例子就是使用批处理结合第三方程序来处理的,但前提是需要额外安装第三方程序。

    不过在Windows下其实有更“绿色”的做法:使用WSH(Windows脚本宿主)脚本——Windows时代更强大的“批处理”,可以支持JS,VBS等脚本语言。

    虽然Windows中可以通过配置PATHEXT环境变量,将某些扩展名当做“可执行文件”的扩展名,直接敲入主文件名即可执行——比如需要执行WSH脚本“pre-commit.js”,在命令提示符下直接敲入“pre-commit”即可;但很遗憾,测试发现Subversion在需要触发pre-commit钩子脚本时,并不会直接触发“pre-commit.js”。

    但我们仍然可以通过批处理脚本pre-commit.bat或pre-commit.cmd来间接调用WSH脚本。

    批处理的参数:%0代表批处理脚本命令自身(的文件名),%1,%2,%3……依次代表批处理的参数。

    批处理参数的扩展:“%~dp0”用来获取批处理脚本所在的文件夹绝对路径。可以在命令提示符中输入“CALL /?”了解相关语法详情。

    传入pre-commit钩子脚本的参数:第1为版本库位置,第2为提交事务的id。

    CScript脚本宿主支持标准输入输出及错误流,而WScript脚本宿主则不支持。Windows的默认脚本宿主为WScript,因此必须明确调用CScript。

    (当默认宿主被改为CScript时,这种写法也是可行的“svnlook log %1 -t %2 | "%~dp0pre-commit.js"”)。

    被调用的WSH脚本名需要重新围上双引号(%~批处理参数扩展会移除原始参数包围的双引号),以确保版本库路径中包含空格时不会出错。

    钩子脚本执行流程:
    批处理脚本执行svnlook命令输出日志信息,通过管道将日志流输出到WSH脚本;
    WSH脚本读取流之后,判断日志内容是否为只含空白的字符串;
    WSH脚本执行完成后,退出码会被写入ERRORLEVEL环境变量,最后批处理脚本也使用此错误码退出。
    若钩子脚本的退出码非0,提交事务便会被阻止,同时脚本输出到标准错误流的消息将被传送给SVN客户端进行提示。

     

    上面的做法使用了管道流。下面是另一种做法,直接将批处理收到的钩子脚本参数转给WSH脚本。

    本例不仅阻止了仅含空白字符的日志消息,同时也阻止了一些常见垃圾文件的提交。

    文件:pre-commit.bat

    [plain] view plaincopy
    1. CScript "%~dp0pre-commit.js" %1 %2  
    2. EXIT %ERRORLEVEL%  

    文件:pre-commit.js

    [javascript] view plaincopy
    1. var WshShell = new ActiveXObject("WScript.Shell");  
    2. var args = WScript.Arguments;  
    3. var error = 0;  
    4.   
    5. // 用于将命令模版中的参数替换为WSH脚本参数,并包上用于兼容含空格路径的双引号  
    6. function replaceArgs($0, $1) {  
    7.     return '"'+ args($1) + '"';  
    8. }  
    9.   
    10. // 检测日志信息  
    11. function checkLog() {  
    12.     var cmd = 'svnlook log %0 -t %1';  
    13.     cmd = cmd.replace(/%(d)/g, replaceArgs);  
    14.     var log = WshShell.Exec(cmd).StdOut.ReadAll();  
    15.     log = log.replace(/^s+|s+$/g, '');  
    16.     if (log.length < 1) {  
    17.         WScript.StdErr.WriteLine('【由于版本库管理员的设定,您必须输入非空的日志信息,用以描述本次提交的内容。】');  
    18.         return 1;  
    19.     }  
    20.     return 0;  
    21. }  
    22.   
    23. // 检测垃圾文件  
    24. function fileFilter() {  
    25.     var cmd = 'svnlook changed %0 -t %1';  
    26.     cmd = cmd.replace(/%(d)/g, replaceArgs);  
    27.     var oExec = WshShell.Exec(cmd);  
    28.     var stdout = oExec.StdOut;  
    29.     // svnlook changed 命令的输出格式可参考SVN手册。每行表示一个文件变动,行首字母A表示版本差异中新增的文件。  
    30.     // 此正则表达式可匹配新增文件中的“Thumbs.db”“desktop.ini”及部分Office临时文件  
    31.     var r = /^A.ss((?:[^/]+/)*(?:Thumbs.db|desktop.ini|~$.*.(?:docx?|xlsx?|pptx?)))$/i;  
    32.     var illegals = [];  
    33.     var m;  
    34.     while (!stdout.AtEndOfStream) {  
    35.         var line = stdout.ReadLine();  
    36.         if (m = line.match(r)) {  
    37.             illegals[illegals.length] = m[1];  
    38.         }  
    39.     }  
    40.     if (illegals.length) {  
    41.         WScript.StdErr.WriteLine('【下列文件被判定为垃圾文件而禁止提交,请排除后重新提交。】');  
    42.         WScript.StdErr.WriteLine('【如判定有误或有其它问题,请联系版本库管理员。】');  
    43.         WScript.StdErr.WriteLine(illegals.join(' '));  
    44.         return 1;  
    45.     }  
    46.     return 0;  
    47. }  
    48.   
    49. error += checkLog();  
    50. error += fileFilter();  
    51. WScript.Quit(error);  

     

    WSH的强大已足以应付这些问题。

    而pre-commit钩子脚本的不足之处就是,需要等全部改动传输至服务器之后才会被调用。

    当改动内容很多时,数据传输了半天,突然来了个提交被阻止岂不是很郁闷。

    可以考虑将服务器端钩子脚本作为最终关卡,平时还是尽量优先以客户端的配置来进行操作过滤。

     

     

    以上测试环境:Windows XP/2003,WSH 5.7,TortoiseSVN-1.7.10(Subversion 1.7.7)

  • 相关阅读:
    OC基础框架
    协议代理
    内存管理
    重写init或自定义init方法
    iOS输入框UITextField输入限制
    iOS 打包FrameWork
    iOS 持续往文件写入数据。
    ld: library not found for -lxxx 问题的解决办法
    iOS 侧滑返回过程中导航栏的黑色问题解决办法
    iOS 蓝牙分包发送数据
  • 原文地址:https://www.cnblogs.com/youngt/p/3277547.html
Copyright © 2011-2022 走看看