Add a wrapper program for running linters which cannot receive stdin input on Windows.
This commit is contained in:
parent
2f86a92ecb
commit
4489514e4b
6 changed files with 112 additions and 7 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
/init.vim
|
||||
/doc/tags
|
||||
.*
|
||||
*.obj
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
1. [Guidelines](#guidelines)
|
||||
2. [Creating Pull Requests](#pull-requests)
|
||||
3. [Creating Pull Requests](#compiling)
|
||||
|
||||
<a name="guidelines"></a>
|
||||
|
||||
|
@ -40,6 +41,21 @@ table and list.
|
|||
# 2.2. Adding New Options
|
||||
|
||||
If you add new options to the plugin, make sure to document those new options in the [README.md](README.md) file, and also
|
||||
in the [help file](doc/ale.txt). Follow the format of other options in each. Global options should appear in the README
|
||||
in the [help file](doc/ale.txt). Follow the format of other options in each. Global options should appear in the README
|
||||
file, and in the relevant section in the help file, and options specific to a particular linter should go in the section
|
||||
for that linter.
|
||||
|
||||
<a name="compiling"></a>
|
||||
|
||||
# 3. Compiling the Windows stdin wrapper
|
||||
|
||||
To compile the stdin wrapper program for Windows, when updating the D program, you will need to compile the program with
|
||||
[LDC](https://github.com/ldc-developers/ldc) in release mode. Download and install the Community edition of Visual Studio
|
||||
from [the Visual Studio website](https://www.visualstudio.com/downloads/) first before installing LDC. LDC typically comes in
|
||||
a ZIP you can just extract somewhere.
|
||||
|
||||
Make sure to compile with the 32-bit architecture flag, otherwise the EXE will not run on 32-bit machines.
|
||||
|
||||
```
|
||||
ldc2 -m32 -Oz -release stdin_wrapper.d -of=stdin-wrapper.exe
|
||||
```
|
||||
|
|
12
README.md
12
README.md
|
@ -30,11 +30,11 @@ name. That seems to be the fairest way to arrange this table.
|
|||
| Bourne Shell | [-n flag](http://linux.die.net/man/1/sh), [shellcheck](https://www.shellcheck.net/) |
|
||||
| C | [gcc](https://gcc.gnu.org/) |
|
||||
| CoffeeScript | [coffeelint](https://www.npmjs.com/package/coffeelint) |
|
||||
| CSS | [csslint](http://csslint.net/)^ |
|
||||
| Cython (pyrex filetype) | [cython](http://cython.org/)^ |
|
||||
| CSS | [csslint](http://csslint.net/) |
|
||||
| Cython (pyrex filetype) | [cython](http://cython.org/) |
|
||||
| D | [dmd](https://dlang.org/dmd-linux.html)^ |
|
||||
| Fortran | [gcc](https://gcc.gnu.org/) |
|
||||
| Haskell | [ghc](https://www.haskell.org/ghc/)^ |
|
||||
| Haskell | [ghc](https://www.haskell.org/ghc/) |
|
||||
| HTML | [tidy](http://www.html-tidy.org/) |
|
||||
| JavaScript | [eslint](http://eslint.org/), [jscs](http://jscs.info/), [jshint](http://jshint.com/) |
|
||||
| JSON | [jsonlint](http://zaa.ch/jsonlint/) |
|
||||
|
@ -44,9 +44,9 @@ name. That seems to be the fairest way to arrange this table.
|
|||
| SASS | [sass-lint](https://www.npmjs.com/package/sass-lint) |
|
||||
| SCSS | [sass-lint](https://www.npmjs.com/package/sass-lint), [scss-lint](https://github.com/brigade/scss-lint) |
|
||||
| Scala | [scalac](http://scala-lang.org) |
|
||||
| TypeScript | [tslint](https://github.com/palantir/tslint)^ |
|
||||
| Vim | [vint](https://github.com/Kuniwak/vint)^ |
|
||||
| YAML | [yamllint](https://yamllint.readthedocs.io/)^ |
|
||||
| TypeScript | [tslint](https://github.com/palantir/tslint) |
|
||||
| Vim | [vint](https://github.com/Kuniwak/vint) |
|
||||
| YAML | [yamllint](https://yamllint.readthedocs.io/) |
|
||||
|
||||
*^ Supported only on Unix machines via a wrapper script.*
|
||||
|
||||
|
|
|
@ -13,6 +13,10 @@ function! s:FindWrapperScript()
|
|||
let path = expand(parent . '/' . 'stdin-wrapper')
|
||||
|
||||
if filereadable(path)
|
||||
if has('win32')
|
||||
return path . '.exe'
|
||||
endif
|
||||
|
||||
return path
|
||||
endif
|
||||
endfor
|
||||
|
|
BIN
stdin-wrapper.exe
Normal file
BIN
stdin-wrapper.exe
Normal file
Binary file not shown.
84
stdin_wrapper.d
Normal file
84
stdin_wrapper.d
Normal file
|
@ -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]);
|
||||
}
|
Reference in a new issue