print_git_revision.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /* -*- mode:c; indent-tabs-mode:nil; c-basic-offset:2 -*-
  2. * Author: Travis Cross <tc@traviscross.com>
  3. */
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <sys/wait.h>
  9. #include <time.h>
  10. static int show_unclean = 0;
  11. static int sys(char *buf, int buflen, char *cmd) {
  12. int i, p[2];
  13. if (pipe(p)) return 255;
  14. if (!(i=fork())) {
  15. close(p[0]);
  16. dup2(p[1],1);
  17. close(p[1]);
  18. execlp("sh","sh","-c",cmd,NULL);
  19. } else {
  20. int s, x=0;
  21. close(p[1]);
  22. waitpid(i,&s,0);
  23. if (!(WIFEXITED(s))) return 255;
  24. if (WEXITSTATUS(s)) return WEXITSTATUS(s);
  25. if (buf) {
  26. while (buflen>1 && (x=read(p[0],buf,buflen-1))>0) buf+=x,buflen-=x;
  27. close(p[0]);
  28. if (x<0) return 255;
  29. *buf=0;
  30. } else close(p[0]);
  31. }
  32. return 0;
  33. }
  34. static int sys1(char *buf, int buflen, char *cmd) {
  35. int r; char *c;
  36. if ((r=sys(buf,buflen,cmd))) return r;
  37. if ((c=strstr(buf,"\n"))) *c=0;
  38. return 0;
  39. }
  40. static int print_version(void) {
  41. char xver[256], xdate[256], xfdate[256], xcommit[256];
  42. time_t xdate_t; struct tm *xdate_tm;
  43. if ((sys1(xdate,sizeof(xdate),"git log -n1 --format='%ct' HEAD"))) return 1;
  44. xdate_t=(time_t)atoi(xdate);
  45. if (!(xdate_tm=gmtime(&xdate_t))) return 1;
  46. strftime(xfdate,sizeof(xfdate),"%Y%m%dT%H%M%SZ",xdate_tm);
  47. if ((sys1(xcommit,sizeof(xcommit),"git rev-list -n1 --abbrev=10 --abbrev-commit HEAD")))
  48. return 1;
  49. snprintf(xver,sizeof(xver),"+git~%s~%s",xfdate,xcommit);
  50. if (show_unclean && (sys(NULL,0,"git diff-index --quiet HEAD"))) {
  51. char buf[256], now[256]; time_t now_t=time(NULL); struct tm *now_tm;
  52. if (!(now_tm=gmtime(&now_t))) return 1;
  53. strftime(now,sizeof(now),"%Y%m%dT%H%M%SZ",now_tm);
  54. snprintf(buf,sizeof(buf),"%s+unclean~%s",xver,now);
  55. strncpy(xver,buf,sizeof(xver));
  56. }
  57. printf("%s\n",xver);
  58. return 0;
  59. }
  60. static int print_human_version(void) {
  61. char xver[256], xdate[256], xfdate[256], xcommit[256];
  62. time_t xdate_t; struct tm *xdate_tm;
  63. if ((sys1(xdate,sizeof(xdate),"git log -n1 --format='%ct' HEAD"))) return 1;
  64. xdate_t=(time_t)atoi(xdate);
  65. if (!(xdate_tm=gmtime(&xdate_t))) return 1;
  66. strftime(xfdate,sizeof(xfdate),"%Y-%m-%d %H:%M:%SZ",xdate_tm);
  67. if ((sys1(xcommit,sizeof(xcommit),"git rev-list -n1 --abbrev=7 --abbrev-commit HEAD")))
  68. return 1;
  69. snprintf(xver,sizeof(xver),"git %s %s",xcommit,xfdate);
  70. if (show_unclean && (sys(NULL,0,"git diff-index --quiet HEAD"))) {
  71. char buf[256], now[256]; time_t now_t=time(NULL); struct tm *now_tm;
  72. if (!(now_tm=gmtime(&now_t))) return 1;
  73. strftime(now,sizeof(now),"%Y-%m-%d %H:%M:%SZ",now_tm);
  74. snprintf(buf,sizeof(buf),"%s unclean %s",xver,now);
  75. strncpy(xver,buf,sizeof(xver));
  76. }
  77. printf("%s\n",xver);
  78. return 0;
  79. }
  80. int main(int argc, char **argv) {
  81. if (argc > 1 && !strcasecmp(argv[1],"-h"))
  82. return print_human_version();
  83. else
  84. return print_version();
  85. }