c++实现svn提交日志校验

来源:互联网 发布:mvn怎么编译java项目 编辑:程序博客网 时间:2024/06/06 06:57

关于svn日志提交的简介请参考 点击打开链接


下面直接上代码,如下:


#define _CRT_SECURE_NO_WARNINGS#include <iostream>#include <stdlib.h>#include <stdio.h>#include <string>#include <vector>#include <windows.h>#define BUFF_SIZE 2048const char* commitfmtlogs = "\请按照如下格式填写提交修改记录信息:\n\【修改内容】\n\此处说明你的修改内容,不少于20个字。\n\【修改原因】\n\此处说明你为什么要做出这样的修改,不少于20个字。\n\【影响范围】\n\此处说明你的修改会对其它什么地方产生影响,不少于10个字。\n\【TODO列表】\n\此处说明针对这次提交,还有什么事情没有做,如可能想到一些功能缺陷,以后要进行修改。 字数不限,如没有内容请填写 无。\n\【问题列表】\n\fixes #Redmine上的问题编号。(已解决某问题)\n\或\n\refs #Redmine上的问题编号。(关联到某问题)\n";//HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\VisualSVN\VisualSVN Server\InstallDirbool getSvnBinPath(std::string& svnBinPath){    HKEY hKey = NULL;    LONG retVal = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\VisualSVN\\VisualSVN Server", 0, KEY_ALL_ACCESS, &hKey);    if (ERROR_SUCCESS != retVal)    {        OutputDebugStringA("打开svn注册表失败");        return false;    }    char buff[MAX_PATH] = { 0 };    DWORD len = MAX_PATH;    DWORD type = REG_SZ;    retVal = RegQueryValueExA(hKey, "InstallDir", NULL, &type, (unsigned char*)buff, &len);    if (ERROR_SUCCESS != retVal)    {        OutputDebugStringA("读取svn注册表项InstallDir失败");        return false;    }    svnBinPath = buff;    svnBinPath += "bin\\";    return true;}/*** @brief 通过svnlook获取提交的日志信息。* 函数功能详述:* @param* @return* @noteno* @warning no* @seeno*/void getSvnLog(const char* cmd, std::string& commitLogs){    //创建匿名管道从svnlook进程中获取提交的日志信息    HANDLE hReadPipe = NULL;    HANDLE hWritePipe = NULL;    SECURITY_ATTRIBUTES stSecurity;    stSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);    stSecurity.lpSecurityDescriptor = NULL;    stSecurity.bInheritHandle = TRUE;//继承性    CreatePipe(&hReadPipe, &hWritePipe, &stSecurity, 0);    STARTUPINFOA siStartInfo;    GetStartupInfo(&siStartInfo);    siStartInfo.hStdInput = hReadPipe;    siStartInfo.hStdOutput = hWritePipe;    siStartInfo.hStdError = hWritePipe;    siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;    siStartInfo.wShowWindow = SW_HIDE;    PROCESS_INFORMATION procInfo;    if (CreateProcessA(NULL, (char*)cmd, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &siStartInfo, &procInfo))    {        char buff[BUFF_SIZE + 1] = { 0 };        DWORD bytes_read = BUFF_SIZE;        while (true)        {            PeekNamedPipe(hReadPipe, buff, BUFF_SIZE, &bytes_read, NULL, NULL);            if (0 != bytes_read)            {                ReadFile(hReadPipe, buff, bytes_read, &bytes_read, NULL);                OutputDebugStringA(buff);                break;            }        }        commitLogs = buff;    }}/*** @brief 按照指定规则进行格式化字符串。* 函数功能详述:* @param* @return* @noteno* @warning no* @seeno*/bool splitString(const std::string& src,                 std::vector<std::string>& fields,                 const std::string& pattern){    int size = src.size();    int pos = 0;    int i = 0;    for (; i < size; ++i)    {        pos = src.find(pattern, i);        if (std::string::npos == pos)        {            break;        }        fields.push_back(src.substr(i, pos - i));        i = pos + pattern.size() - 1;    }    //判断最后是否是以pattern结尾    if (i != size)    {        fields.push_back(src.substr(i, size - i));    }    return true;}/** * @brief 判断问题号是否为数字。 * 函数功能详述: * @param  * @return  * @noteno * @warning no * @seeno */bool isDigit(std::string issue){    int len = issue.size();    for (int i = 0; i < len; ++i)    {        if (issue[i] >= '0' && issue[i] <= '9')        {            return true;        }    }    return false;}/*** @brief 检查日志规则。* 函数功能详述:* @param* @return* @noteno* @warning no* @seeno*/bool checkSvnLog(const std::string& commitLogs){    std::string subLogs;    std::vector<std::string> fields;    splitString(commitLogs, fields, "\r\n");    int flag = 10;  //至少需要10行内容,才能匹配规则    int cnts = fields.size();    if (cnts < flag)    {        OutputDebugStringA("cnts < flag");        return false;    }    //第一项 修改内容检查    if (std::string::npos == fields[0].find("修改内容"))    {        OutputDebugStringA("缺少【修改内容】");        return false;    }    if (fields[1].size() < 20)    {        OutputDebugStringA("【修改内容】字数不够");        return false;    }    //第二项 修改原因检查    if (std::string::npos == fields[2].find("修改原因"))    {        OutputDebugStringA("缺少【修改原因】");        return false;    }    if (fields[3].size() < 20)    {        OutputDebugStringA("【修改原因】字数不够");        return false;    }    //第三项 影响范围检查    if (std::string::npos == fields[4].find("影响范围"))    {        OutputDebugStringA("缺少【影响范围】");        return false;    }    if (fields[5].size() < 10)    {        OutputDebugStringA("【影响范围】字数不够");        return false;    }    /*if (fields[1] == fields[3] ||        fields[2] == fields[3] ||        fields[1] == fields[2])        {        OutputDebugStringA("【修改内容】【修改原因】【影响范围】三处内容不能一样");        return false;        }*/    //第四项 TODO列表检查    if (std::string::npos == fields[6].find("TODO列表"))    {        OutputDebugStringA("缺少【TODO列表】");        return false;    }        //第五项 问题列表检查    if (std::string::npos == fields[8].find("问题列表"))    {        OutputDebugStringA("缺少【问题列表】");        return false;    }    if (std::string::npos == fields[9].find("fixes #") &&        std::string::npos == fields[9].find("refs #"))    {        OutputDebugStringA("【问题列表】内容不对");        return false;    }    std::string issueId = fields[9].substr(fields[9].find("#"));        if (!isDigit(issueId))    {        OutputDebugStringA("问题号为非数字");        return false;    }    return true;}int main(int argc, char** argv){    if (argc < 3)    {        return 0;    }    std::string svnlookpath = "";    getSvnBinPath(svnlookpath);    std::string cmd = "\"" + svnlookpath + "svnlook.exe\" log \"" + argv[1] + "\" -t " + argv[2];    std::string commitLogs = "";    getSvnLog(cmd.c_str(), commitLogs);    if (!checkSvnLog(commitLogs))    {        std::cerr << commitfmtlogs;        return 1;    }    return 0;}


0 0
原创粉丝点击