From 5bda49a2b896ed1b9a3b18b62ef539425ea1f1b0 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 25 Oct 2008 14:29:06 +0400 Subject: [PATCH] Implement git support in gensvnrevision tool and related changes in code. gvnrevision still support svn version generation and have addition options now (see sources). gensvnrevision/svn_revision.h and other svn reference will fixed later. Now version strings include commit date/time that can be used in git case for fast find git commit without using git hash most time. In chat ".server info" output git hash can be copied by shift-click in chat and then copied to cliboard if need. --- src/game/Level0.cpp | 9 +- src/mangosd/CliRunnable.cpp | 1 - src/mangosd/Master.cpp | 3 +- src/realmd/Main.cpp | 3 +- src/shared/SystemConfig.h.in | 13 +- src/tools/gensvnrevision/gensvnrevision.cpp | 271 +++++++++++++++++++++++----- 6 files changed, 248 insertions(+), 52 deletions(-) diff --git a/src/game/Level0.cpp b/src/game/Level0.cpp index 4b9350c2c..e6b2aaecf 100644 --- a/src/game/Level0.cpp +++ b/src/game/Level0.cpp @@ -29,6 +29,7 @@ #include "Language.h" #include "AccountMgr.h" #include "SystemConfig.h" +#include "svn_revision.h" #include "Util.h" bool ChatHandler::HandleHelpCommand(const char* args) @@ -92,7 +93,13 @@ bool ChatHandler::HandleInfoCommand(const char* /*args*/) uint32 maxQueuedClientsNum = sWorld.GetMaxQueuedSessionCount(); std::string str = secsToTimeString(sWorld.GetUptime()); - PSendSysMessage(_FULLVERSION); + char const* full; + if(m_session) + full = _FULLVERSION(SVN_DATE,SVN_TIME,"|cffffffff|Hurl:" SVN_REVISION "|h" SVN_REVISION "|h|r"); + else + full = _FULLVERSION(SVN_DATE,SVN_TIME,SVN_REVISION); + + PSendSysMessage(full); PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum); PSendSysMessage(LANG_UPTIME, str.c_str()); diff --git a/src/mangosd/CliRunnable.cpp b/src/mangosd/CliRunnable.cpp index b48e1c576..77d87fcda 100644 --- a/src/mangosd/CliRunnable.cpp +++ b/src/mangosd/CliRunnable.cpp @@ -27,7 +27,6 @@ #include "ScriptCalls.h" #include "ObjectMgr.h" #include "WorldSession.h" -#include "SystemConfig.h" #include "Config/ConfigEnv.h" #include "Util.h" #include "AccountMgr.h" diff --git a/src/mangosd/Master.cpp b/src/mangosd/Master.cpp index 0c883e4c9..c1a9a9a37 100644 --- a/src/mangosd/Master.cpp +++ b/src/mangosd/Master.cpp @@ -32,6 +32,7 @@ #include "Timer.h" #include "Policies/SingletonImp.h" #include "SystemConfig.h" +#include "svn_revision.h" #include "Config/ConfigEnv.h" #include "Database/DatabaseEnv.h" #include "CliRunnable.h" @@ -195,7 +196,7 @@ Master::~Master() /// Main function int Master::Run() { - sLog.outString( "%s (world-daemon)", _FULLVERSION ); + sLog.outString( "%s [world-daemon]", _FULLVERSION(SVN_DATE,SVN_TIME,SVN_REVISION) ); sLog.outString( " to stop.\n\n" ); sLog.outTitle( "MM MM MM MM MMMMM MMMM MMMMM"); diff --git a/src/realmd/Main.cpp b/src/realmd/Main.cpp index b9d53af17..be7ed148e 100644 --- a/src/realmd/Main.cpp +++ b/src/realmd/Main.cpp @@ -29,6 +29,7 @@ #include "sockets/ListenSocket.h" #include "AuthSocket.h" #include "SystemConfig.h" +#include "svn_revision.h" #include "Util.h" #ifdef WIN32 @@ -149,7 +150,7 @@ extern int main(int argc, char **argv) while (pause > clock()) {} } - sLog.outString( "%s (realm-daemon)", _FULLVERSION ); + sLog.outString( "%s [realm-daemon]", _FULLVERSION(SVN_DATE,SVN_TIME,SVN_REVISION) ); sLog.outString( " to stop.\n" ); /// realmd PID file creation diff --git a/src/shared/SystemConfig.h.in b/src/shared/SystemConfig.h.in index d669f9bbc..7a19c1dc4 100644 --- a/src/shared/SystemConfig.h.in +++ b/src/shared/SystemConfig.h.in @@ -24,13 +24,12 @@ #endif #include "Platform/Define.h" -#include "svn_revision.h" #ifndef _VERSION #if PLATFORM == PLATFORM_WINDOWS -# define _VERSION "0.12.0-SVN" " (Revision " SVN_REVISION ")" +# define _VERSION(REVD,REVT,REV) "0.12.0-SVN" " (" REVD " " REVT " Revision " REV ")" #else -# define _VERSION "@VERSION@" " (Revision " SVN_REVISION ")" +# define _VERSION(REVD,REVT,REV) "@VERSION@" " (" REVD " " REVT " Revision " REV ")" #endif #endif @@ -56,18 +55,20 @@ #if PLATFORM == PLATFORM_WINDOWS # ifdef _WIN64 -# define _FULLVERSION _PACKAGENAME "/" _VERSION " (Win64," _ENDIAN_STRING ")" +# define _ENDIAN_PLATFORM "Win64 (" _ENDIAN_STRING ")" # else -# define _FULLVERSION _PACKAGENAME "/" _VERSION " (Win32," _ENDIAN_STRING ")" +# define _ENDIAN_PLATFORM "Win32 (" _ENDIAN_STRING ")" # endif # define _MANGOSD_CONFIG SYSCONFDIR"mangosd.conf" # define _REALMD_CONFIG SYSCONFDIR"realmd.conf" #else -# define _FULLVERSION _PACKAGENAME "/" _VERSION " (Unix," _ENDIAN_STRING ")" +# define _ENDIAN_PLATFORM "Unix (" _ENDIAN_STRING ")" # define _MANGOSD_CONFIG SYSCONFDIR"mangosd.conf" # define _REALMD_CONFIG SYSCONFDIR"realmd.conf" #endif +#define _FULLVERSION(REVD,REVT,REV) _PACKAGENAME "/" _VERSION(REVD,REVT,REV) " for " _ENDIAN_PLATFORM + #define DEFAULT_PLAYER_LIMIT 100 #define DEFAULT_WORLDSERVER_PORT 8085 //8129 #define DEFAULT_REALMSERVER_PORT 3724 diff --git a/src/tools/gensvnrevision/gensvnrevision.cpp b/src/tools/gensvnrevision/gensvnrevision.cpp index 3533a0bff..daca90119 100644 --- a/src/tools/gensvnrevision/gensvnrevision.cpp +++ b/src/tools/gensvnrevision/gensvnrevision.cpp @@ -18,63 +18,249 @@ #include #include +#include #pragma warning(disable:4996) -int main(int argc, char **argv) +struct RawData { - std::string path; + char rev_str[200]; + char date_str[200]; + char time_str[200]; +}; + +void extractDataFromSvn(FILE* EntriesFile, bool url, RawData& data) +{ + char buf[200]; + + char repo_str[200]; + char num_str[200]; + + fgets(buf,200,EntriesFile); + fgets(buf,200,EntriesFile); + fgets(buf,200,EntriesFile); + fgets(buf,200,EntriesFile); sscanf(buf,"%s",num_str); + fgets(buf,200,EntriesFile); sscanf(buf,"%s",repo_str); + fgets(buf,200,EntriesFile); + fgets(buf,200,EntriesFile); + fgets(buf,200,EntriesFile); + fgets(buf,200,EntriesFile); + fgets(buf,200,EntriesFile); sscanf(buf,"%10sT%8s",data.date_str,data.time_str); + + if(url) + sprintf(data.rev_str,"%s at %s",num_str,repo_str); + else + strcpy(data.rev_str,num_str); +} - if(argc >= 1 && argv[1] ) +void extractDataFromGit(FILE* EntriesFile, std::string path, bool url, RawData& data) +{ + char buf[200]; + fgets(buf,200,EntriesFile); + + char hash_str[200]; + char branch_str[200]; + char url_str[200]; + sscanf(buf,"%s branch %s of %s",hash_str,branch_str,url_str); + + if(url) { - path = argv[1]; - if(path.size() > 0 && (path[path.size()-1]!='/' || path[path.size()-1]!='\\')) - path += '/'; + char* host_str = NULL; + char* acc_str = NULL; + char* repo_str = NULL; + + // parse URL like git@github.com:mangos/mangos + char url_buf[200]; + int res = sscanf(url_str,"git@%s",url_buf); + if(res) + { + host_str = strtok(url_buf,":"); + acc_str = strtok(NULL,"/"); + repo_str = strtok(NULL," "); + } + else + { + int res = sscanf(url_str,"git://%s",url_buf); + if(res) + { + host_str = strtok(url_buf,"/"); + acc_str = strtok(NULL,"/"); + repo_str = strtok(NULL,"."); + } + } + + // can generate nice link + if(res) + sprintf(data.rev_str,"http://%s/%s/%s/commit/%s",host_str,acc_str,repo_str,hash_str); + // unknonw URL format, use as-is + else + sprintf(data.rev_str,"%s at %s",hash_str,url_str); } + else + strcpy(data.rev_str,hash_str); + + time_t rev_time = 0; + // extracting date/time + FILE* LogFile = fopen((path+".git/logs/HEAD").c_str(), "r"); + if(LogFile) + { + while(fgets(buf,200,LogFile)) + { + char buf2[200]; + char new_hash[200]; + int unix_time = 0; + int res2 = sscanf(buf,"%s %s %s %s %i",buf2,new_hash,buf2,buf2,&unix_time,buf2); + if(res2!=5) + continue; + + if(strcmp(hash_str,new_hash)) + continue; + + rev_time = unix_time; + break; + } + + fclose(LogFile); - FILE* EntriesFile = fopen((path+".svn/entries").c_str(), "r"); + if(rev_time) + { + tm* aTm = localtime(&rev_time); + // YYYY year + // MM month (2 digits 01-12) + // DD day (2 digits 01-31) + // HH hour (2 digits 00-23) + // MM minutes (2 digits 00-59) + // SS seconds (2 digits 00-59) + sprintf(data.date_str,"%04d-%02d-%02d",aTm->tm_year+1900,aTm->tm_mon+1,aTm->tm_mday); + sprintf(data.time_str,"%02d:%02d:%02d",aTm->tm_hour,aTm->tm_min,aTm->tm_sec); + } + else + { + strcpy(data.date_str,"Unknown"); + strcpy(data.time_str,"Unknown"); + } + } + else + { + strcpy(data.date_str,"Unknown"); + strcpy(data.time_str,"Unknown"); + } +} + +bool extractDataFromSvn(std::string filename, bool url, RawData& data) +{ + FILE* EntriesFile = fopen(filename.c_str(), "r"); if(!EntriesFile) - EntriesFile = fopen((path+"_svn/entries").c_str(), "r"); + return false; - std::ostringstream newData; + extractDataFromSvn(EntriesFile,url,data); + fclose(EntriesFile); + return true; +} +bool extractDataFromGit(std::string filename, std::string path, bool url, RawData& data) +{ + FILE* EntriesFile = fopen(filename.c_str(), "r"); if(!EntriesFile) + return false; + + extractDataFromGit(EntriesFile,path,url,data); + fclose(EntriesFile); + return true; +} + +std::string generateHeader(char const* rev_str, char const* date_str, char const* time_str) +{ + std::ostringstream newData; + newData << "#ifndef __SVN_REVISION_H__" << std::endl; + newData << "#define __SVN_REVISION_H__" << std::endl; + newData << " #define SVN_REVISION \"" << rev_str << "\"" << std::endl; + newData << " #define SVN_DATE \"" << date_str << "\"" << std::endl; + newData << " #define SVN_TIME \"" << time_str << "\""<< std::endl; + newData << "#endif // __SVN_REVISION_H__" << std::endl; + return newData.str(); +} + +int main(int argc, char **argv) +{ + bool use_url = false; + bool svn_prefered = false; + std::string path; + + // Call: tool {options} [path] + // -g use git prefered (default) + // -s use svn prefered + // -r use only revision (without repo URL) (default) + // -u include repositire URL as commit URL or "rev at URL" + for(int k = 1; k <= argc; ++k) { - newData << "#ifndef __SVN_REVISION_H__" << std::endl; - newData << "#define __SVN_REVISION_H__" << std::endl; - newData << " #define SVN_REVISION \"Unknown\"" << std::endl; - newData << " #define SVN_DATE \"Unknown\"" << std::endl; - newData << " #define SVN_TIME \"Unknown\""<< std::endl; - newData << "#endif // __SVN_REVISION_H__" << std::endl; + if(!argv[k] || !*argv[k]) + break; + + if(argv[k][0]!='-') + { + path = argv[k]; + if(path.size() > 0 && (path[path.size()-1]!='/' || path[path.size()-1]!='\\')) + path += '/'; + break; + } + + switch(argv[k][1]) + { + case 'g': + svn_prefered = false; + continue; + case 'r': + use_url = false; + continue; + case 's': + svn_prefered = true; + continue; + case 'u': + use_url = true; + continue; + default: + printf("Unknown option %s",argv[k]); + return 1; + } } - else + + /// new data extraction + std::string newData; + { - char buf[200]; - int revision; - char date_str[200]; - char time_str[200]; - - fgets(buf,200,EntriesFile); - fgets(buf,200,EntriesFile); - fgets(buf,200,EntriesFile); - fscanf(EntriesFile,"%i",&revision); - fgets(buf,200,EntriesFile); - fgets(buf,200,EntriesFile); - fgets(buf,200,EntriesFile); - fgets(buf,200,EntriesFile); - fgets(buf,200,EntriesFile); - fscanf(EntriesFile,"%10sT%8s",date_str,time_str); - - newData << "#ifndef __SVN_REVISION_H__" << std::endl; - newData << "#define __SVN_REVISION_H__" << std::endl; - newData << " #define SVN_REVISION \"" << revision << "\"" << std::endl; - newData << " #define SVN_DATE \"" << date_str << "\"" << std::endl; - newData << " #define SVN_TIME \"" << time_str << "\""<< std::endl; - newData << "#endif // __SVN_REVISION_H__" << std::endl; - - fclose(EntriesFile); + RawData data; + + bool res = false; + + if(svn_prefered) + { + /// SVN data + res = extractDataFromSvn(path+".svn/entries",use_url,data); + if (!res) + res = extractDataFromSvn(path+"_svn/entries",use_url,data); + // GIT data + if (!res) + res = extractDataFromGit(path+".git/FETCH_HEAD",path,use_url,data); + } + else + { + // GIT data + res = extractDataFromGit(path+".git/FETCH_HEAD",path,use_url,data); + /// SVN data + if (!res) + res = extractDataFromSvn(path+".svn/entries",use_url,data); + if (!res) + res = extractDataFromSvn(path+"_svn/entries",use_url,data); + } + + if(res) + newData = generateHeader(data.rev_str,data.date_str,data.time_str); + else + newData = generateHeader("Unknown", "Unknown", "Unknown"); } + /// get existed header data for compare std::string oldData; if(FILE* HeaderFile = fopen("svn_revision.h","rb")) @@ -90,11 +276,12 @@ int main(int argc, char **argv) fclose(HeaderFile); } - if(newData.str() != oldData) + /// update header only if different data + if(newData != oldData) { if(FILE* OutputFile = fopen("svn_revision.h","wb")) { - fprintf(OutputFile,"%s",newData.str().c_str()); + fprintf(OutputFile,"%s",newData.c_str()); fclose(OutputFile); } } -- 2.11.4.GIT