1 module config; 2 3 import std.file; 4 import std.path; 5 import std.process : environment; 6 import std..string; 7 8 import core.runtime; 9 10 import ae.sys.d.manager; 11 import ae.sys.paths; 12 import ae.utils.funopt; 13 import ae.utils.meta; 14 import ae.utils.sini; 15 16 static import std.getopt; 17 18 struct Opts 19 { 20 Option!(string, hiddenOption) dir; 21 Option!(string, "Path to the configuration file to use", "PATH") configFile; 22 Switch!("Do not update D repositories from GitHub [local.offline]") offline; 23 Option!(string, "How many jobs to run makefiles in [local.makeJobs]", "N", 'j') jobs; 24 Option!(string[], "Additional configuration. Equivalent to digger.ini settings.", "NAME=VALUE", 'c', "config") configLines; 25 26 Parameter!(string, "Action to perform (see list below)") action; 27 Parameter!(immutable(string)[]) actionArguments; 28 } 29 immutable Opts opts; 30 31 struct ConfigFile 32 { 33 DManager.Config.Build build; 34 DManager.Config.Local local; 35 36 struct App 37 { 38 string[] gitOptions; 39 } 40 App app; 41 } 42 immutable ConfigFile config; 43 44 shared static this() 45 { 46 alias fun = structFun!Opts; 47 enum funOpts = FunOptConfig([std.getopt.config.stopOnFirstNonOption]); 48 void usageFun(string) {} 49 auto opts = funopt!(fun, funOpts, usageFun)(Runtime.args); 50 51 if (opts.dir) 52 chdir(opts.dir.value); 53 54 enum CONFIG_FILE = "digger.ini"; 55 56 if (!opts.configFile) 57 { 58 auto searchDirs = [ 59 string.init, 60 thisExePath.dirName, 61 __FILE__.dirName, 62 ] ~ getConfigDirs() ~ [ 63 buildPath(environment.get("HOME", environment.get("USERPROFILE")), ".digger"), // legacy 64 ]; 65 version (Posix) 66 searchDirs ~= "/etc/"; // legacy 67 68 foreach (dir; searchDirs) 69 { 70 auto path = dir.buildPath(CONFIG_FILE); 71 if (path.exists) 72 { 73 opts.configFile = path; 74 break; 75 } 76 } 77 } 78 79 if (opts.configFile.value.exists) 80 { 81 config = cast(immutable) 82 opts.configFile.value 83 .readText() 84 .splitLines() 85 .parseIni!ConfigFile(); 86 } 87 88 string workDir; 89 if (!config.local.workDir.length) 90 if (exists("repo")) // legacy 91 workDir = "."; 92 else 93 workDir = "work"; // TODO use ~/.cache/digger 94 else 95 workDir = config.local.workDir.expandTilde(); 96 config.local.workDir = workDir.absolutePath().buildNormalizedPath(); 97 98 if (opts.offline) 99 config.local.offline = opts.offline; 100 if (opts.jobs) 101 config.local.makeJobs = opts.jobs; 102 opts.configLines.parseIniInto(config); 103 104 .opts = cast(immutable)opts; 105 106 if (config.app.gitOptions) 107 { 108 import ae.sys.git : Repository; 109 Repository.globalOptions ~= config.app.gitOptions; 110 } 111 } 112 113 @property string subDir(string name)() { return buildPath(config.local.workDir, name); }