1 /**
2 Copyright 2019 Mark Fisher
3 
4 Permission is hereby granted, free of charge, to any person obtaining a copy of
5 this software and associated documentation files (the "Software"), to deal in
6 the Software without restriction, including without limitation the rights to
7 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8 of the Software, and to permit persons to whom the Software is furnished to do
9 so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 SOFTWARE.
21 **/
22 module dxx.devconst;
23 
24 private import std.json;
25 
26 public import dxx.constants;
27 
28 version(DXX_Bootstrap) {
29   //private import aermicioi.aedi;
30   private import std.variant;
31   //static Container __c;
32   static Variant[string] __p;
33 
34   template _(T) {
35     auto _(string v) {
36       //return __c.locate!T(v);
37       if(auto x = v in __p) {
38         return x.get!T;
39       }
40       static if (is(T == bool)) {
41         return false;
42       } else {
43         return null;
44       }
45     }
46   }
47 
48   auto __(string v) {
49     return _!string(v);
50   }
51   auto ___(string v) {
52     return _!(string[])(v);
53   }
54 
55   template CWD() {
56     alias CWD=()=>runtimeConstants.curDir;
57   }
58   template APPDIR() {
59     alias APPDIR=()=>runtimeConstants.appDir;
60   }
61   template APPS() {
62     alias APPS=()=>___("build.apps");
63   }
64 
65   template PROJECTS() {
66     alias PROJECTS=()=>___("build.projects");
67   }
68 
69   template UTPROJECTS() {
70     alias UTPROJECTS=()=>___("ut.projects");
71   }
72   template ARCH() {
73     alias ARCH=()=>__("build.arch");
74   }
75   template BUILD() {
76     alias BUILD=()=>__("build.build");
77   }
78   template DEBUGS() {
79     alias DEBUGS=()=>___("build.debugs");
80   }
81   template VERSIONS() {
82     alias VERSIONS=()=>___("build.versions");
83   }
84 
85   template FORCE() {
86     alias FORCE=()=>_!bool("build.force");
87   }
88 
89   template PARALLEL() {
90     alias PARALLEL=()=>_!bool("build.parallel");
91   }
92 
93   template NODEPS() {
94     alias NODEPS=()=>_!bool("build.nodeps");
95   }
96 
97   template EXEPATH() {
98     alias EXEPATH =()=>runtimeConstants.appFileName;
99   }
100   template EXEDIR() {
101     alias EXEDIR = ()=>runtimeConstants.appDir;
102   }
103   template APPARG() {
104     alias APPARG = ()=>runtimeConstants.argsApp;
105   }
106   template ARGPASS() {
107     alias ARGPASS = ()=>cast(string[])runtimeConstants.argsAppPassthrough.dup;
108   }
109   template PID() {
110   	alias PID = ()=>runtimeConstants.appPid;
111   }
112 
113   string[] toStringArray(const(JSONValue)[] ar) {
114     string[] res;
115     foreach(v;ar) {
116       debug {
117         import std.experimental.logger;
118         debug(DXX_Developer) {
119           sharedLog.trace("array ",v);
120         }
121       }
122       res ~= v.str;
123     }
124     return res;
125   }
126   //void load(T : DocumentContainer!X, X...)(T container) {
127   //void load(T)(T container) {
128   void load(const(JSONValue) __j) {
129   	//with (container.configure) { // Create a configuration context for config container
130     import std..string : indexOf;
131 
132     void _register(_T)(string name,string fqn="",const(JSONValue) j=__j) {
133         debug {
134           import std.experimental.logger;
135           debug(DXX_Developer) {
136             sharedLog.trace("reg ",fqn," ",name);
137           }
138         }
139         auto inx = name.indexOf('.');
140         if(inx != -1) {
141           string n = name[0..inx];
142           if(const(JSONValue)* x = n in j) {
143             _register!_T(name[inx+1..$],n ~ ".",*x);
144             return;
145           }
146         }
147         if(const (JSONValue)* val = name in j) {
148           name = fqn ~ name;
149           static if(is(_T == int)) {
150             //register!_T(val.integer,name);
151             __p[name] = Variant(val.integer);
152           } else if(is(_T == bool)) {
153             //register!_T(val.boolean,name);
154             __p[name] = Variant(val.boolean);
155           } else if (is(_T == string)) {
156             //register!_T(val.str,name);
157             __p[name] = Variant(val.str);
158           } else if (is(_T == string[])) {
159             string[] vals;
160             vals = toStringArray(val.array);
161             //register!(string[])(vals,name);
162             __p[name] = Variant(vals);
163           }
164         } else {
165           static if(is(_T == int)) {
166             __p[name] = Variant(-1);
167           } else if(is(_T == bool)) {
168             __p[name] = Variant(false);
169           } else if (is(_T == string)) {
170             __p[name] = Variant("");
171           } else if (is(_T == string[])) {
172               string[] x = [];
173             __p[name] = Variant(x);
174           }
175         }
176     }
177     //with(__j) {
178   		_register!string("build.arch"); // Define `protocol` property of type `string`
179   		_register!string("build.build");
180 
181       _register!(string[])("build.debugs");
182       _register!(string[])("build.versions");
183       _register!(string)("build.config");
184       _register!(string[])("build.projects");
185       _register!(string[])("build.apps");
186       _register!(string)("build.tag");
187       _register!(bool)("build.force");
188       _register!(bool)("build.parallel");
189       _register!(bool)("build.nodeps");
190 
191       _register!string("ut.arch"); // Define `protocol` property of type `string`
192   		_register!string("ut.build");
193       _register!(string[])("ut.debugs");
194       _register!(string[])("ut.versions");
195       _register!(string)("ut.config");
196       _register!(string[])("ut.projects");
197   	//}
198   }
199 
200   auto loadJson(string pathOrData) {
201     import std.file : exists, readText;
202     if (pathOrData.exists) {
203       debug(trace) trace("Loading json from ", pathOrData);
204       pathOrData = pathOrData.readText();
205     }
206     return parseJSON(pathOrData);
207   }
208 
209   static this() {
210     /* auto c = container(
211       //singleton,
212       //prototype,
213       argument,
214       env,
215       //xml("config.xml"),
216       json("resources/dale.json"),
217       json("resources/dale-default.json"),
218       //yaml("config.yaml"),
219       //sdlang("config.sdlang")
220     ); */
221     import std.file : exists, readText;
222     auto __j = loadJson("resources/dale.json");
223 
224     load(__j);
225 
226     /*auto c = container(prototype);
227 
228 	  foreach (subcontainer; c) {
229 		    subcontainer.load;
230     }
231     __c = c;*/
232 
233   }
234 
235   string[] buildDubArgs(string cmd)(string root=".") {
236     string[] args;
237     args ~= [
238       cmd,
239       "--root="~root
240     ];
241     static if ("build" == cmd || "run" == cmd || "test" == cmd) {
242       import std.conv : to;
243       args ~= [
244         "--arch="~ARCH,
245         "--build="~BUILD,
246         //"--config="~CONFIG,
247         "--force="~FORCE.to!string,
248         "--nodeps="~NODEPS.to!string,
249         "--parallel="~PARALLEL.to!string
250       ];
251       foreach(dbg;DEBUGS) {
252           args ~= [ "--debug="~dbg ];
253       }
254       foreach(vers;VERSIONS) {
255           args ~= [ "--version="~vers ];
256       }
257     }
258     return args;
259   }
260 }