1 /**
2 Copyright: Auburn Sounds 2015-2018.
3 License: All Rights Reserved.
4 */
5 module utils;
6
7 import std.process;
8 import std.string;
9 import std.file;
10 import std.path;
11
12 import consolecolors;
13
14 void info(string msg)
15 {
16 cwritefln("info: %s".white, escapeCCL(msg));
17 }
18
19 void warning(string msg)
20 {
21 cwritefln("warning: %s".yellow, escapeCCL(msg));
22 }
23
24 void error(string msg)
25 {
26 cwritefln("error: %s".red, escapeCCL(msg));
27 }
28
29 class ExternalProgramErrored : Exception
30 {
31 public
32 {
33 @safe pure nothrow this(int errorCode,
34 string message,
35 string file =__FILE__,
36 size_t line = __LINE__,
37 Throwable next = null)
38 {
39 super(message, file, line, next);
40 this.errorCode = errorCode;
41 }
42
43 int errorCode;
44 }
45 }
46
47
48 void safeCommand(string cmd)
49 {
50 cwritefln("$ %s".cyan, cmd);
51 auto pid = spawnShell(cmd);
52 auto errorCode = wait(pid);
53 if (errorCode != 0)
54 throw new ExternalProgramErrored(errorCode, format("Command '%s' returned %s", cmd, errorCode));
55 }
56
57 // Currently this only escapes spaces...
58 string escapeShellArgument(string arg)
59 {
60 version(Windows)
61 {
62 return `"` ~ arg ~ `"`;
63 }
64 else
65 return arg.replace(" ", "\\ ");
66 }
67
68 /// Recursive directory copy.
69 /// https://forum.dlang.org/post/n7hc17$19jg$1@digitalmars.com
70 /// Returns: number of copied files
71 int copyRecurse(string from, string to)
72 {
73 // from = absolutePath(from);
74 // to = absolutePath(to);
75
76 if (isDir(from))
77 {
78 mkdirRecurse(to);
79
80 auto entries = dirEntries(from, SpanMode.shallow);
81 int result = 0;
82 foreach (entry; entries)
83 {
84 auto dst = buildPath(to, entry.name[from.length + 1 .. $]);
85 result += copyRecurse(entry.name, dst);
86 }
87 return result;
88 }
89 else
90 {
91 std.file.copy(from, to);
92 return 1;
93 }
94 }
95