Wednesday, 21 January 2015

The Power of AWK: svn log to RPM change history.

For many years I used awk and gawk to just do simple column parsing because it is so good at stripping out the white space. Recently I have begun to use awk to do more complex task. One of these is reading the subversion log and converting it to RPM change log history.

I am using this awk as part of my build system to automatically generate rpm.spec files as one step of my build system for my many projects.
The goal is to turn this
------------------------------------------------------------------------
r4 | royce | 2015-01-21 13:03:49 -0700 (Wed, 21 Jan 2015) | 1 line

New SVN project
------------------------------------------------------------------------
r3 | royce | 2015-01-21 10:13:03 -0700 (Wed, 21 Jan 2015) | 1 line


------------------------------------------------------------------------
r2 | royce | 2015-01-21 10:12:25 -0700 (Wed, 21 Jan 2015) | 1 line


------------------------------------------------------------------------
r1 | royce | 2015-01-21 10:02:31 -0700 (Wed, 21 Jan 2015) | 1 line

First build
------------------------------------------------------------------------


In to this
* Wed Jan 21 2015 Revision r4
- First build
- New SVN project



Below is the awk code.
Save it as the file SvnLog2SpecChangeLog.awk.
Then from your project directory run it as svn log | awk -f SvnLog2SpecChangeLog.awk

BEGIN {
   DI=1;
   LASTDATE="";
}

{
   # print "working on "$0
   if($1 == "------------------------------------------------------------------------") {
      nextrow=0
      # print "split row"
   } else {
      # print "text row"
      if(nextrow > 0) {
         if ($1 == "") {
            # print "Blank row"
            nextrow++;
         } else {
            DOCS[DI++]=$0;
         }
      }
      if(nextrow==0) {
         # print "Revison row also contains date"
         NEWREV=$1;
         NEWDATE=$5;
         nextrow++;
         if(LASTDATE != "") {
            # print "LASTDATE="LASTDATE;
            if((LASTDATE!=NEWDATE) && (DI > 1)) {
               DATECMD="date +\"%a %b %d %Y\" -d"LASTDATE
               DATECMD | getline DATEOUT;               
               printf("* %s Revision %s\n", DATEOUT, LASTREV);
               for (DK in DOCS) {
                  printf("- %s\n", DOCS[DK]);
               }
               printf "\n";
               delete DOCS;
               DI=1
               LASTDATE=NEWDATE;
               LASTREV=NEWREV;
            }
         } else {
            LASTDATE=NEWDATE;
            LASTREV=NEWREV;
         }
      }
   }
}

END {
   DATECMD="date +\"%a %b %d %Y\" -d"LASTDATE
   DATECMD | getline DATEOUT;               
   printf("* %s Revision %s\n", DATEOUT, LASTREV);
   for (DK in DOCS) {
      printf("- %s\n", DOCS[DK]);
   }
   printf "\n";
}

No comments:

Post a Comment