- Change updaterevision to use git instead of svnversion

This commit is contained in:
Randy Heit 2013-06-22 20:49:38 -05:00
parent 742ecd324b
commit fece189bdb

View file

@ -1,8 +1,9 @@
/* updaterevision.c /* updaterevision.c
* *
* Public domain. This program uses the svnversion command to get the * Public domain. This program uses git commands command to get
* repository revision for a particular directory and writes it into * various bits of repository status for a particular directory
* a header file so that it can be used as a project's build number. * and writes it into a header file so that it can be used for a
* project's versioning.
*/ */
#define _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_NO_DEPRECATE
@ -13,24 +14,41 @@
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
// Used to strip newline characters from lines read by fgets.
void stripnl(char *str)
{
if (*str != '\0')
{
size_t len = strlen(str);
if (str[len - 1] == '\n')
{
str[len - 1] = '\0';
}
}
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char *name; char *name;
char currev[64], lastrev[64], run[256], *rev; char vertag[64], lastlog[64], lasthash[64], run[256], *hash = NULL;
unsigned long urev;
FILE *stream = NULL; FILE *stream = NULL;
int gotrev = 0, needupdate = 1; int gotrev = 0, needupdate = 1;
vertag[0] = '\0';
lastlog[0] = '\0';
if (argc != 3) if (argc != 3)
{ {
fprintf (stderr, "Usage: %s <repository directory> <path to svnrevision.h>\n", argv[0]); fprintf(stderr, "Usage: %s <repository directory> <path to gitinfo.h>\n", argv[0]);
return 1; return 1;
} }
// Use svnversion to get the revision number. If that fails, pretend it's // Use git describe --tags to get a version string. If we are sitting directly
// revision 0. Note that this requires you have the command-line svn tools installed. // on a tag, it returns that tag. Otherwise it returns <most recent tag>-<number of
sprintf (run, "svnversion -cn %s", argv[1]); // commits since the tag>-<short hash>.
if ((name = tempnam(NULL, "svnout")) != NULL) // Use git log to get the time of the latest commit in ISO 8601 format and its full hash.
sprintf(run, "git describe --tags && git log -1 --format=%%ai*%%H", argv[1]);
if ((name = tempnam(NULL, "gitout")) != NULL)
{ {
#ifdef __APPLE__ #ifdef __APPLE__
// tempnam will return errno of 2 even though it is successful for our purposes. // tempnam will return errno of 2 even though it is successful for our purposes.
@ -40,39 +58,41 @@ int main(int argc, char **argv)
system(run) == 0 && system(run) == 0 &&
errno == 0 && errno == 0 &&
fseek(stream, 0, SEEK_SET) == 0 && fseek(stream, 0, SEEK_SET) == 0 &&
fgets(currev, sizeof currev, stream) == currev && fgets(vertag, sizeof vertag, stream) == vertag &&
(isdigit(currev[0]) || (currev[0] == '-' && currev[1] == '1'))) fgets(lastlog, sizeof lastlog, stream) == lastlog)
{ {
stripnl(vertag);
stripnl(lastlog);
gotrev = 1; gotrev = 1;
} }
} }
if (stream != NULL) if (stream != NULL)
{ {
fclose (stream); fclose(stream);
remove (name); remove(name);
} }
if (name != NULL) if (name != NULL)
{ {
free (name); free(name);
} }
if (!gotrev) if (gotrev)
{ {
fprintf (stderr, "Failed to get current revision: %s\n", strerror(errno)); hash = strchr(lastlog, '*');
strcpy (currev, "0"); if (hash != NULL)
rev = currev; {
*hash = '\0';
hash++;
} }
else
{
rev = strchr (currev, ':');
if (rev == NULL)
{
rev = currev;
} }
else if (hash == NULL)
{ {
rev += 1; fprintf(stderr, "Failed to get commit info: %s\n", strerror(errno));
} strcpy(vertag, "<unknown version>");
lastlog[0] = '\0';
lastlog[1] = '0';
lastlog[2] = '\0';
hash = lastlog + 1;
} }
stream = fopen (argv[2], "r"); stream = fopen (argv[2], "r");
@ -86,13 +106,10 @@ int main(int argc, char **argv)
// Read the revision that's in this file already. If it's the same as // Read the revision that's in this file already. If it's the same as
// what we've got, then we don't need to modify it and can avoid rebuilding // what we've got, then we don't need to modify it and can avoid rebuilding
// dependant files. // dependant files.
if (fgets(lastrev, sizeof lastrev, stream) == lastrev) if (fgets(lasthash, sizeof lasthash, stream) == lasthash)
{ {
if (lastrev[0] != '\0') stripnl(lasthash);
{ // Strip trailing \n if (strcmp(hash, lasthash + 3) == 0)
lastrev[strlen(lastrev) - 1] = '\0';
}
if (strcmp(rev, lastrev + 3) == 0)
{ {
needupdate = 0; needupdate = 0;
} }
@ -107,22 +124,22 @@ int main(int argc, char **argv)
{ {
return 1; return 1;
} }
urev = strtoul(rev, NULL, 10); fprintf(stream,
fprintf (stream,
"// %s\n" "// %s\n"
"//\n" "//\n"
"// This file was automatically generated by the\n" "// This file was automatically generated by the\n"
"// updaterevision tool. Do not edit by hand.\n" "// updaterevision tool. Do not edit by hand.\n"
"\n" "\n"
"#define SVN_REVISION_STRING \"%s\"\n" "#define GIT_DESCRIPTION \"%s\"\n"
"#define SVN_REVISION_NUMBER %lu\n", "#define GIT_HASH \"%s\"\n"
rev, rev, urev); "#define GIT_TIME \"%s\"\n",
fclose (stream); hash, vertag, hash, lastlog);
fprintf (stderr, "%s updated to revision %s.\n", argv[2], rev); fclose(stream);
fprintf(stderr, "%s updated to commit %s.\n", argv[2], vertag);
} }
else else
{ {
fprintf (stderr, "%s is up to date at revision %s.\n", argv[2], rev); fprintf (stderr, "%s is up to date at commit %s.\n", argv[2], vertag);
} }
return 0; return 0;