支持spec内置版本信息的处理
This commit is contained in:
@@ -462,6 +462,125 @@ static BOOL UpdateVersionInfoFile(LPCTSTR lpPath, LPCTSTR lpProductVersion, LPCT
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// 检查 spec 文件中 version= 是否为无引号标识符(表示 spec 内内联 VSVersionInfo 对象)
|
||||
static BOOL HasInlineVersionInfoBlock(LPCTSTR lpSpecPath)
|
||||
{
|
||||
if (!PathFileExists(lpSpecPath)) return FALSE;
|
||||
|
||||
CFile myFile;
|
||||
CFileException fileEx;
|
||||
if (!myFile.Open(lpSpecPath, CFile::modeRead, &fileEx)) return FALSE;
|
||||
|
||||
DWORD dwLen = (DWORD)myFile.GetLength();
|
||||
std::vector<char> buf(dwLen + 1, 0);
|
||||
myFile.Read(buf.data(), dwLen);
|
||||
myFile.Close();
|
||||
|
||||
std::string strContent(buf.data(), dwLen);
|
||||
std::string::size_type nPos = 0;
|
||||
while ((nPos = strContent.find("version=", nPos)) != std::string::npos)
|
||||
{
|
||||
bool bIsParam = (nPos == 0
|
||||
|| strContent[nPos - 1] == '\n'
|
||||
|| strContent[nPos - 1] == '\r'
|
||||
|| strContent[nPos - 1] == ' '
|
||||
|| strContent[nPos - 1] == '\t');
|
||||
if (bIsParam)
|
||||
{
|
||||
std::string::size_type nValStart = nPos + 8;
|
||||
while (nValStart < strContent.size() && strContent[nValStart] == ' ')
|
||||
nValStart++;
|
||||
if (nValStart < strContent.size())
|
||||
{
|
||||
char c = strContent[nValStart];
|
||||
// 无引号且以字母或下划线开头,视为 Python 标识符
|
||||
if (c != '\'' && c != '"' && (isalpha((unsigned char)c) || c == '_'))
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
nPos += 8;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 修改 spec 文件中 version= 的引号值(内联版本号字符串场景)
|
||||
// 当 version= 后是非外部文件路径的字符串字面量时,直接替换该值为新版本号
|
||||
static BOOL UpdateVersionStringInSpec(LPCTSTR lpSpecPath, LPCTSTR lpNewValue)
|
||||
{
|
||||
if (!PathFileExists(lpSpecPath))
|
||||
{
|
||||
_tprintf(_T("错误: spec 文件不存在: %s\n"), lpSpecPath);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CFile myFile;
|
||||
CFileException fileEx;
|
||||
if (!myFile.Open(lpSpecPath, CFile::modeReadWrite, &fileEx))
|
||||
{
|
||||
_tprintf(_T("错误: 无法打开 spec 文件: %s\n"), lpSpecPath);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD dwLen = (DWORD)myFile.GetLength();
|
||||
std::vector<char> buf(dwLen + 1, 0);
|
||||
myFile.Read(buf.data(), dwLen);
|
||||
myFile.Close();
|
||||
|
||||
std::string strContent(buf.data(), dwLen);
|
||||
CStringA strNewValueA(lpNewValue);
|
||||
std::string strNewValue(strNewValueA);
|
||||
|
||||
std::string::size_type nPos = 0;
|
||||
bool bUpdated = false;
|
||||
while ((nPos = strContent.find("version=", nPos)) != std::string::npos)
|
||||
{
|
||||
bool bIsParam = (nPos == 0
|
||||
|| strContent[nPos - 1] == '\n'
|
||||
|| strContent[nPos - 1] == '\r'
|
||||
|| strContent[nPos - 1] == ' '
|
||||
|| strContent[nPos - 1] == '\t');
|
||||
if (bIsParam)
|
||||
{
|
||||
std::string::size_type nValStart = nPos + 8; // skip "version="
|
||||
while (nValStart < strContent.size() && strContent[nValStart] == ' ')
|
||||
nValStart++;
|
||||
if (nValStart < strContent.size())
|
||||
{
|
||||
char cQuote = strContent[nValStart];
|
||||
if (cQuote == '\'' || cQuote == '"')
|
||||
{
|
||||
std::string::size_type nValEnd = strContent.find(cQuote, nValStart + 1);
|
||||
if (nValEnd != std::string::npos)
|
||||
{
|
||||
strContent.replace(nValStart + 1, nValEnd - nValStart - 1, strNewValue);
|
||||
bUpdated = true;
|
||||
_tprintf(_T("成功: 已更新 spec 内联版本号 -> %s\n"), lpNewValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
nPos += 8;
|
||||
}
|
||||
|
||||
if (!bUpdated)
|
||||
{
|
||||
_tprintf(_T("错误: 未在 spec 文件中找到可替换的 version= 引号值。\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!myFile.Open(lpSpecPath, CFile::modeCreate | CFile::modeWrite, &fileEx))
|
||||
{
|
||||
_tprintf(_T("错误: 无法写入 spec 文件: %s\n"), lpSpecPath);
|
||||
return FALSE;
|
||||
}
|
||||
myFile.Write(strContent.c_str(), (UINT)strContent.size());
|
||||
myFile.Close();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int HandlePyinstallerBuildCommand(int argc, TCHAR* argv[])
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
@@ -535,13 +654,16 @@ int HandlePyinstallerBuildCommand(int argc, TCHAR* argv[])
|
||||
CString strExistingVersionPath;
|
||||
if (ReadVersionPathFromSpec(strSpecPath, strExistingVersionPath))
|
||||
{
|
||||
// spec 已有 version=,直接更新所指向的文件(不存在则创建)
|
||||
// spec 已有 version=,解析其指向的文件路径
|
||||
CString strVersionInfoFullPath;
|
||||
if (PathIsRelative(strExistingVersionPath))
|
||||
strVersionInfoFullPath.Format(_T("%s\\%s"), szSpecDir, strExistingVersionPath.GetString());
|
||||
else
|
||||
strVersionInfoFullPath = strExistingVersionPath;
|
||||
|
||||
if (PathFileExists(strVersionInfoFullPath))
|
||||
{
|
||||
// 外部版本信息文件存在,直接更新
|
||||
if (!UpdateVersionInfoFile(strVersionInfoFullPath, strProductVersion, strFileVersion))
|
||||
{
|
||||
_tprintf(_T("错误: 无法更新版本信息文件: %s。\n"), strVersionInfoFullPath.GetString());
|
||||
@@ -550,6 +672,27 @@ int HandlePyinstallerBuildCommand(int argc, TCHAR* argv[])
|
||||
_tprintf(_T("版本信息文件已更新: %s\n"), strVersionInfoFullPath.GetString());
|
||||
}
|
||||
else
|
||||
{
|
||||
// version= 后的值不是有效的外部文件路径,视为 spec 内联版本号定义,直接修改 spec
|
||||
_tprintf(_T("版本信息文件未找到(%s),将修改 spec 内联版本号。\n"), strVersionInfoFullPath.GetString());
|
||||
if (!UpdateVersionStringInSpec(strSpecPath, strFileVersion))
|
||||
{
|
||||
_tprintf(_T("错误: 无法修改 spec 文件内联版本号。\n"));
|
||||
return 46;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (HasInlineVersionInfoBlock(strSpecPath))
|
||||
{
|
||||
// spec 中 version=<标识符>,标识符指向 spec 内定义的 VSVersionInfo 对象,直接更新 spec 文件中的版本字段
|
||||
if (!UpdateVersionInfoFile(strSpecPath, strProductVersion, strFileVersion))
|
||||
{
|
||||
_tprintf(_T("错误: 无法更新 spec 内联版本块: %s。\n"), strSpecPath.GetString());
|
||||
return 45;
|
||||
}
|
||||
_tprintf(_T("spec 内联版本块已更新: %s\n"), strSpecPath.GetString());
|
||||
}
|
||||
else
|
||||
{
|
||||
// spec 未指定 version=,生成 version_info.txt 并注入 spec
|
||||
CString strVersionInfoPath;
|
||||
|
||||
Reference in New Issue
Block a user