Switch to semantic versioning via Git with fallback to old version string format.

This commit is contained in:
/dev/urandom 2016-08-30 23:55:11 +02:00
parent 3271a6d510
commit 8aae51db64
No known key found for this signature in database
GPG Key ID: 41322B973E0F295E
10 changed files with 90 additions and 71 deletions

View File

@ -1,3 +1,5 @@
gitVersioningCommand = "git describe --tags --dirty --always"
-- Quote the given string input as a C string
function cstrquote(value)
result = value:gsub("\\", "\\\\")
@ -11,6 +13,19 @@ function cstrquote(value)
return result
end
-- Converts tags in "vX.X.X" format to X,X,X.
-- In the case where the format does not work fall back to old 4,2,REVISION.
function vertonum(value, vernumber)
vernum = {}
for num in string.gmatch(value, "%d+") do
table.insert(vernum, num)
end
if #vernum < 3 then
return "4,2," .. vernumber
end
return vernum[1] .. "," .. vernum[2] .. "," .. vernum[3]
end
-- Option to allow copying the DLL file to a custom folder after build
newoption {
trigger = "copy-to",
@ -57,10 +72,12 @@ newoption {
trigger = "disable-bitmessage",
description = "Disable use of BitMessage completely."
}
newoption {
trigger = "disable-node-log",
description = "Disable debugging messages for Nodes in Debug builds."
}
newoption {
trigger = "disable-base128",
description = "Disable debugging messages for Nodes in Debug builds."
@ -70,12 +87,12 @@ newaction {
trigger = "version",
description = "Returns the version string for the current commit of the source code.",
onWorkspace = function(wks)
-- get revision number via git
local proc = assert(io.popen("git rev-list --count HEAD", "r"))
local revNumber = assert(proc:read('*a')):gsub("%s+", "")
-- get current version via git
local proc = assert(io.popen(gitVersioningCommand, "r"))
local gitDescribeOutput = assert(proc:read('*a')):gsub("%s+", "")
proc:close()
print(revNumber)
print(gitDescribeOutput)
os.exit(0)
end
}
@ -87,60 +104,73 @@ newaction {
-- get revision number via git
local proc = assert(io.popen("git rev-list --count HEAD", "r"))
local revNumber = assert(proc:read('*a')):gsub("%s+", "")
-- get current version via git
local proc = assert(io.popen(gitVersioningCommand, "r"))
local gitDescribeOutput = assert(proc:read('*a')):gsub("%s+", "")
proc:close()
-- get whether this is a clean revision (no uncommitted changes)
proc = assert(io.popen("git status --porcelain", "r"))
local revClean = 1
local revCleanSuffix = ""
if assert(proc:read('*a')) ~= "" then
revClean = 0
revCleanSuffix = " (unclean)"
end
local revDirty = (assert(proc:read('*a')) ~= "")
if revDirty then revDirty = 1 else revDirty = 0 end
proc:close()
-- get current tag name (aka milestone for now)
proc = assert(io.popen("git tag"))
proc = assert(io.popen("git describe --tags --abbrev=0"))
local tagName = assert(proc:read('*l'))
-- get old version number from version.hpp if any
local oldRevNumber = "(none)"
local oldRevClean = 1
local oldRevCleanSuffix = ""
local oldVersionHeader = io.open(wks.location .. "/src/version.hpp", "r")
if oldVersionHeader ~=nil then
local oldVersionHeaderContent = assert(oldVersionHeader:read('*a'))
oldRevNumber = string.match(oldVersionHeaderContent, "#define REVISION (%d+)")
if oldRevNumber == nil then
-- old version.hpp format?
oldRevNumber = "(none)"
local oldVersion = "(none)"
local oldVersionHeader = io.open(wks.location .. "/src/version.h", "r")
if oldVersionHeader ~= nil then
local oldVersionHeaderContent = assert(oldVersionHeader:read('*l'))
while oldVersionHeaderContent do
m = string.match(oldVersionHeaderContent, "#define GIT_DESCRIBE (.+)%s*$")
if m ~= nil then
oldVersion = m
end
oldVersionHeaderContent = oldVersionHeader:read('*l')
end
oldRevClean = string.match(oldVersionHeaderContent, "#define REVISION_CLEAN (%d+)")
if oldRevClean == nil then
-- old version.hpp format?
oldRevClean = 1
elseif oldRevClean ~= "1" then
oldRevClean = 0
else
oldRevClean = 1
end
end
if oldRevClean == 0 then
oldRevCleanSuffix = " (unclean)"
end
-- generate version.hpp with a revision number if not equal
if oldRevNumber ~= revNumber or oldRevClean ~= revClean then
print ("Update " .. oldRevNumber .. oldRevCleanSuffix .. " -> " .. revNumber .. revCleanSuffix)
local versionHeader = assert(io.open(wks.location .. "/src/version.hpp", "w"))
gitDescribeOutputQuoted = cstrquote(gitDescribeOutput)
if oldVersion ~= gitDescribeOutputQuoted then
print ("Update " .. oldVersion .. " -> " .. gitDescribeOutputQuoted)
local versionHeader = assert(io.open(wks.location .. "/src/version.h", "w"))
versionHeader:write("/*\n")
versionHeader:write(" * Automatically generated by premake5.\n")
versionHeader:write(" * Do not touch, you fucking moron!\n")
versionHeader:write(" */\n")
versionHeader:write("\n")
versionHeader:write("#define GIT_DESCRIBE " .. gitDescribeOutputQuoted .. "\n")
versionHeader:write("#define GIT_DIRTY " .. revDirty .. "\n")
versionHeader:write("#define GIT_TAG " .. cstrquote(tagName) .. "\n")
versionHeader:write("\n")
versionHeader:write("// Legacy definitions (needed for update check)\n")
versionHeader:write("#define REVISION " .. revNumber .. "\n")
versionHeader:write("#define REVISION_CLEAN " .. revClean .. "\n")
versionHeader:write("#define MILESTONE " .. cstrquote(tagName) .. "\n")
versionHeader:write("\n")
versionHeader:write("// Version transformed for RC files\n")
versionHeader:write("#define VERSION_RC " .. vertonum(tagName, revNumber) .. "\n")
versionHeader:write("\n")
versionHeader:write("// Alias definitions\n")
versionHeader:write("#define VERSION GIT_DESCRIBE\n")
versionHeader:write("#define SHORTVERSION GIT_TAG\n")
versionHeader:close()
local versionHeader = assert(io.open(wks.location .. "/src/version.hpp", "w"))
versionHeader:write("/*\n")
versionHeader:write(" * Automatically generated by premake5.\n")
versionHeader:write(" * Do not touch, you fucking moron!\n")
versionHeader:write(" *\n")
versionHeader:write(" * This file exists for reasons of complying with our coding standards.\n")
versionHeader:write(" *\n")
versionHeader:write(" * The Resource Compiler will ignore any content from C++ header files if they're not from STDInclude.hpp.\n")
versionHeader:write(" * That's the reason why we now place all version info in version.h instead.\n")
versionHeader:write(" */\n")
versionHeader:write("\n")
versionHeader:write("#include \".\\version.h\"\n")
versionHeader:close()
end
end

View File

@ -76,14 +76,14 @@ namespace Components
}
else if(IsWindow(*reinterpret_cast<HWND*>(0x64A3288)) != FALSE)
{
SetWindowTextA(*reinterpret_cast<HWND*>(0x64A3288), Utils::String::VA("IW4x(r" REVISION_STR REVISION_SUFFIX ") : %s", hostname.data()));
SetWindowTextA(*reinterpret_cast<HWND*>(0x64A3288), Utils::String::VA("IW4x(" VERSION ") : %s", hostname.data()));
}
}
void Console::ShowPrompt()
{
wattron(Console::InputWindow, COLOR_PAIR(10) | A_BOLD);
wprintw(Console::InputWindow, "%s> ", VERSION_STR);
wprintw(Console::InputWindow, "%s> ", VERSION);
}
void Console::RefreshOutput()
@ -477,7 +477,7 @@ namespace Components
Console::Console()
{
// Console '%s: %s> ' string
Utils::Hook::Set<char*>(0x5A44B4, "IW4x: r" REVISION_STR "> ");
Utils::Hook::Set<char*>(0x5A44B4, "IW4x: " VERSION "> ");
// Internal console
Utils::Hook(0x4F690C, Console::ToggleConsole, HOOK_CALL).Install()->Quick();

View File

@ -204,7 +204,7 @@ namespace Components
// Combine with queuedMinidumpsFolder
char filename[MAX_PATH];
PathCombineA(filename, MinidumpUpload::queuedMinidumpsFolder.data(), Utils::String::VA("%s-" VERSION_STR "-%s.dmp", exeFileName, filenameFriendlyTime));
PathCombineA(filename, MinidumpUpload::queuedMinidumpsFolder.data(), Utils::String::VA("%s-" VERSION "-%s.dmp", exeFileName, filenameFriendlyTime));
// Generate the dump
return Minidump::Create(filename, exceptionInfo, minidumpType);
@ -372,7 +372,7 @@ namespace Components
if (extraHeaders.find("Encoding") == extraHeaders.end())
extraHeaders["Encoding"] = "raw";
extraHeaders["Version"] = VERSION_STR;
extraHeaders["Version"] = VERSION;
output << "-----BEGIN " << marker << "-----\n";

View File

@ -308,7 +308,7 @@ namespace Components
info.Set("clients", fmt::sprintf("%i", clientCount));
info.Set("sv_maxclients", fmt::sprintf("%i", maxclientCount));
info.Set("protocol", fmt::sprintf("%i", PROTOCOL));
info.Set("shortversion", VERSION_STR);
info.Set("shortversion", SHORTVERSION);
info.Set("checksum", fmt::sprintf("%d", Game::Sys_Milliseconds()));
info.Set("mapname", Dvar::Var("mapname").Get<const char*>());
info.Set("isPrivate", (Dvar::Var("g_password").Get<std::string>().size() ? "1" : "0"));

View File

@ -173,26 +173,26 @@ namespace Components
Utils::Hook::Set<char*>(0x6431D1, BASEGAME);
// UI version string
Utils::Hook::Set<char*>(0x43F73B, "IW4x: r" REVISION_STR REVISION_SUFFIX "-" MILESTONE);
Utils::Hook::Set<char*>(0x43F73B, "IW4x: " VERSION);
// console version string
Utils::Hook::Set<char*>(0x4B12BB, "IW4x r" REVISION_STR REVISION_SUFFIX "-" MILESTONE " (built " __DATE__ " " __TIME__ ")");
Utils::Hook::Set<char*>(0x4B12BB, "IW4x " VERSION " (built " __DATE__ " " __TIME__ ")");
// version string
Utils::Hook::Set<char*>(0x60BD56, "IW4x (r" REVISION_STR REVISION_SUFFIX ")");
Utils::Hook::Set<char*>(0x60BD56, "IW4x (" VERSION ")");
// console title
if (ZoneBuilder::IsEnabled())
{
Utils::Hook::Set<char*>(0x4289E8, "IW4x (r" REVISION_STR REVISION_SUFFIX "): ZoneBuilder");
Utils::Hook::Set<char*>(0x4289E8, "IW4x (" VERSION "): ZoneBuilder");
}
else if (Dedicated::IsEnabled())
{
Utils::Hook::Set<char*>(0x4289E8, "IW4x (r" REVISION_STR REVISION_SUFFIX "): Dedicated");
Utils::Hook::Set<char*>(0x4289E8, "IW4x (r" VERSION "): Dedicated");
}
else
{
Utils::Hook::Set<char*>(0x4289E8, "IW4x (r" REVISION_STR REVISION_SUFFIX "): Console");
Utils::Hook::Set<char*>(0x4289E8, "IW4x (r" VERSION "): Console");
}
// window title
@ -202,7 +202,7 @@ namespace Components
Utils::Hook::Set<char*>(0x4D378B, "IW4Host");
// shortversion
Utils::Hook::Set<char*>(0x60BD91, VERSION_STR);
Utils::Hook::Set<char*>(0x60BD91, SHORTVERSION);
// console logo
Utils::Hook::Set<char*>(0x428A66, BASEGAME "/images/logo.bmp");

View File

@ -115,7 +115,7 @@ namespace Components
info.Set("gamename", "IW4");
info.Set("sv_maxclients", fmt::sprintf("%i", maxclientCount));
info.Set("protocol", fmt::sprintf("%i", PROTOCOL));
info.Set("shortversion", VERSION_STR);
info.Set("shortversion", SHORTVERSION);
info.Set("mapname", Dvar::Var("mapname").Get<const char*>());
info.Set("isPrivate", (Dvar::Var("g_password").Get<std::string>().empty() ? "0" : "1"));
info.Set("checksum", fmt::sprintf("%X", Utils::Cryptography::JenkinsOneAtATime::Compute(fmt::sprintf("%u", Game::Sys_Milliseconds()))));

View File

@ -449,7 +449,7 @@ namespace Components
if (info.Get("gamename") == "IW4"
&& server.MatchType
#ifndef DEBUG
&& server.Shortversion == VERSION_STR
&& server.Shortversion == SHORTVERSION
#endif
)
{

View File

@ -13,7 +13,7 @@ namespace Components
{
if (Flags::HasFlag("version"))
{
printf("IW4x r" REVISION_STR "-" MILESTONE " (built " __DATE__ " " __TIME__ ")\n");
printf("IW4x " VERSION " (built " __DATE__ " " __TIME__ ")\n");
ExitProcess(0);
}

View File

@ -2,7 +2,6 @@
//
#pragma code_page(65001)
#define RESOURCE_DATA
#include "STDInclude.hpp"
#define APSTUDIO_READONLY_SYMBOLS
@ -47,8 +46,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION VERSION
PRODUCTVERSION VERSION
FILEVERSION VERSION_RC
PRODUCTVERSION VERSION_RC
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -69,12 +68,12 @@ BEGIN
#else
VALUE "FileDescription", "IW4 client modification"
#endif
VALUE "FileVersion", VERSION_STR
VALUE "FileVersion", SHORTVERSION
VALUE "InternalName", "iw4x"
VALUE "LegalCopyright", "No rights reserved."
VALUE "OriginalFilename", "iw4x.dll"
VALUE "ProductName", "IW4x"
VALUE "ProductVersion", VERSION_STR
VALUE "ProductVersion", SHORTVERSION
END
END
BLOCK "VarFileInfo"

View File

@ -1,9 +1,9 @@
#pragma once
// Version number
#include <version.hpp>
#include "version.h"
#ifndef RESOURCE_DATA
#ifndef RC_INVOKED
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
@ -120,22 +120,12 @@ using namespace std::literals;
#endif
// Revision number
#define STRINGIZE_(x) #x
#define STRINGIZE(x) STRINGIZE_(x)
#define BASEGAME "iw4x"
#define CLIENT_CONFIG "iw4x_config.cfg"
#define REVISION_STR STRINGIZE(REVISION)
#if !REVISION_CLEAN
#define REVISION_SUFFIX "*"
#else
#define REVISION_SUFFIX ""
#endif
#define VERSION 4,2,REVISION
#define VERSION_STR "4.2." REVISION_STR
#define Assert_Size(x, size) static_assert(sizeof(x) == size, STRINGIZE(x) " structure has an invalid size.")
// Resource stuff