From 8aae51db647804d8699c6623b4739e71e5070fea Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 30 Aug 2016 23:55:11 +0200 Subject: [PATCH] Switch to semantic versioning via Git with fallback to old version string format. --- premake5.lua | 106 ++++++++++++++-------- src/Components/Modules/Console.cpp | 6 +- src/Components/Modules/MinidumpUpload.cpp | 4 +- src/Components/Modules/Party.cpp | 2 +- src/Components/Modules/QuickPatch.cpp | 14 +-- src/Components/Modules/ServerInfo.cpp | 2 +- src/Components/Modules/ServerList.cpp | 2 +- src/Components/Modules/Singleton.cpp | 2 +- src/Resource.rc | 9 +- src/STDInclude.hpp | 14 +-- 10 files changed, 90 insertions(+), 71 deletions(-) diff --git a/premake5.lua b/premake5.lua index b68220b5..476a647a 100644 --- a/premake5.lua +++ b/premake5.lua @@ -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 diff --git a/src/Components/Modules/Console.cpp b/src/Components/Modules/Console.cpp index dc3f19d6..6b25113d 100644 --- a/src/Components/Modules/Console.cpp +++ b/src/Components/Modules/Console.cpp @@ -76,14 +76,14 @@ namespace Components } else if(IsWindow(*reinterpret_cast(0x64A3288)) != FALSE) { - SetWindowTextA(*reinterpret_cast(0x64A3288), Utils::String::VA("IW4x(r" REVISION_STR REVISION_SUFFIX ") : %s", hostname.data())); + SetWindowTextA(*reinterpret_cast(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(0x5A44B4, "IW4x: r" REVISION_STR "> "); + Utils::Hook::Set(0x5A44B4, "IW4x: " VERSION "> "); // Internal console Utils::Hook(0x4F690C, Console::ToggleConsole, HOOK_CALL).Install()->Quick(); diff --git a/src/Components/Modules/MinidumpUpload.cpp b/src/Components/Modules/MinidumpUpload.cpp index 8fca92c0..89da69a8 100644 --- a/src/Components/Modules/MinidumpUpload.cpp +++ b/src/Components/Modules/MinidumpUpload.cpp @@ -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"; diff --git a/src/Components/Modules/Party.cpp b/src/Components/Modules/Party.cpp index 7922d1c8..3f467b8c 100644 --- a/src/Components/Modules/Party.cpp +++ b/src/Components/Modules/Party.cpp @@ -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()); info.Set("isPrivate", (Dvar::Var("g_password").Get().size() ? "1" : "0")); diff --git a/src/Components/Modules/QuickPatch.cpp b/src/Components/Modules/QuickPatch.cpp index be912454..01019f39 100644 --- a/src/Components/Modules/QuickPatch.cpp +++ b/src/Components/Modules/QuickPatch.cpp @@ -173,26 +173,26 @@ namespace Components Utils::Hook::Set(0x6431D1, BASEGAME); // UI version string - Utils::Hook::Set(0x43F73B, "IW4x: r" REVISION_STR REVISION_SUFFIX "-" MILESTONE); + Utils::Hook::Set(0x43F73B, "IW4x: " VERSION); // console version string - Utils::Hook::Set(0x4B12BB, "IW4x r" REVISION_STR REVISION_SUFFIX "-" MILESTONE " (built " __DATE__ " " __TIME__ ")"); + Utils::Hook::Set(0x4B12BB, "IW4x " VERSION " (built " __DATE__ " " __TIME__ ")"); // version string - Utils::Hook::Set(0x60BD56, "IW4x (r" REVISION_STR REVISION_SUFFIX ")"); + Utils::Hook::Set(0x60BD56, "IW4x (" VERSION ")"); // console title if (ZoneBuilder::IsEnabled()) { - Utils::Hook::Set(0x4289E8, "IW4x (r" REVISION_STR REVISION_SUFFIX "): ZoneBuilder"); + Utils::Hook::Set(0x4289E8, "IW4x (" VERSION "): ZoneBuilder"); } else if (Dedicated::IsEnabled()) { - Utils::Hook::Set(0x4289E8, "IW4x (r" REVISION_STR REVISION_SUFFIX "): Dedicated"); + Utils::Hook::Set(0x4289E8, "IW4x (r" VERSION "): Dedicated"); } else { - Utils::Hook::Set(0x4289E8, "IW4x (r" REVISION_STR REVISION_SUFFIX "): Console"); + Utils::Hook::Set(0x4289E8, "IW4x (r" VERSION "): Console"); } // window title @@ -202,7 +202,7 @@ namespace Components Utils::Hook::Set(0x4D378B, "IW4Host"); // shortversion - Utils::Hook::Set(0x60BD91, VERSION_STR); + Utils::Hook::Set(0x60BD91, SHORTVERSION); // console logo Utils::Hook::Set(0x428A66, BASEGAME "/images/logo.bmp"); diff --git a/src/Components/Modules/ServerInfo.cpp b/src/Components/Modules/ServerInfo.cpp index 8a3151e7..695d4470 100644 --- a/src/Components/Modules/ServerInfo.cpp +++ b/src/Components/Modules/ServerInfo.cpp @@ -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()); info.Set("isPrivate", (Dvar::Var("g_password").Get().empty() ? "0" : "1")); info.Set("checksum", fmt::sprintf("%X", Utils::Cryptography::JenkinsOneAtATime::Compute(fmt::sprintf("%u", Game::Sys_Milliseconds())))); diff --git a/src/Components/Modules/ServerList.cpp b/src/Components/Modules/ServerList.cpp index 9cff72d7..06aa5454 100644 --- a/src/Components/Modules/ServerList.cpp +++ b/src/Components/Modules/ServerList.cpp @@ -449,7 +449,7 @@ namespace Components if (info.Get("gamename") == "IW4" && server.MatchType #ifndef DEBUG - && server.Shortversion == VERSION_STR + && server.Shortversion == SHORTVERSION #endif ) { diff --git a/src/Components/Modules/Singleton.cpp b/src/Components/Modules/Singleton.cpp index 7c8d5956..bb13be4f 100644 --- a/src/Components/Modules/Singleton.cpp +++ b/src/Components/Modules/Singleton.cpp @@ -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); } diff --git a/src/Resource.rc b/src/Resource.rc index 44f73f4e..1a74c1b4 100644 --- a/src/Resource.rc +++ b/src/Resource.rc @@ -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" diff --git a/src/STDInclude.hpp b/src/STDInclude.hpp index 6a3faf0f..35936c14 100644 --- a/src/STDInclude.hpp +++ b/src/STDInclude.hpp @@ -1,9 +1,9 @@ #pragma once // Version number -#include +#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