1 module commands.justbuild;
2 import util.config, util.statman, util.inform;
3 import std.file;
4 
5 auto execAndDiff(const BuildSpecification buildThis)
6 {
7     import std.datetime;
8     import std.process;
9     import std.range, std.algorithm;
10 
11     const now = Clock.currTime();
12     executeShell(buildThis.exactCommand);
13     return dirEntries(getcwd, SpanMode.depth).filter!(x => !x.isDir && timeLastModified(x) > now);
14 }
15 
16 void elfData(T)(T x, string fileName)
17 {
18     import std.conv : to;
19     import elf;
20 
21     ELF tmp = ELF.fromFile(fileName);
22     auto head = tmp.header;
23     auto elfStuff = x.category("ELF");
24     with (elfStuff)
25     {
26         setAtom("machineISA", head.machineISA);
27         setAtom("objectFileType", head.objectFileType);
28         foreach (section; tmp.sections)
29         {
30             with (elfStuff.category("sections").category(section.name))
31             {
32                 setAtom("type", section.type.to!string);
33                 setAtom("address", section.address);
34                 setAtom("offset", section.offset);
35                 setAtom("flags", cast(ubyte) section.flags);
36                 setAtom("size", section.size);
37                 setAtom("entry size", section.entrySize);
38                 
39             }
40         }
41     }
42 
43 }
44 
45 auto command(inout BuildSpecification build, string[] args)
46 {
47 
48     import std.getopt;
49     import std.format : format;
50     import std.stdio;
51     import std.range;
52     import std.algorithm;
53     import std.datetime;
54     import elf;
55 
56     const dir = getcwd;
57 
58     bool readElf = false;
59 
60     getopt(args, "elf|readElf", &readElf);
61 
62     inform(format!"Building %s in %s\n"(build.exactCommand, dir));
63 
64     import std.file;
65 
66     auto rawOutput = execAndDiff(build);
67 
68     auto stats = StatManager("build - " ~ build.name);
69 
70     auto data = stats.category("resultingFiles");
71 
72     stats.setAtom("builtIn", dir);
73     auto output = rawOutput.array.sort!((x, y) => x.timeLastModified < y.timeLastModified);
74     SysTime lastTime;
75     //There is actually some output
76     if(output.length) 
77         lastTime = output[0].timeLastModified;
78     foreach (file; output)
79     {
80         
81         import std.path : baseName;
82 
83         with (data.category(file.name.baseName))
84         {
85             import std.conv : to;
86 
87             setAtom("sizeBytes", file.size);
88             setAtom("sizeKiloBytes", (cast(float) file.size) / 1024f);
89             setAtom("timeLastModified", file.timeLastModified.to!string);
90             setAtom("approxBuildTime_msecs", (file.timeLastModified - lastTime).total!"msecs");
91             //No elf on windows, no post on sundays
92         }
93         if(readElf)
94             elfData(data.category(file.name.baseName), file.name);
95     }
96     
97     return stats.gcDup;
98 }