diff options
author | w0rp <devw0rp@gmail.com> | 2016-10-07 21:33:16 +0100 |
---|---|---|
committer | w0rp <devw0rp@gmail.com> | 2016-10-07 21:33:16 +0100 |
commit | 4489514e4b3edb4376040ed217c95b5ccb489bb0 (patch) | |
tree | 3b379280548e209414e46ae43dc45329d798d8c9 /stdin_wrapper.d | |
parent | 2f86a92ecbd276b694d0a33db954e7e148b733a8 (diff) | |
download | ale-4489514e4b3edb4376040ed217c95b5ccb489bb0.zip |
Add a wrapper program for running linters which cannot receive stdin input on Windows.
Diffstat (limited to 'stdin_wrapper.d')
-rw-r--r-- | stdin_wrapper.d | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/stdin_wrapper.d b/stdin_wrapper.d new file mode 100644 index 00000000..8714bc2a --- /dev/null +++ b/stdin_wrapper.d @@ -0,0 +1,84 @@ +// Author: w0rp <devw0rp@gmail.com> +// Description: This file provides a D program for implementing +// the stdin-wrapper on Windows. + +import std.algorithm; +import std.array; +import std.file; +import std.process; +import std.stdio; +import std.path; + +@safe +auto createTemporaryFilename(string fileExtension) { + import std.uuid; + + string filename; + + do { + const randomPart = randomUUID().toString.replace("-", "_"); + + filename = buildPath(tempDir(), "ale_" ~ randomPart ~ fileExtension); + } while (exists(filename)); + + return filename; +} + +@trusted +void readStdinToFile(ref File tempFile) { + stdin.byChunk(4096).copy(tempFile.lockingTextWriter()); +} + +// Expand program names like "csslint" to "csslint.cmd" +// D is not able to perform this kind of expanstion in spawnProcess +@safe +string expandedProgramName(string name) { + auto extArray = environment["PATHEXT"].split(";"); + + foreach(pathDir; environment["PATH"].split(";")) { + foreach(extension; extArray) { + const candidate = buildPath(pathDir, name ~ extension); + + if (exists(candidate)) { + return candidate; + } + } + } + + // We were given a full path for a program name, so use that. + if (exists(name)) { + return name; + } + + return ""; +} + +@trusted +int runLinterProgram(string[] args) { + const expandedName = expandedProgramName(args[0]); + + writeln(expandedName); + + if (expandedName) { + return wait(spawnProcess([expandedName] ~ args[1..$])); + } + + return 1; +} + +@safe +int main(string[] args) { + const filename = createTemporaryFilename(args[1]); + + auto tempFile = File(filename, "w"); + + scope(exit) { + tempFile.close(); + remove(filename); + } + + readStdinToFile(tempFile); + tempFile.close(); + + return runLinterProgram(args[2..$] ~ [filename]); +} |