Changing the behavior how Quassel Events are processed.
[quassel.git] / src / common / genversion.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-09 by the Quassel Project                          *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) version 3.                                           *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 /** This is called at compile time and generates a suitable version.gen.
22  *  usage: genversion git_root target_file
23  */
24
25 #include <QDebug>
26 #include <QProcess>
27 #include <QString>
28 #include <QStringList>
29 #include <QRegExp>
30 #include <QFile>
31
32 int main(int argc, char **argv) {
33   if(argc < 3) {
34     qFatal("Usage: ./genversion <git_root> <target_file>");
35     return 255;
36   }
37   QString gitroot = argv[1];
38   QString target = argv[2];
39   QString basever, protover, clientneeds, coreneeds, descrver, dirty;
40   QString committish, commitdate;
41
42   // check Git for information if present
43   if(QFile::exists(gitroot + "/.git")) {
44     // try to execute git-describe to get a version string
45     QProcess git;
46     git.setWorkingDirectory(gitroot);
47     #ifdef Q_OS_WIN
48     git.start("cmd.exe", QStringList() << "/C" << "git" << "describe" << "--long");
49     #else
50     git.start("git", QStringList() << "describe" << "--long");
51     #endif
52     if(git.waitForFinished(10000)) {
53       QString descr = git.readAllStandardOutput().trimmed();
54       if(!descr.isEmpty() && !descr.contains("fatal")) {
55         // seems we have a valid git describe string
56         descrver = descr;
57         // check if the workdir is dirty
58         #ifdef Q_OS_WIN
59         git.start("cmd.exe", QStringList() << "/C" << "git" << "diff-index" << "--name-only" << "HEAD");
60         #else
61         git.start("git", QStringList() << "diff-index" << "--name-only" << "HEAD");
62         #endif
63         if(git.waitForFinished(10000)) {
64           if(!git.readAllStandardOutput().isEmpty()) dirty = "*";
65         }
66         // get a full committish
67         #ifdef Q_OS_WIN
68         git.start("cmd.exe", QStringList() << "/C" << "git" << "rev-parse" << "HEAD");
69         #else
70         git.start("git", QStringList() << "rev-parse" << "HEAD");
71         #endif
72         if(git.waitForFinished(10000)) {
73           committish = git.readAllStandardOutput().trimmed();
74         }
75         // Now we do some replacement magic...
76         //QRegExp rxCheckTag("(.*)-0-g[0-9a-f]+\n$");
77         //QRegExp rxGittify("(.*)-(\\d+)-g([0-9a-f]+)\n$");
78         //gitversion.replace(rxCheckTag, QString("\\1%1").arg(dirty));
79         //gitversion.replace(rxGittify, QString("\\1:git-\\3+\\2%1").arg(dirty));
80       }
81     }
82   }
83
84   // parse version.inc
85   QFile verfile(gitroot + "/version.inc");
86   if(verfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
87     QString ver = verfile.readAll();
88
89     QRegExp rxBasever("baseVersion\\s*=\\s*\"(.*)\";");
90     if(rxBasever.indexIn(ver) >= 0)
91       basever = rxBasever.cap(1);
92
93     QRegExp rxProtover("protocolVersion\\s*=\\s*(\\d+)");
94     if(rxProtover.indexIn(ver) >= 0)
95       protover = rxProtover.cap(1);
96
97     QRegExp rxClientneeds("clientNeedsProtocol\\s*=\\s*(\\d+)");
98     if(rxClientneeds.indexIn(ver) >= 0)
99       clientneeds = rxClientneeds.cap(1);
100
101     QRegExp rxCoreneeds("coreNeedsProtocol\\s*=\\s*(\\d+)");
102     if(rxCoreneeds.indexIn(ver) >= 0)
103       coreneeds = rxCoreneeds.cap(1);
104
105     if(committish.isEmpty()) {
106       QRegExp rxCommit("distCommittish\\s*=\\s*([0-9a-f]+)");
107       if(rxCommit.indexIn(ver) >= 0) committish = rxCommit.cap(1);
108     }
109
110     QRegExp rxTimestamp("distCommitDate\\s*=\\s*([0-9]+)");
111     if(rxTimestamp.indexIn(ver) >= 0) commitdate = rxTimestamp.cap(1);
112     verfile.close();
113   }
114
115   // generate the contents for version.gen
116   QByteArray contents = QString("QString buildinfo = \"%1,%2,%3,%4,%5,%6,%7,%8\";\n")
117                                 .arg(basever, descrver, dirty, committish, commitdate, protover, clientneeds, coreneeds)
118                                 .toAscii();
119
120   QFile gen(target);
121   if(!gen.open(QIODevice::ReadWrite | QIODevice::Text)) {
122     qFatal("%s", qPrintable(QString("Could not write %1!").arg(target)));
123     return EXIT_FAILURE;
124   }
125   QByteArray oldContents = gen.readAll();
126   if(oldContents != contents) { // only touch the file if something changed
127     gen.seek(0);
128     gen.resize(0);
129     gen.write(contents);
130     gen.waitForBytesWritten(10000);
131   }
132   gen.close();
133
134   return EXIT_SUCCESS;
135 }