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