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 }