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