diff --git a/GitVer/GitVer.cpp b/GitVer/GitVer.cpp index d096cd3..de96d68 100644 --- a/GitVer/GitVer.cpp +++ b/GitVer/GitVer.cpp @@ -353,11 +353,11 @@ void PrintFullUsageExamples() LPCTSTR lpUsageText = _T("用法:\n") _T(" gitver (显示帮助后进入当前分支创建 tag 流程)\n") - _T(" gitver rewrite [PEType可选]\n") - _T(" gitver setver= [repoPath可选] [-f可选] [-test可选]\n") - _T(" gitver nuitkabuild [pid] [mainPy] [repoPath可选] [-test可选] [nuitka额外参数可选]\n") - _T(" gitver nuitkapydbuild [pid] [modulePy] [repoPath可选] [-test可选] [nuitka额外参数可选]\n") - _T(" gitver -setup=0|1 [pid] [repoPath可选] [-f可选] [-test可选]\n") + _T(" gitver rewrite [PEType可选] [-f可选]\n") + _T(" gitver setver= [repodir=可选] [-test可选]\n") + _T(" gitver nuitkabuild= [repodir=可选] [-test可选] [params=\"\"可选]\n") + _T(" gitver nuitkapydbuild= [repodir=可选] [-test可选] [params=\"\"可选]\n") + _T(" gitver -setup=0|1 [pid] [repodir=可选] [-test可选]\n") _T(" -setup=0: 使用 Inno Setup 脚本 (setup.iss)\n") _T(" -setup=1: 使用 NSIS 脚本 (setup.nsh)\n") _T("\n示例:\n") @@ -365,24 +365,21 @@ void PrintFullUsageExamples() _T(" gitver rewrite\n") _T(" gitver rewrite 2\n") _T(" gitver rewrite -f\n") - _T(" gitver setver=5 E:\\Code\\OTH\\gitver\n") + _T(" gitver setver=5 repodir=E:\\Code\\OTH\\gitver\n") _T(" gitver setver=5\n") - _T(" gitver setver=5 -f\n") _T(" gitver setver=5 -test\n") - _T(" gitver nuitkabuild 5 main.py\n") - _T(" gitver nuitkabuild 5 main.py -f\n") - _T(" gitver nuitkabuild 5 main.py -test\n") - _T(" gitver nuitkabuild 5 src\\app.py E:\\Code\\MyPyProj --standalone --output-dir=dist\n") - _T(" gitver nuitkabuild 5 main.py --standalone -f\n") - _T(" gitver nuitkapydbuild 5 module.py\n") - _T(" gitver nuitkapydbuild 5 module.py -f\n") - _T(" gitver nuitkapydbuild 5 module.py -test\n") - _T(" gitver nuitkapydbuild 5 src\\core.py E:\\Code\\MyPyProj --output-dir=dist\n") + _T(" gitver nuitkabuild=5 main.py\n") + _T(" gitver nuitkabuild=5 main.py -test\n") + _T(" gitver nuitkabuild=5 src\\app.py repodir=E:\\Code\\MyPyProj params=\"--standalone --output-dir=dist\"\n") + _T(" gitver nuitkapydbuild=5 module.py\n") + _T(" gitver nuitkapydbuild=5 module.py -test\n") + _T(" gitver nuitkapydbuild=5 src\\core.py repodir=E:\\Code\\MyPyProj params=\"--output-dir=dist\"\n") _T(" gitver -setup=0 5\n") - _T(" gitver -setup=1 5 E:\\Code\\MyProj\n") - _T("\n说明: nuitkabuild/nuitkapydbuild 中,-f/-test 在额外参数开始前表示 gitver 选项;进入额外参数后会透传给 Nuitka。\n") + _T(" gitver -setup=1 5 repodir=E:\\Code\\MyProj\n") + _T("params: 传递给 Nuitka 的额外参数,用双引号括起来,如 params=\"--standalone --output-dir=dist\"。\n") _T("-test: 将产品版本号的 major 和 minor 都置为 0(用于测试版本构建)。\n") - _T("无参数时会读取当前分支最近三次 tag,并提示选择 major 加 1 或 minor 加 1,然后创建新 tag。\n"); + _T("无参数时会读取当前分支最近三次 tag,并提示选择 major 加 1 或 minor 加 1,然后创建新 tag。\n") + _T("未找到当前分支 tag 时自动使用默认版本 1.0。\n"); _tprintf(_T("%s"), lpUsageText); } @@ -393,9 +390,9 @@ void PrintFullUsageExamples() void PrintShortCommandUsage() { _tprintf(_T("请使用:gitver rewrite [PE类型可选]\n")); - _tprintf(_T("请使用:gitver setver= [repoPath可选]\n")); - _tprintf(_T("或:gitver nuitkabuild [pid] [mainPy] [repoPath可选] [nuitka额外参数可选]\n")); - _tprintf(_T("或:gitver nuitkapydbuild [pid] [modulePy] [repoPath可选] [nuitka额外参数可选]\n")); + _tprintf(_T("请使用:gitver setver= [repodir=可选]\n")); + _tprintf(_T("或:gitver nuitkabuild= [repodir=可选] [params=\"\"可选]\n")); + _tprintf(_T("或:gitver nuitkapydbuild= [repodir=可选] [params=\"\"可选]\n")); } /// @@ -406,15 +403,15 @@ void PrintShortCommandUsage() /// 示例中的必选参数。 void PrintCommandUsageAndExamples(LPCTSTR lpCommandName, LPCTSTR lpRequiredArgs, LPCTSTR lpExampleRequiredArgs) { - _tprintf(_T("用法:gitver %s %s [repoPath可选]\n"), lpCommandName, lpRequiredArgs); + _tprintf(_T("用法:gitver %s %s [repodir=可选]\n"), lpCommandName, lpRequiredArgs); if (lpExampleRequiredArgs != NULL && _tcslen(lpExampleRequiredArgs) > 0) { - _tprintf(_T("示例:gitver %s 5 %s E:\\Code\\OTH\\gitver\n"), lpCommandName, lpExampleRequiredArgs); + _tprintf(_T("示例:gitver %s 5 %s repodir=E:\\Code\\OTH\\gitver\n"), lpCommandName, lpExampleRequiredArgs); _tprintf(_T("示例:gitver %s 5 %s\n"), lpCommandName, lpExampleRequiredArgs); } else { - _tprintf(_T("示例:gitver %s 5 E:\\Code\\OTH\\gitver\n"), lpCommandName); + _tprintf(_T("示例:gitver %s 5 repodir=E:\\Code\\OTH\\gitver\n"), lpCommandName); _tprintf(_T("示例:gitver %s 5\n"), lpCommandName); } } @@ -583,9 +580,8 @@ int HandleSetVerCommand(int argc, TCHAR* argv[]) } LPCTSTR lpRepoPath = NULL; - BOOL bUseDefaultTagWhenMissing = FALSE; BOOL bTestMode = FALSE; - int nRepoArgRet = ParseSetVerOptions(argc, argv, 2, lpRepoPath, bUseDefaultTagWhenMissing, bTestMode); + int nRepoArgRet = ParseSetVerOptions(argc, argv, 2, lpRepoPath, bTestMode); if (nRepoArgRet != 0) { return nRepoArgRet; @@ -600,7 +596,6 @@ int HandleSetVerCommand(int argc, TCHAR* argv[]) errorCodes, strProductVersion, strFileVersion, - bUseDefaultTagWhenMissing, DEFAULT_MAJOR_WHEN_NO_TAG, DEFAULT_MINOR_WHEN_NO_TAG); if (nVersionRet != 0) @@ -873,7 +868,7 @@ int main(int argc, TCHAR* argv[], TCHAR* envp[]) return nCmdRet; } - if (argc >= 2 && _tcsicmp(argv[1], _T("nuitkabuild")) == 0) + if (argc >= 2 && _tcsnicmp(argv[1], _T("nuitkabuild="), 12) == 0) { DWORD dwStartTick = LogCommandStart(_T("nuitkabuild")); int nCmdRet = HandleNuitkaBuildCommand(argc, argv); @@ -882,7 +877,7 @@ int main(int argc, TCHAR* argv[], TCHAR* envp[]) return nCmdRet; } - if (argc >= 2 && _tcsicmp(argv[1], _T("nuitkapydbuild")) == 0) + if (argc >= 2 && _tcsnicmp(argv[1], _T("nuitkapydbuild="), 15) == 0) { DWORD dwStartTick = LogCommandStart(_T("nuitkapydbuild")); int nCmdRet = HandleNuitkaPydBuildCommand(argc, argv); diff --git a/GitVer/GitVer_cli.cpp b/GitVer/GitVer_cli.cpp index d07bbf1..c5566b8 100644 --- a/GitVer/GitVer_cli.cpp +++ b/GitVer/GitVer_cli.cpp @@ -10,21 +10,14 @@ void PrintInvalidRepoPathError(LPCTSTR lpRepoPath) _tprintf(_T(": ЧIJֿ· %s\n"), lpRepoPath == NULL ? _T("") : lpRepoPath); } -int ParseSetVerOptions(int argc, TCHAR* argv[], int nStartIndex, LPCTSTR& lpRepoPath, BOOL& bUseDefaultTagWhenMissing, BOOL& bTestMode) +int ParseSetVerOptions(int argc, TCHAR* argv[], int nStartIndex, LPCTSTR& lpRepoPath, BOOL& bTestMode) { lpRepoPath = NULL; - bUseDefaultTagWhenMissing = FALSE; bTestMode = FALSE; for (int i = nStartIndex; i < argc; ++i) { CString strArg = argv[i]; - if (strArg.CompareNoCase(_T("-f")) == 0) - { - bUseDefaultTagWhenMissing = TRUE; - continue; - } - if (strArg.CompareNoCase(_T("-test")) == 0) { bTestMode = TRUE; @@ -37,14 +30,20 @@ int ParseSetVerOptions(int argc, TCHAR* argv[], int nStartIndex, LPCTSTR& lpRepo continue; } - if (lpRepoPath == NULL) + if (strArg.GetLength() > 8 && strArg.Left(8).CompareNoCase(_T("repodir=")) == 0) { - if (!PathIsDirectory(argv[i])) + if (lpRepoPath != NULL) { - PrintInvalidRepoPathError(argv[i]); + _tprintf(_T(": repodir ظ: %s\n"), argv[i]); return 23; } - lpRepoPath = argv[i]; + LPCTSTR lpPath = argv[i] + 8; + if (!PathIsDirectory(lpPath)) + { + PrintInvalidRepoPathError(lpPath); + return 23; + } + lpRepoPath = lpPath; continue; } diff --git a/GitVer/GitVer_cli.h b/GitVer/GitVer_cli.h index efbbcf7..88f7ddd 100644 --- a/GitVer/GitVer_cli.h +++ b/GitVer/GitVer_cli.h @@ -1,5 +1,5 @@ #pragma once void PrintInvalidRepoPathError(LPCTSTR lpRepoPath); -int ParseSetVerOptions(int argc, TCHAR* argv[], int nStartIndex, LPCTSTR& lpRepoPath, BOOL& bUseDefaultTagWhenMissing, BOOL& bTestMode); +int ParseSetVerOptions(int argc, TCHAR* argv[], int nStartIndex, LPCTSTR& lpRepoPath, BOOL& bTestMode); int ParseRewriteOptions(int argc, TCHAR* argv[], int& nPEType, BOOL& bForceRewrite); diff --git a/GitVer/GitVer_nuitka.cpp b/GitVer/GitVer_nuitka.cpp index 82ef099..f49f8e5 100644 --- a/GitVer/GitVer_nuitka.cpp +++ b/GitVer/GitVer_nuitka.cpp @@ -13,52 +13,56 @@ void PrintCommandUsageAndExamples(LPCTSTR lpCommand, LPCTSTR lpRequiredArgs, LPC const UINT DEFAULT_MAJOR_WHEN_NO_TAG_FOR_NUITKA = 1; const UINT DEFAULT_MINOR_WHEN_NO_TAG_FOR_NUITKA = 0; -static int ParseNuitkaOptions(int argc, TCHAR* argv[], LPCTSTR& lpRepoPath, BOOL& bUseDefaultTagWhenMissing, CString& strExtraArgs, BOOL& bTestMode) +static int ParseNuitkaOptions(int argc, TCHAR* argv[], LPCTSTR& lpRepoPath, CString& strExtraArgs, BOOL& bTestMode) { lpRepoPath = NULL; - bUseDefaultTagWhenMissing = FALSE; strExtraArgs.Empty(); bTestMode = FALSE; - BOOL bExtraArgsStarted = FALSE; - for (int i = 4; i < argc; ++i) + for (int i = 3; i < argc; ++i) { CString strArg = argv[i]; - BOOL bOptionStyleArg = !strArg.IsEmpty() && strArg.Left(1) == _T("-"); - // ڶδʼʱ -f Ϊ gitver ѡ - // һ׶Σ-f Ӧ͸ Nuitka - if (!bExtraArgsStarted && strArg.CompareNoCase(_T("-f")) == 0) - { - bUseDefaultTagWhenMissing = TRUE; - continue; - } - - if (!bExtraArgsStarted && strArg.CompareNoCase(_T("-test")) == 0) + if (strArg.CompareNoCase(_T("-test")) == 0) { bTestMode = TRUE; continue; } - if (!bExtraArgsStarted && lpRepoPath == NULL && !bOptionStyleArg && PathIsDirectory(argv[i])) + if (strArg.GetLength() > 8 && strArg.Left(8).CompareNoCase(_T("repodir=")) == 0) { - lpRepoPath = argv[i]; + if (lpRepoPath != NULL) + { + _tprintf(_T(": repodir ظ: %s\n"), argv[i]); + return 23; + } + LPCTSTR lpPath = argv[i] + 8; + if (!PathIsDirectory(lpPath)) + { + PrintInvalidRepoPathError(lpPath); + return 23; + } + lpRepoPath = lpPath; continue; } - if (!bExtraArgsStarted && lpRepoPath == NULL && !bOptionStyleArg && IsLikelyPathArg(argv[i])) + if (strArg.GetLength() > 7 && strArg.Left(7).CompareNoCase(_T("params=")) == 0) { - PrintInvalidRepoPathError(argv[i]); - return 23; + if (!strExtraArgs.IsEmpty()) + { + _tprintf(_T(": params ظ\n")); + return 3; + } + CString strVal = strArg.Mid(7); + // ȥ˫ţ params="--standalone" + if (strVal.GetLength() >= 2 && strVal[0] == _T('"') && strVal[strVal.GetLength() - 1] == _T('"')) + strVal = strVal.Mid(1, strVal.GetLength() - 2); + strExtraArgs = strVal; + continue; } - bExtraArgsStarted = TRUE; - - if (!strExtraArgs.IsEmpty()) - { - strExtraArgs += _T(" "); - } - strExtraArgs += QuoteCmdArg(argv[i]); + _tprintf(_T(": δ֪IJ %s\n"), argv[i]); + return 3; } if (lpRepoPath == NULL) @@ -87,6 +91,7 @@ static void RunNuitkaBuild(LPCTSTR lpStartMessage, CString& strNuitkaCmd, const static int HandleNuitkaBuildCommandCore( int argc, TCHAR* argv[], + int nCmdPrefixLen, BOOL bBuildModule, LPCTSTR lpStartMessage, LPCTSTR lpUsageName, @@ -97,28 +102,27 @@ static int HandleNuitkaBuildCommandCore( int nTagErrorCode, int nCommitErrorCode) { - if (argc < 4) + // pidǶ argv[1] У "nuitkabuild=5" + CString strPid = CString(argv[1]).Mid(nCmdPrefixLen); + UINT nPid = 0; + if (strPid.IsEmpty() || !TryParseUInt16(strPid, nPid)) { - _tprintf(_T(": 㡣\n")); - CString strRequiredArgs; - strRequiredArgs.Format(_T("[pid] [%s]"), lpEntryArgName); - PrintCommandUsageAndExamples(lpUsageName, strRequiredArgs.GetString(), lpEntryArgName); + _tprintf(_T(": %s= pid Ч%sӦΪ 0-65535 Χ\n"), lpUsageName, strPid.GetString()); + return nPidErrorCode; + } + + if (argc < 3) + { + _tprintf(_T(": 㣬ȱ %s\n"), lpEntryArgName); + _tprintf(_T("÷gitver %s= <%s> [repodir=ѡ] [-testѡ] [params=\"\"\u53efѡ]\n"), lpUsageName, lpEntryArgName); return nArgLackErrorCode; } - UINT nPid = 0; - int nArgRet = ParseUInt16ArgOrError(argv, 2, _T("pid"), nPid, nPidErrorCode); - if (nArgRet != 0) - { - return nArgRet; - } - - CString strMainOrModulePy = argv[3]; + CString strMainOrModulePy = argv[2]; LPCTSTR lpRepoPath = NULL; - BOOL bUseDefaultTagWhenMissing = FALSE; CString strExtraArgs; BOOL bTestMode = FALSE; - int nRepoArgRet = ParseNuitkaOptions(argc, argv, lpRepoPath, bUseDefaultTagWhenMissing, strExtraArgs, bTestMode); + int nRepoArgRet = ParseNuitkaOptions(argc, argv, lpRepoPath, strExtraArgs, bTestMode); if (nRepoArgRet != 0) { return nRepoArgRet; @@ -133,7 +137,6 @@ static int HandleNuitkaBuildCommandCore( errorCodes, strProductVersion, strFileVersion, - bUseDefaultTagWhenMissing, DEFAULT_MAJOR_WHEN_NO_TAG_FOR_NUITKA, DEFAULT_MINOR_WHEN_NO_TAG_FOR_NUITKA); if (nVersionRet != 0) @@ -181,6 +184,7 @@ int HandleNuitkaBuildCommand(int argc, TCHAR* argv[]) return HandleNuitkaBuildCommandCore( argc, argv, + 12, FALSE, _T("Nuitka ʼ.."), _T("nuitkabuild"), @@ -197,6 +201,7 @@ int HandleNuitkaPydBuildCommand(int argc, TCHAR* argv[]) return HandleNuitkaBuildCommandCore( argc, argv, + 15, TRUE, _T("Nuitka pyd ʼ.."), _T("nuitkapydbuild"), diff --git a/GitVer/GitVer_setup.cpp b/GitVer/GitVer_setup.cpp index 443cc26..db689da 100644 --- a/GitVer/GitVer_setup.cpp +++ b/GitVer/GitVer_setup.cpp @@ -14,7 +14,7 @@ BOOL ReadTextFileAsAnsi(LPCTSTR lpFile, std::string& strContent, std::string& st BOOL WriteTextFileAsAnsi(LPCTSTR lpFile, const std::string& strContent, const std::string& strBomPrefix); void PrintInvalidRepoPathError(LPCTSTR lpRepoPath); -int ParseSetVerOptions(int argc, TCHAR* argv[], LPCTSTR& lpRepoPath, BOOL& bUseDefaultTagWhenMissing, BOOL& bTestMode); +int ParseSetVerOptions(int argc, TCHAR* argv[], int nStartIndex, LPCTSTR& lpRepoPath, BOOL& bTestMode); static const UINT DEFAULT_MAJOR_WHEN_NO_TAG_FOR_SETUP = 1; static const UINT DEFAULT_MINOR_WHEN_NO_TAG_FOR_SETUP = 0; @@ -334,9 +334,9 @@ int HandleSetupCommand(int argc, TCHAR* argv[]) if (argc < 3) { _tprintf(_T("错误: 参数不足。\n")); - _tprintf(_T("用法:gitver -setup=0|1 [pid] [repoPath可选]\n")); + _tprintf(_T("用法:gitver -setup=0|1 [pid] [repodir=可选]\n")); _tprintf(_T("示例:gitver -setup=0 5\n")); - _tprintf(_T("示例:gitver -setup=1 5 E:\\Code\\MyProj\n")); + _tprintf(_T("示例:gitver -setup=1 5 repodir=E:\\Code\\MyProj\n")); return 3; } @@ -348,9 +348,8 @@ int HandleSetupCommand(int argc, TCHAR* argv[]) } LPCTSTR lpRepoPath = NULL; - BOOL bUseDefaultTagWhenMissing = FALSE; BOOL bTestMode = FALSE; - int nRepoArgRet = ParseSetVerOptions(argc, argv, 3, lpRepoPath, bUseDefaultTagWhenMissing, bTestMode); + int nRepoArgRet = ParseSetVerOptions(argc, argv, 3, lpRepoPath, bTestMode); if (nRepoArgRet != 0) { return nRepoArgRet; @@ -365,7 +364,6 @@ int HandleSetupCommand(int argc, TCHAR* argv[]) errorCodes, strProductVersion, strFileVersion, - bUseDefaultTagWhenMissing, DEFAULT_MAJOR_WHEN_NO_TAG_FOR_SETUP, DEFAULT_MINOR_WHEN_NO_TAG_FOR_SETUP); if (nVersionRet != 0) diff --git a/GitVer/GitVer_version.cpp b/GitVer/GitVer_version.cpp index 8f6bc09..ce235d3 100644 --- a/GitVer/GitVer_version.cpp +++ b/GitVer/GitVer_version.cpp @@ -6,7 +6,7 @@ BOOL TryGetCurrentBranch(LPCTSTR lpRepoPath, CString& strBranch) { - _tprintf(_T("ȡǰ֧ƣ\n")); + _tprintf(_T("��ȡ��ǰ��֧���ƣ�\n")); strBranch = StartProcess(NULL, _T("cmd /c git rev-parse --abbrev-ref HEAD"), lpRepoPath); strBranch.Replace(_T("\r"), _T("")); strBranch.Replace(_T("\n"), _T("")); @@ -92,7 +92,7 @@ BOOL GetLastMajorMinorTag(LPCTSTR lpRepoPath, const CString& strBranch, CString& CString strTagList = StartProcess(NULL, _T("cmd /c git tag --list --sort=v:refname"), lpRepoPath); if (strTagList.IsEmpty()) { - _tprintf(_T(": ȡǩбʧ\n")); + _tprintf(_T("����: ��ȡ��ǩ�б�ʧ��\n")); return FALSE; } @@ -103,7 +103,7 @@ BOOL GetLastMajorMinorTag(LPCTSTR lpRepoPath, const CString& strBranch, CString& strLine.Trim(); if (strLine.Left(6).CompareNoCase(_T("fatal:")) == 0) { - _tprintf(_T(": ȡǩбʧ %s\n"), strLine.GetString()); + _tprintf(_T("����: ��ȡ��ǩ�б�ʧ�� %s\n"), strLine.GetString()); return FALSE; } @@ -125,7 +125,7 @@ BOOL GetLastMajorMinorTag(LPCTSTR lpRepoPath, const CString& strBranch, CString& void GetFileVersionDateFromSystemTime(const SYSTEMTIME& stLocal, UINT& nYY, UINT& nMMDD) { nYY = stLocal.wYear % 100; - // Ϊð汾Ŷ4λ·ݴ1-12ӳ䵽11-22; + // Ϊ���ð汾�Ŷ���4λ���·ݴ�1-12ӳ�䵽11-22; nMMDD = (stLocal.wMonth + 10) * 100 + stLocal.wDay; } @@ -221,32 +221,32 @@ BOOL ResolveFileVersionDateAndCommitCount(LPCTSTR lpRepoPath, const CString& str UINT nTodayCommitCount = 0; if (!TryGetBranchCommitCountByDate(lpRepoPath, strBranch, stTargetDate, nTodayCommitCount)) { - _tprintf(_T(": ȡύʧ\n")); + _tprintf(_T("����: ��ȡ�����ύ����ʧ��\n")); return FALSE; } if (nTodayCommitCount == 0) { - _tprintf(_T("ύΪ0ȡһύ\n")); + _tprintf(_T("�����ύ����Ϊ0������ȡ���һ���ύ����\n")); if (!TryGetLastBranchCommitDate(lpRepoPath, strBranch, stTargetDate)) { - _tprintf(_T(": ȡһύʧ\n")); + _tprintf(_T("����: ��ȡ���һ���ύ����ʧ��\n")); return FALSE; } if (!TryGetBranchCommitCountByDate(lpRepoPath, strBranch, stTargetDate, nTodayCommitCount)) { - _tprintf(_T(": ȡ[%s]ύʧ\n"), strBranch.GetString()); + _tprintf(_T("����: ��ȡ[%s]�ύ����ʧ��\n"), strBranch.GetString()); return FALSE; } - _tprintf(_T("ȡһύ: %04u-%02u-%02u, ύ: %u\n"), + _tprintf(_T("��ȡ�����һ���ύ����: %04u-%02u-%02u, �ύ����: %u\n"), stTargetDate.wYear, stTargetDate.wMonth, stTargetDate.wDay, nTodayCommitCount); } else { - _tprintf(_T("ȡύ: %u\n"), nTodayCommitCount); + _tprintf(_T("��ȡ�������ύ����: %u\n"), nTodayCommitCount); } GetFileVersionDateFromSystemTime(stTargetDate, nYY, nMMDD); @@ -260,14 +260,12 @@ int BuildVersionsFromRepo( const VersionBuildErrorCodes& errorCodes, CString& strProductVersion, CString& strFileVersion, - BOOL bUseDefaultTagWhenMissing, UINT nDefaultMajor, UINT nDefaultMinor) { - _tprintf(_T("ʼ汾: ֿ·=%s pid=%u ĬTag(%s)=%u.%u\n"), + _tprintf(_T("\xBF\xAA\xCA\xBC\xB9\xB9\xBD\xA8\xB0\xE6\xB1\xBE: \xB2\xD6\xBF\xE2\xC2\xB7\xBE\xB6=%s pid=%u default=%u.%u\n"), lpRepoPath == NULL ? _T("") : lpRepoPath, nPid, - bUseDefaultTagWhenMissing ? _T("") : _T("ر"), nDefaultMajor, nDefaultMinor); @@ -275,36 +273,30 @@ int BuildVersionsFromRepo( CString strBranch; if (!TryGetCurrentBranch(lpRepoPath, strBranch)) { - _tprintf(_T(": ȡǰ֧ʧܡ\n")); + _tprintf(_T("����: ��ȡ��ǰ��֧ʧ�ܡ�\n")); return errorCodes.nBidErrorCode; } - _tprintf(_T("ǰ֧: %s\n"), strBranch.GetString()); + _tprintf(_T("��ǰ��֧: %s\n"), strBranch.GetString()); if (!TryGetBidFromBranch(strBranch, nBid)) { - _tprintf(_T(": ȡ֧ bid ʧ\n")); + _tprintf(_T("����: ��ȡ��֧ bid ʧ��\n")); return errorCodes.nBidErrorCode; } - _tprintf(_T("֧ bid: %u\n"), nBid); + _tprintf(_T("��֧ bid: %u\n"), nBid); CString strLastTag; UINT nMajor = 0; UINT nMinor = 0; if (!GetLastMajorMinorTag(lpRepoPath, strBranch, strLastTag, nMajor, nMinor)) { - if (!bUseDefaultTagWhenMissing) - { - _tprintf(_T(": ȡǩʧ\n")); - return errorCodes.nTagErrorCode; - } - nMajor = nDefaultMajor; nMinor = nDefaultMinor; - _tprintf(_T("ʹĬϱǩ %u %u\n"), nMajor, nMinor); + _tprintf(_T("ʹ��Ĭ�ϱ�ǩ %u %u\n"), nMajor, nMinor); } else { - _tprintf(_T("ȡıǩ: %s (major=%u minor=%u)\n"), strLastTag.GetString(), nMajor, nMinor); + _tprintf(_T("��ȡ���ı�ǩ: %s (major=%u minor=%u)\n"), strLastTag.GetString(), nMajor, nMinor); } UINT nYY = 0; @@ -312,13 +304,13 @@ int BuildVersionsFromRepo( UINT nId = 0; if (!ResolveFileVersionDateAndCommitCount(lpRepoPath, strBranch, nYY, nMMDD, nId)) { - _tprintf(_T(": ȡ֧ύϢʧ\n")); + _tprintf(_T("����: ��ȡ��֧�ύ��Ϣʧ��\n")); return errorCodes.nCommitErrorCode; } - _tprintf(_T("֧ύϢ: yy=%u mmdd=%u id=%u\n"), nYY, nMMDD, nId); + _tprintf(_T("��֧�ύ��Ϣ: yy=%u mmdd=%u id=%u\n"), nYY, nMMDD, nId); strProductVersion.Format(_T("%u.%u.%u.%u"), nPid, nBid, nMajor, nMinor); strFileVersion.Format(_T("%u.%u.%u.%u"), nPid, nYY, nMMDD, nId); - _tprintf(_T("ļ汾Ϣ: ProductVersion=%s FileVersion=%s\n"), strProductVersion.GetString(), strFileVersion.GetString()); + _tprintf(_T("�ļ��汾��Ϣ: ProductVersion=%s FileVersion=%s\n"), strProductVersion.GetString(), strFileVersion.GetString()); return 0; } \ No newline at end of file diff --git a/GitVer/GitVer_version.h b/GitVer/GitVer_version.h index e3f9045..291dbd7 100644 --- a/GitVer/GitVer_version.h +++ b/GitVer/GitVer_version.h @@ -17,6 +17,5 @@ int BuildVersionsFromRepo( const VersionBuildErrorCodes& errorCodes, CString& strProductVersion, CString& strFileVersion, - BOOL bUseDefaultTagWhenMissing, UINT nDefaultMajor, UINT nDefaultMinor); diff --git a/README.md b/README.md index 6b0aeaf..82fe20b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,372 @@ # GitVer -# 命令行版本管理工具 \ No newline at end of file + +命令行版本管理工具,从 Git 仓库读取 tag 自动生成并回写版本号。 + +--- + +## 用法总览 + +``` +gitver +gitver rewrite [PEType] [-f] +gitver setver= [repodir=] [-f] [-test] [-setup=0|1] +gitver nuitkabuild= [repodir=] [-f] [-test] [params=""] +gitver nuitkapydbuild= [repodir=] [-f] [-test] [params=""] +gitver -setup=0|1 [repodir=] [-f] [-test] +``` + +**通用参数说明:** + +| 参数 | 说明 | +|---|---| +| `pid` | 产品 ID,整数,范围 0-65535,内嵌在命令名中(如 `setver=5`) | +| `repodir=` | Git 仓库目录,缺省使用当前运行目录 | +| `-f` | 未找到当前分支 tag 时使用默认 major/minor(1.0)继续 | +| `-test` | 将产品版本号的 major/minor 置为 0(测试版本构建) | +| `params="..."` | 传递给 Nuitka 的额外参数,用双引号括起来 | + +**BID 规则:** +`main`/`master` 分支固定 `bid=0`;其他分支格式须为 `<描述>.<数字>`,自动读取末尾数字作为 `bid`。 + +--- + +## 命令详解 + +### `gitver`(无参数交互模式) + +自动读取当前分支最近三次符合 `<分支>.major.minor` 格式的 tag,提示用户选择 major+1 或 minor+1,二次确认后创建新 tag。 + +当前分支无有效 tag 时进入首发引导:提示输入默认 major/minor(回车使用默认 1/0),再创建首个 tag。 + +**交互示例(已有 tag):** + +``` +当前分支: main,最近三个 tag: + main.1920.9 + main.1920.10 + main.1920.11 +输入 1 → 创建 main.1921.0 +输入 2 → 创建 main.1920.12 +``` + +**交互示例(无 tag 首发):** + +``` +未找到符合规则的历史标签 +输入默认 major(回车=1): 2 +输入默认 minor(回车=0): 5 +→ 创建 <分支>.2.5 +``` + +--- + +### `gitver rewrite` + +自动识别当前目录源码类型(C++、C#、Python),执行默认版本回写。 + +``` +gitver rewrite [PEType] [-f] +``` + +| 参数 | 说明 | +|---|---| +| `PEType` | 可选,`1`=EXE(默认),`2`=DLL,最多出现一次 | +| `-f` | 强制模式:未找到目标文件或回写失败仅提示,不返回错误码 35 | + +**回写行为:** + +- **C++**:递归查找首个 `.rc` 文件,回写 `FILEVERSION`、`PRODUCTVERSION`、`VALUE "FileVersion"`、`VALUE "ProductVersion"`(限定在 `VS_VERSION_INFO` 版本块内) +- **C#**:递归查找首个 `AssemblyInfo.cs`,回写 `AssemblyVersion`、`AssemblyFileVersion` +- **Python**:不执行回写,提示改用 `nuitkabuild=` 或 `nuitkapydbuild=` + +**示例:** + +``` +gitver rewrite +gitver rewrite 2 +gitver rewrite -f +``` + +--- + +### `gitver setver=` + +从 Git 仓库读取 tag,生成产品版本号与文件版本号,并按源码类型自动回写。 + +``` +gitver setver= [repodir=] [-f] [-test] [-setup=0|1] +``` + +**版本号生成规则:** + +- `ProductVersion = pid.bid.major.minor`(取当前分支前缀的最新 tag) +- `FileVersion = pid.yy.mmdd.id`(id = 当天当前分支提交次数) + +**`-setup=N` 标志(打包模式):** + +存在 `-setup=N` 时,**不回写**版本信息到项目文件,改为: +1. 在 exe 目录或上级目录查找安装脚本 +2. 修改脚本中的版本号字段 +3. 调用对应编译器打包 + +| 值 | 脚本文件 | 编译器 | +|---|---|---| +| `0` | `setup.iss` | Inno Setup(`ISCC.exe`) | +| `1` | `setup.nsi` | NSIS(`makensis.exe`) | + +**示例:** + +``` +gitver setver=5 +gitver setver=5 repodir=E:\Code\OTH\gitver +gitver setver=5 -f +gitver setver=5 -test +gitver setver=5 -setup=0 +gitver setver=5 repodir=E:\Code\MyProj -setup=1 +``` + +**输出示例:** + +``` +ProductVersion=5.0.1920.11 +FileVersion=5.26.0519.3 +``` + +**回写说明:** + +- **C++**:回写 `.rc` 文件中的 FILEVERSION、PRODUCTVERSION 及对应字符串字段 +- **C#**:回写 `AssemblyInfo.cs` 中的 AssemblyVersion、AssemblyFileVersion +- **Python**:仅输出版本号,不执行文件回写,提示改用 Nuitka 命令 +- 编码:支持 ANSI/UTF-8(保留 UTF-8 BOM);UTF-16 文件会报错停止 + +--- + +### `gitver nuitkabuild=` + +生成版本号并调用 Nuitka 打包 Python 程序(EXE 模式)。 + +``` +gitver nuitkabuild= [repodir=] [-f] [-test] [params=""] +``` + +自动调用: + +``` +python -m nuitka --windows-product-version=<版本> --windows-file-version=<版本> +``` + +**示例:** + +``` +gitver nuitkabuild=5 main.py +gitver nuitkabuild=5 main.py -f +gitver nuitkabuild=5 main.py -test +gitver nuitkabuild=5 src\app.py repodir=E:\Code\MyPyProj params="--standalone --output-dir=dist" +``` + +**输出示例:** + +``` +Nuitka 打包开始.. +ProductVersion=5.0.1920.11 +FileVersion=5.26.0519.3 +``` + +> 需要当前环境已安装 Nuitka(可通过 `python -m nuitka --version` 验证)。 + +--- + +### `gitver nuitkapydbuild=` + +生成版本号并调用 Nuitka 打包 Python 模块(pyd/DLL 模式)。 + +``` +gitver nuitkapydbuild= [repodir=] [-f] [-test] [params=""] +``` + +自动调用: + +``` +python -m nuitka --module --windows-product-version=<版本> --windows-file-version=<版本> +``` + +**示例:** + +``` +gitver nuitkapydbuild=5 module.py +gitver nuitkapydbuild=5 module.py -f +gitver nuitkapydbuild=5 module.py -test +gitver nuitkapydbuild=5 src\core.py repodir=E:\Code\MyPyProj params="--output-dir=dist" +``` + +> 需要当前环境已安装 Nuitka(可通过 `python -m nuitka --version` 验证)。 + +--- + +### `gitver -setup=0|1`(独立打包命令) + +独立调用安装脚本打包,不依赖 `setver=` 命令。 + +``` +gitver -setup=0|1 [repodir=] [-f] [-test] +``` + +**示例:** + +``` +gitver -setup=0 5 +gitver -setup=1 5 repodir=E:\Code\MyProj +``` + +--- + +## 错误码 + +| 码 | 含义 | +|---|---| +| 2 | 默认回写流程下未获取到 git 提交号 | +| 3 | 参数非法或未知参数 | +| 4 | `setver=` 的 pid 非法 | +| 5 | `setver=` 无法根据分支名计算 bid | +| 6 | `setver=` 未找到当前分支格式 tag | +| 9 | `setver=` 获取当天分支提交次数失败 | +| 15 | 回写流程未识别源码类型 | +| 16 | 回写流程识别到 Python,请改用 nuitka 命令 | +| 17 | `nuitkabuild=` 参数不足(缺少 mainPy) | +| 18 | `nuitkabuild=` 的 pid 非法 | +| 19 | `nuitkabuild=` 无法根据分支名计算 bid | +| 20 | `nuitkabuild=` 未找到当前分支格式 tag | +| 21 | `nuitkabuild=` 获取当天分支提交次数失败 | +| 22 | `rewrite` 参数非法(PEType 非法或重复) | +| 23 | `repodir=` 不是有效目录 | +| 24 | `nuitkapydbuild=` 参数不足(缺少 modulePy) | +| 25 | `nuitkapydbuild=` 的 pid 非法 | +| 26 | `nuitkapydbuild=` 无法根据分支名计算 bid | +| 27 | `nuitkapydbuild=` 未找到当前分支格式 tag | +| 28 | `nuitkapydbuild=` 获取当天分支提交次数失败 | +| 29 | 无参数模式下无法获取当前分支 | +| 30 | 无参数模式下读取标签列表失败 | +| 31 | 无参数模式下未读取到用户输入 | +| 32 | 无参数模式下用户选择非法,或 major/minor 已达上限 | +| 33 | 无参数模式下创建 tag 失败 | +| 34 | 无参数模式下创建 tag 后校验失败 | +| 35 | 未找到可回写目标文件,或回写失败 | +| 36 | `-setup=` 值不支持(仅支持 0 和 1) | +| 37 | 未找到安装脚本(setup.iss / setup.nsi) | +| 38 | 修改安装脚本失败 | +| 39 | 未找到安装编译器(ISCC.exe / makensis.exe) | + +--- + +## 最小自测 + +### 基础验证:`setver=` + +```bash +# 初始化测试仓库 +mkdir test_repo && cd test_repo +git init +echo test > README.txt +git add . && git commit -m "init" +git tag main.1920.10 +git tag main.1920.11 + +# 验证版本生成 +gitver setver=5 +# 预期: +# ProductVersion=5.0.1920.11 +# FileVersion=5.yy.mmdd. +# 返回码: 0 +``` + +### 验证 `-f`(无 tag 时使用默认版本) + +```bash +git checkout -b newbranch +gitver setver=5 -f +# 预期: ProductVersion=5..1.0 +# 返回码: 0 +``` + +### 验证分支 tag 隔离 + +```bash +git checkout -b feature.12 +git tag feature.12.1930.7 +git tag feature.12.1930.8 +gitver setver=5 +# 预期: ProductVersion=5.12.1930.8(忽略 main.* tag) +# 返回码: 0 +``` + +### 验证 `-test` + +```bash +gitver setver=5 -test +# 预期: ProductVersion=5.0.0.0(major/minor 置零) +# 返回码: 0 +``` + +### 验证 `nuitkabuild=` + +```bash +gitver nuitkabuild=5 main.py +# 预期: 调用 python -m nuitka,注入版本号参数 + +gitver nuitkabuild=5 src\app.py params="--standalone --output-dir=dist" +# 预期: 额外参数传递给 Nuitka +``` + +### 验证 `-setup=` + +```bash +# 确保 exe 目录或上级目录有 setup.iss +gitver setver=5 -setup=0 +# 预期: 修改 setup.iss 中的版本号并调用 ISCC.exe 编译 +``` + +--- + +## 回归清单 + +### rewrite 组 + +| 命令 | 预期返回码 | +|---|---| +| `gitver rewrite` | 0 / 15 / 16 / 35 | +| `gitver rewrite -f` | 0 / 15 / 16 | +| `gitver rewrite 2` | 0 / 15 / 35 | +| `gitver rewrite 1 2` | 22 | + +### setver= 组 + +| 命令 | 预期返回码 | +|---|---| +| `gitver setver=5` | 0 | +| `gitver setver=5 -f` | 0 | +| `gitver setver=5 -test` | 0 | +| `gitver setver=5 repodir=E:\NotExists` | 23 | +| `gitver setver=5 -setup=0` | 0 / 37 / 38 / 39 | +| `gitver setver=5 -setup=9` | 36 | +| `gitver setver=abc` | 4 | + +### nuitkabuild= 组 + +| 命令 | 预期返回码 | +|---|---| +| `gitver nuitkabuild=5 main.py` | 0 / 19 / 20 / 21 | +| `gitver nuitkabuild=5 main.py -f` | 0 | +| `gitver nuitkabuild=5 main.py -test` | 0 | +| `gitver nuitkabuild=5 main.py params="--standalone"` | 0 | +| `gitver nuitkabuild=5 main.py repodir=E:\NotExists` | 23 | +| `gitver nuitkabuild=5` | 17 | + +### nuitkapydbuild= 组 + +| 命令 | 预期返回码 | +|---|---| +| `gitver nuitkapydbuild=5 module.py` | 0 / 26 / 27 / 28 | +| `gitver nuitkapydbuild=5 module.py -f` | 0 | +| `gitver nuitkapydbuild=5 module.py params="--output-dir=dist"` | 0 | +| `gitver nuitkapydbuild=5 module.py repodir=E:\NotExists` | 23 | +| `gitver nuitkapydbuild=5` | 24 |