1 module gccbuild.build.common;
2 
3 import gccbuild, scriptlike;
4 
5 /**
6  * type is used to lookup arguments for the command in the component
7  */
8 void runBuildCommands(string[] commands, string[string] extraVars = string[string].init)
9 {
10     auto scriptVars = buildVariables.dup;
11     foreach (key, val; extraVars)
12         scriptVars[key] = val;
13 
14     foreach (cmd; commands)
15     {
16         cmd = cmd.substituteVars(scriptVars);
17         if (!cmd.empty)
18             runCollectLog(cmd);
19     }
20 }
21 
22 string substituteVars(string text, string[string] vars = string[string].init)
23 {
24     size_t numReplaced;
25     do
26     {
27         text = substituteVars(text, vars, numReplaced);
28     }
29     while (numReplaced != 0);
30     return text;
31 }
32 
33 string substituteVars(string text, string[string] vars, out size_t numReplaced)
34 {
35     auto result = appender!string();
36 
37     auto remain = text;
38     numReplaced = 0;
39     while (!remain.empty)
40     {
41         auto parts = remain.findSplit("${");
42         result ~= parts[0];
43         remain = parts[2];
44 
45         if (parts)
46         {
47             parts = remain.findSplit("}");
48             failEnforcec(cast(bool) parts, "Can't find closing } in macro:", text);
49             auto val = parts[0] in vars;
50             failEnforce(val != null, "Couldn't find replacement value for ",
51                 parts[0], " in ", text);
52             result ~= *val;
53             remain = parts[2];
54             numReplaced++;
55         }
56     }
57 
58     return result.data;
59 }
60 
61 /**
62  * 1) Delete old directory
63  * 2) Create directory
64  * 3) chdir into directory
65  */
66 auto prepareBuildDir(Component component)
67 {
68     component.buildFolder.tryRmdirRecurse();
69     component.buildFolder.tryMkdirRecurse();
70     return component.buildFolder.pushCWD();
71 }
72 
73 auto pushCWD(Path dir, bool autoPop = true)
74 {
75     auto saveDir = getcwd();
76     dir.chdir();
77     return RefCounted!(RestoreCWD)(saveDir, autoPop);
78 }
79 
80 struct RestoreCWD
81 {
82 private:
83     Path saveDir;
84     bool autoPop;
85 
86 public:
87      ~this()
88     {
89         if (autoPop)
90             saveDir.chdir();
91     }
92 
93     void popCWD()
94     {
95         saveDir.chdir();
96     }
97 }
98 
99 string updatePathVar(Path additional, bool prepend = true)
100 {
101     auto oldPath = environment["PATH"];
102     string newPath;
103     if (prepend)
104         newPath = additional.toString() ~ ":" ~ oldPath;
105     else
106         newPath = oldPath ~ ":" ~ additional.toString();
107 
108     environment["PATH"] = newPath;
109     yap("Updated path: ", oldPath, " => ", newPath);
110     return oldPath;
111 }
112 
113 void restorePathVar(string val)
114 {
115     yap("Restore path: ", val);
116     environment["PATH"] = val;
117 }