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