1 module doveralls.sourcefiles; 2 import doveralls.args; 3 4 import std.file, std.conv, std.stdio, std.string, std.array, std.typecons, 5 std.algorithm, std.path; 6 7 // Get an array of all source files and their coverage. 8 auto getSourceFiles( string path ) 9 { 10 CoverallsArgs.SourceFile[] files; 11 12 // Find each source file. 13 foreach( immutable dirEntry; dirEntries( path, "*.d", SpanMode.breadth, true ) ) 14 { 15 // The name of the D source file. 16 string fileName = dirEntry.name.relativePath( path ) 17 .chompPrefix( "./" ); 18 // The name of the corresponding .lst file. 19 string lstName = fileName.replace( "/", "-" ) 20 .replace( "\\", "-" ) 21 .replace( ".d", ".lst" ) 22 .absolutePath( path ); 23 24 // If we don't have coverage info, skip the file. 25 if( !lstName.exists() ) 26 { 27 continue; 28 } 29 30 CoverallsArgs.SourceFile file; 31 file.name = fileName; 32 33 // Get the coverage for each line. 34 foreach( line; File( lstName ).byLine( KeepTerminator.no ) ) 35 { 36 // Ignore the "filename is x% covered" lines. 37 if( line.countUntil( "|" ) == -1 ) 38 { 39 continue; 40 } 41 42 // Get the numbers. 43 auto split = line.split( "|" ); 44 file.source ~= split[ 1..$ ].join( "|" ) ~ "\n"; 45 auto hitCountStr = split[ 0 ].strip(); 46 47 Nullable!uint hit; 48 if( hitCountStr.length ) 49 hit = hitCountStr.to!uint; 50 else 51 hit.nullify(); 52 53 file.coverage ~= hit; 54 } 55 56 files ~= file; 57 } 58 59 return files; 60 }