dmce

dmce compares code coverage to changed lines in a git repo
git clone https://noulin.net/git/dmce.git
Log | Files | Refs | LICENSE

dmce.c (3337B)


      1 //
      2 
      3 #include "libsheepyObject.h"
      4 
      5 #define internal static
      6 
      7 #include <stdlib.h>
      8 #include <stdio.h>
      9 
     10 int MAIN(int ARGC, char** ARGV);
     11 
     12 int argc; char **argv;
     13 
     14 #ifndef unitTest
     15 // Remove main when running the unit tests
     16 #define MAIN   main
     17 #endif
     18 int MAIN(int ARGC, char** ARGV) {
     19   smallArrayt *list = NULL;
     20 
     21   argc = ARGC; argv = ARGV;;// dmce, did my code execute
     22   // checks if the code not yet commited has been executed during the unit tests
     23   // dmce uses gcov to get the code coverage
     24 
     25   // Steps
     26   // list file in current folder
     27   // consider gcov files
     28   // load gcov file
     29   // store source code coverage in coverage list
     30   // find out source filename
     31   // create git diff command
     32   // list diff for the complete code in source file
     33   // analyze the diff and code coverage
     34 
     35 
     36   // list file in current folder
     37   list = walkDirO(".");
     38 
     39   forEachSmallArray(list, e) {
     40     castS(g, duplicateO(e));
     41 
     42     // consider gcov files
     43     // TODO use basename instead of path in g
     44     if (hasG(g, ".gcov") && !hasG(g, "./.")) {
     45       createAllocateSmallArray(source);
     46       createAllocateSmallArray(coverage);
     47       createAllocateSmallArray(rawCov);
     48 
     49       // load gcov file
     50       time_t gcovTime = getModificationTimeG(g);
     51       // store source code coverage in coverage list
     52       readFileG(rawCov, ssGet(g));
     53       forEachSmallArray(rawCov, l) {
     54         castS(L, l);
     55         smallArrayt *line = splitG(L, ":");
     56         if (lenG(line) >= 3) {
     57           pushNFreeG(coverage, duplicateO(L));
     58         }
     59         terminateO(line);
     60         free(l);
     61       }
     62       terminateO(rawCov);
     63 
     64       // find out source filename
     65       sliceG(g,0,-5);
     66       printf("--- %s\n\n", ssGet(g));
     67       printf("\n");
     68       time_t time = getModificationTimeG(g);
     69       if (gcovTime < time) {
     70         logE("Gcov file for %s is old.", ssGet(g));
     71         XFailure;
     72       }
     73       // create git diff command
     74       char *cmd;
     75       cmd      = appendS("git diff --no-prefix -U100000 ", ssGet(g)); {
     76       // list diff for the complete code in source file
     77       execO(cmd, source, NULL);
     78       free(cmd);
     79 
     80       // analyze the diff and code coverage
     81       int status = 0;
     82       int lines  = 0;
     83       forEachSmallArray(source, l) {
     84         castS(L, l);
     85 
     86         if (!status) {
     87           if (getG(L,0,0) == '@' && getG(L,0,1) == '@') {
     88             // found diff start
     89             status = 1;
     90         }
     91           }
     92         else {
     93           // find code not yet commited
     94           if (getG(L,0,0) == '+') {
     95             //print 'src: %d - %s', lines, *l
     96             //print 'cov: %d - %s', lines+5, coverage[lines+5]
     97             // check new lines have been executed
     98             smallStringt *s = getG(coverage, rtSmallStringt, lines+5);
     99 	    if (not s) logXFailure(".c and .c.gcov files probably don't match");
    100             if (hasG(s, "#####:")) {
    101               // print new code that has not been executed in the unit tests
    102               printf("%10d: %s", lines, ssGet(L));
    103               printf("\n");
    104               //print '        cov: %s\n', coverage[lines+5]
    105             }
    106             free(s);
    107           }
    108           if (getG(L,0,0) != '-') {
    109             // ignore removed lines
    110             lines++;
    111         }
    112           }
    113         free(l);
    114       }
    115 
    116       terminateO(source);
    117       terminateO(coverage);
    118     }
    119       }
    120     terminateO(g);
    121     free(e);
    122   }
    123 
    124   terminateO(list);
    125 }