aboutsummaryrefslogtreecommitdiff
path: root/source/util.d
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2019-06-07 12:21:15 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2019-06-07 12:21:15 -0400
commit2a2175b43561869deb11bcb963aa2718f638c4ed (patch)
tree93f9e9ca95936ac0092ca646c26f6d55fb31f22a /source/util.d
parent58985ee9e484c45314af16392d37b180929ce668 (diff)
downloaddm-2a2175b43561869deb11bcb963aa2718f638c4ed.tar.gz
Add comments
Diffstat (limited to 'source/util.d')
-rw-r--r--source/util.d197
1 files changed, 194 insertions, 3 deletions
diff --git a/source/util.d b/source/util.d
index 3624d88..0e3fc18 100644
--- a/source/util.d
+++ b/source/util.d
@@ -10,9 +10,16 @@ import std.path;
import std.conv : to;
+/// MAXCOLS refers to terminal width
enum byte MAXCOLS = 80;
+/**
+ Print a wordwrapped string encapsulated by `ch`
+Params:
+ ch = ASCII character to create border
+ s = string to print
+ */
void banner(const char ch, string s) {
string ruler;
byte i = 0;
@@ -36,17 +43,54 @@ void banner(const char ch, string s) {
}
-static auto getenv(string[string] base=null, string preface=null) {
+/**
+ Dump the parent shell runtime environment and convert it into an associative
+ array
+
+Params:
+ base = use an existing mapping as the base environment
+ preface = command to execute prior to dumping the environment
+
+Returns:
+ an associative array containing the runtime environment
+
+Example:
+---
+import std.stdio;
+import util;
+
+void main()
+{
+ string exfile = "example.sh";
+ File(exfile, "w+").write("export EXAMPLE_FILE=parsed\n");
+ scope(exit) exfile.remove;
+
+ auto myenv = getenv();
+ myenv["EXAMPLE"] = "works";
+
+ auto myenv2 = getenv(myenv);
+ writeln(myenv2["EXAMPLE"]);
+
+ auto myenv3 = getenv(myenv2, "source example.sh");
+ writeln(myenv3["EXAMPLE"]);
+ writeln(myenv3["EXAMPLE_FILE"]);
+}
+---
+ */
+string[string] getenv(string[string] base=null, string preface=null) {
const char delim = '=';
char delim_line = '\n';
string[string] env;
string cmd = "env";
+ /// Under GNU we have the option to use nul-terminated strings, which means
+ /// we can safely parse awful pairs generated by `env-modules`
version (linux) {
cmd ~= " -0";
delim_line = '\0';
}
+ /// Untested
version (Windows) {
cmd = "set";
delim_line = "\r\n";
@@ -78,10 +122,54 @@ static auto getenv(string[string] base=null, string preface=null) {
}
+/**
+ Produce a single-quoted string
+
+Params:
+ s = string to quote
+
+Returns:
+ single-quoted string
+
+Example:
+---
+import std.stdio;
+import util;
+
+void main()
+{
+ writeln(safe_spec("single-quoted"));
+ // 'single-quoted'
+}
+---
+ */
string safe_spec(string s) {
return "'" ~ s ~ "'";
}
+
+/**
+ Produces conda/pip compatible installation arguments
+
+Params:
+ specs = array of string arguments
+
+Returns:
+ string of single-quoted arguments
+
+Example:
+---
+import std.stdio;
+import util;
+
+void main()
+{
+ string[] arguments = ["a", "b", "c"];
+ writeln(safe_install(arguments));
+ // 'a' 'b' 'c'
+}
+---
+ */
string safe_install(string[] specs) {
string[] result;
foreach (record; specs) {
@@ -90,6 +178,30 @@ string safe_install(string[] specs) {
return result.join(" ");
}
+
+/**
+ Produces `conda`/`pip` compatible installation arguments by splitting on white
+ space
+
+ Params:
+ specs = a string containing arguments
+
+ Returns:
+ string of single quoted arguments
+
+ Example:
+ ---
+ import std.stdio;
+ import util;
+
+ void main()
+ {
+ string arguments = "a b c";
+ writeln(safe_install(arguments));
+ // 'a' 'b' 'c'
+ }
+ ---
+ */
string safe_install(string specs) {
string[] result;
foreach (record; specs.split(" ")) {
@@ -99,7 +211,19 @@ string safe_install(string specs) {
}
+/**
+ pytest emits invalid junit, so this rewrites the local configuration
+ file (i.e. `setup.cfg`, `pytest.ini`, etc) to include the proper
+ `junit_family` settings.
+
+Params:
+ filename = path to configuration file
+
+Returns:
+ new configuration file contents as string
+ */
string pytest_xunit2(string filename) {
+ // Generate the requested file if need be
if (!filename.exists) {
auto dummy = File(filename, "w+");
dummy.write("");
@@ -139,6 +263,7 @@ string pytest_xunit2(string filename) {
return data ~ format("\n%s\n%s\n", section, cfgitem);
}
+ // figure out when/where we should write our revisions to the config
foreach (rec; splitLines(data)) {
if (!has_section) {
break;
@@ -163,6 +288,16 @@ string pytest_xunit2(string filename) {
}
+/**
+ Find all occurences of character in a string
+
+Params:
+ s = string to read
+ ch = character to find
+
+Returns:
+ array of offsets
+ */
ulong[] indexOfAll(string s, char ch) {
ulong[] result;
for (ulong i = 0; i < s.length; i++) {
@@ -174,6 +309,7 @@ ulong[] indexOfAll(string s, char ch) {
}
+/// Unused
string expander(string[string] aa, string name, char delim = '$') {
string s = aa[name].dup;
ulong[] needles = indexOfAll(s, delim);
@@ -200,25 +336,57 @@ string expander(string[string] aa, string name, char delim = '$') {
}
+
+/**
+ Perform variable interpolation on a string given a named environment
+
+Params:
+ aa = assoc. array to use (i.e. runtime environment)
+ str = string to scan for variables
+ delim = character to trigger parsing variable
+
+Returns:
+ string with variables replaced
+
+Note:
+ When a variable cannot be mapped the variable text in the string is not
+ modified.
+
+Example:
+---
+import std.stdio;
+import util;
+
+void main()
+{
+ string[string] aa = ["my_var": "example"];
+ string my_str = "This is the ${my_var}.";
+ writeln(interpolate(aa, my_str));
+}
+---
+ */
string interpolate(string[string]aa, string str, char delim = '$') {
import std.ascii;
string s = str.dup;
ulong[] needles = indexOfAll(s, delim);
string[] found;
+ // scan any indicies we've found
foreach (needle; needles) {
string tmp = "";
+ // trigger variable parsing on delimiter
for (ulong i = needle; i < s.length; i++) {
if (s[i] == delim) continue;
- else if (s[i] == '{' || s[i] == '}')
+ else if (s[i] == '{' || s[i] == '}') // ${} also supported
continue;
- else if (!s[i].isAlphaNum && s[i] != '_' )
+ else if (!s[i].isAlphaNum && s[i] != '_') // unusable, die
break;
tmp ~= s[i];
}
found ~= tmp;
}
+ // rewrite string with substitutions
foreach (match; found) {
foreach (pair; aa.byPair) {
if (pair.key != match)
@@ -232,6 +400,29 @@ string interpolate(string[string]aa, string str, char delim = '$') {
}
+/**
+ Produce a short/compact version
+
+Params:
+ vrs = version string
+
+Returns:
+ shortened version string
+
+Example:
+---
+import std.stdio;
+import util;
+
+void main()
+{
+ writeln(short_version("3.6.8"));
+ // 36
+ writeln(short_version("2.7.66"));
+ // 27
+}
+---
+ */
string short_version(string vrs) {
string tmp = vrs.dup;
tmp = tmp.replace(".", "");