1 module settings; 2 3 import core.stdc.stdlib; 4 import model; 5 import std.range; 6 import std.regex; 7 import std.stdio; 8 version (unittest) import unit_threaded; 9 10 struct Settings 11 { 12 string compiler; 13 string[] depsFiles; 14 bool scan; 15 string[] umlFiles; 16 Regex!char pattern; 17 bool detail; 18 bool transitive; 19 bool dot; 20 string[] targetFiles; 21 bool simplify; 22 string[] unrecognizedArgs; 23 } 24 25 Settings read(string[] args) 26 in (!args.empty) 27 { 28 import std.exception : enforce; 29 import std.getopt : config, defaultGetoptPrinter, getopt, GetoptResult; 30 31 Settings settings; 32 33 with (settings) 34 { 35 string filter; 36 GetoptResult result; 37 38 try 39 { 40 result = getopt(args, 41 config.passThrough, 42 "compiler|c", "Specify the compiler to use", &compiler, 43 "deps", "Read module dependencies from file", &depsFiles, 44 "uml", "Read dependencies from PlantUML file", ¨Files, 45 "filter", "Filter source files matching the regular expression", &filter, 46 "detail", "Inspect dependencies between modules instead of packages", &detail, 47 "transitive|t", "Keep transitive dependencies", &transitive, 48 "dot", "Write dependency graph in the DOT language", &dot, 49 "check", "Check against the PlantUML target dependencies", &targetFiles, 50 "simplify", "Use simplifying assumptions for the check (experimental)", &simplify, 51 ); 52 if (!filter.empty) 53 { 54 enforce(!compiler.empty || !depsFiles.empty, 55 "filter can only be applied to dependencies collected by a compiler"); 56 57 pattern = regex(filter); 58 } 59 } 60 catch (Exception exception) 61 { 62 stderr.writeln("error: ", exception.msg); 63 exit(EXIT_FAILURE); 64 } 65 if (result.helpWanted) 66 { 67 import std.path : baseName; 68 69 writefln("Usage: %s [options] files", args.front.baseName); 70 writeln("Process import dependencies as created by dmd with the --deps switch."); 71 writeln("If no compiler is specified, source files are scanned for (simple) import declarations."); 72 defaultGetoptPrinter("Options:", result.options); 73 exit(EXIT_SUCCESS); 74 } 75 unrecognizedArgs = args.dropOne; 76 } 77 return settings; 78 } 79 80 @("read settings") 81 unittest 82 { 83 const settings = read(["depend", "--deps", "dependencies", "--check", "target"]); 84 85 with (settings) 86 { 87 depsFiles.should.be == ["dependencies"]; 88 targetFiles.should.be == ["target"]; 89 } 90 } 91 92 @("read settings with unrecognized arguments") 93 unittest 94 { 95 const settings = read(["depend", "main.d", "--detail"]); 96 97 with (settings) 98 { 99 unrecognizedArgs.should.be == ["main.d"]; 100 detail.should.be == true; 101 } 102 }