1 module utils;
2 
3 import std.process;
4 import std..string;
5 import std.file;
6 import std.path;
7 
8 import colorize;
9 
10 string white(string s) @property
11 {
12     return s.color(fg.light_white);
13 }
14 
15 string grey(string s) @property
16 {
17     return s.color(fg.white);
18 }
19 
20 string cyan(string s) @property
21 {
22     return s.color(fg.light_cyan);
23 }
24 
25 string green(string s) @property
26 {
27     return s.color(fg.light_green);
28 }
29 
30 string yellow(string s) @property
31 {
32     return s.color(fg.light_yellow);
33 }
34 
35 string red(string s) @property
36 {
37     return s.color(fg.light_red);
38 }
39 
40 void info(string msg)
41 {
42     cwritefln("info: %s".white, msg);
43 }
44 
45 void warning(string msg)
46 {
47     cwritefln("warning: %s".yellow, msg);
48 }
49 
50 void error(string msg)
51 {
52     cwritefln("error: %s".red, msg);
53 }
54 
55 class ExternalProgramErrored : Exception
56 {
57     public
58     {
59         @safe pure nothrow this(int errorCode,
60                                 string message,
61                                 string file =__FILE__,
62                                 size_t line = __LINE__,
63                                 Throwable next = null)
64         {
65             super(message, file, line, next);
66             this.errorCode = errorCode;
67         }
68 
69         int errorCode;
70     }
71 }
72 
73 
74 void safeCommand(string cmd)
75 {
76     cwritefln("$ %s".cyan, cmd);
77     auto pid = spawnShell(cmd);
78     auto errorCode = wait(pid);
79     if (errorCode != 0)
80         throw new ExternalProgramErrored(errorCode, format("Command '%s' returned %s", cmd, errorCode));
81 }
82 
83 // Currently this only escapes spaces...
84 string escapeShellArgument(string arg)
85 {
86     version(Windows)
87     {
88         return `"` ~ arg ~ `"`;
89     }
90     else
91         return arg.replace(" ", "\\ ");
92 }
93 
94 /// Recursive directory copy.
95 /// https://forum.dlang.org/post/n7hc17$19jg$1@digitalmars.com
96 /// Returns: number of copied files
97 int copyRecurse(string from, string to, bool verbose)
98 {
99   //  from = absolutePath(from);
100   //  to = absolutePath(to);
101 
102     if (isDir(from))
103     {
104         if (verbose) cwritefln("    => Create directory %s".green, to);
105         mkdirRecurse(to);
106 
107         auto entries = dirEntries(from, SpanMode.shallow);
108         int result = 0;
109         foreach (entry; entries)
110         {
111             auto dst = buildPath(to, entry.name[from.length + 1 .. $]);
112             result += copyRecurse(entry.name, dst, verbose);
113         }
114         return result;
115     }
116     else
117     {
118         if (verbose) cwritefln("    => Copy %s to %s".green, from, to);
119         std.file.copy(from, to);
120         return 1;
121     }
122 }