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 }