1 #!/usr/bin/rdmd 2 3 module unit_threaded.finder; 4 5 /** 6 * Implements a program to search a list of directories 7 * for all .d files, then writes and executes a D program 8 * to run all tests contained in those files 9 */ 10 11 import std.stdio; 12 import std.file; 13 import std.exception; 14 import std.array; 15 import std.algorithm; 16 import std.path; 17 import std.conv; 18 import std.process; 19 20 21 /** 22 * args is a filename and a list of directories to search in 23 * the filename is the 1st element, the others are directories. 24 */ 25 int main(string[] args) { 26 enforce(args.length >= 2, "Usage: finder.d <filename> <dir>..."); 27 const fileName = args[1]; 28 const dirs = args[2..$]; 29 writeln("Finding all test cases in ", dirs); 30 31 auto modules = findModuleNames(dirs); 32 auto file = writeFile(fileName, modules, dirs); 33 printFile(file); 34 35 auto rdmdArgs = getRdmdArgs(fileName, dirs); 36 writeln("Executing rdmd like this: ", join(rdmdArgs, ", ")); 37 auto rdmd = execute(rdmdArgs); 38 39 writeln(rdmd.output); 40 return rdmd.status; 41 } 42 43 44 auto findModuleEntries(in string[] dirs) { 45 DirEntry[] modules; 46 foreach(dir; dirs) { 47 enforce(isDir(dir), dir ~ " is not a directory name"); 48 modules ~= array(dirEntries(dir, "*.d", SpanMode.depth)); 49 } 50 return modules; 51 } 52 53 auto findModuleNames(in string[] dirs) { 54 //cut off extension 55 return array(map!(a => replace(a.name[0 .. $-2], dirSeparator, "."))(findModuleEntries(dirs))); 56 } 57 58 private auto writeFile(in string fileName, string[] modules, in string[] dirs) { 59 auto file = File(fileName, "w"); 60 file.writeln("import unit_threaded.runner;"); 61 file.writeln("import std.stdio;"); 62 file.writeln(""); 63 file.writeln("int main(string[] args) {"); 64 file.writeln(` writeln("\nAutomatically generated file");`); 65 file.writeln(" writeln(`Running unit tests from dirs " ~ to!string(dirs) ~ "\n`);"); 66 file.writeln(" return runTests!(" ~ join(map!(a => `"` ~ a ~ `"`)(modules), ", ") ~ ")(args);"); 67 file.writeln("}"); 68 file.close(); 69 70 return File(fileName, "r"); 71 } 72 73 private void printFile(File file) { 74 writeln("Executing this code:\n"); 75 foreach(line; file.byLine()) { 76 writeln(line); 77 } 78 writeln(); 79 file.rewind(); 80 } 81 82 private auto getRdmdArgs(in string fileName, in string[] dirs) { 83 return [ "rdmd" ] ~ join(map!(a => "-I" ~ a)(dirs), ", ") ~ fileName; 84 }