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 immutable ConfigFile config;
37 
38 shared static this()
39 {
40 	alias fun = structFun!Opts;
41 	enum funOpts = FunOptConfig([std.getopt.config.stopOnFirstNonOption]);
42 	void usageFun(string) {}
43 	auto opts = funopt!(fun, funOpts, usageFun)(Runtime.args);
44 
45 	if (opts.dir)
46 		chdir(opts.dir.value);
47 
48 	enum CONFIG_FILE = "digger.ini";
49 
50 	if (!opts.configFile)
51 	{
52 		auto searchDirs = [
53 			string.init,
54 			thisExePath.dirName,
55 			__FILE__.dirName,
56 			] ~ getConfigDirs() ~ [
57 			buildPath(environment.get("HOME", environment.get("USERPROFILE")), ".digger"), // legacy
58 		];
59 		version (Posix)
60 			searchDirs ~= "/etc/"; // legacy
61 
62 		foreach (dir; searchDirs)
63 		{
64 			auto path = dir.buildPath(CONFIG_FILE);
65 			if (path.exists)
66 			{
67 				opts.configFile = path;
68 				break;
69 			}
70 		}
71 	}
72 
73 	if (opts.configFile.value.exists)
74 	{
75 		config = cast(immutable)
76 			opts.configFile.value
77 			.readText()
78 			.splitLines()
79 			.parseIni!ConfigFile();
80 	}
81 
82 	string workDir;
83 	if (!config.local.workDir.length)
84 		if (exists("repo")) // legacy
85 			workDir = ".";
86 		else
87 			workDir = "work"; // TODO use ~/.cache/digger
88 	else
89 		workDir = config.local.workDir.expandTilde();
90 	config.local.workDir = workDir.absolutePath().buildNormalizedPath();
91 
92 	if (opts.offline)
93 		config.local.offline = opts.offline;
94 	if (opts.jobs)
95 		config.local.makeJobs = opts.jobs;
96 	opts.configLines.parseIniInto(config);
97 
98 	.opts = cast(immutable)opts;
99 }
100 
101 @property string subDir(string name)() { return buildPath(config.local.workDir, name); }