1 /++ Utilities for duod.
2  +  Provides tools for checking if the build commands are available and executing them.
3  +/
4 module duod.utilities;
5 import std.array : appender;
6 import std.process : executeShell, pipeShell, Redirect, wait;
7 /// True if the `duo` command is avilable at runtime
8 static bool hasDuo;
9 /// True if the `yuglify` command is avilable at runtime
10 static bool hasYuglify;
11 /// Once per runtime for all threads, checks for the existance of duo and yuglify commands.
12 shared static this () {
13     hasDuo = !executeShell("duo --version").status;
14     hasYuglify = !executeShell("yuglify --version").status;
15 }
16 /++ Get the output of a shell command after passing it some input.
17  +  Params:
18  +      command =   Shell command to run.
19  +      input   =   Input to pass to the command via stdin. Defaults to no input.
20  +  Returns: A string containing all stdout output from the given commands execution.
21  +/
22 string getOutput (string command, string input="") {
23     auto pipes = pipeShell (command, Redirect.stdin | Redirect.stdout);
24     scope (exit) wait (pipes.pid);
25 
26     if (input)
27         pipes.stdin.rawWrite (input);
28     pipes.stdin.close ();
29 
30     auto output = appender!string ();
31     foreach (line; pipes.stdout.byLine ())
32         output ~= line;
33     return output.data;
34 }
35 unittest {
36     assert (getOutput ("echo test") == "test");
37 }
38 /// A simple example for giving a program input programatically and returning the result.
39 unittest {
40     assert (getOutput ("awk '{print tolower($0)}'", "TEXT") == "text");
41 }