I recently (recently being about 3 AM this morning) decided that I'd try and replace my Arch Linux/VMWare setup with something a lot less resource intensive, Windows new Subsystem for Linux (WSL). For those of you that aren't familiar, WSL is not a VM. Rather it is a special Ubuntu distro built into Windows 10 that can be activated by using
bash.exe. Microsoft has been making big strides recently to become a more open-source company, and WSL has gone a long way towards bringing devs back to Windows.
Now it's definitely not a perfect solution. For now there is no built-in way to interface with Windows window manager, which means to get GUI applications running you have to install an X server and hack around. Certainly not ideal. Even with this hacky solution, a lot of editors just don't work right. Atom doesn't even launch.
So the solution would appear obvious; just install the Windows binary of Atom and use it that way. That would be a fine solution if Atom (or VScode, Sublime, or any other editor) had baked in support for WSL, but they don't. When you install a linter, like linter-php for example, it expects there to be a binary available in the Windows path and has no clue that WSL even exists. That means that I can do all the hacking around I want with PHP in the terminal, but if I want to lint code in Atom I have to install the PHP binary in Windows using something like Chocolatey. Obviously having 2 of the same, or slightly different, binary is not ideal.
So now that you see the problem, let's talk about the solution. (These tests were being done with
linter-php, but the steps would be similar for any plugin in Atom that requires access to a binary)
WSL recently had an update that included a "interop" for bash. This allows you to enter a command like
bash.exe -c "php -v" into command prompt, have it execute the command
php -v, and return the result without you ever having to enter the shell itself. This seemed like it would be the perfect solution. So I opened up Atom's settings, went to the settings for
linter-php, and changed the "PHP Executable Path" to
bash.exe -c "php". Now either because of the necessary quotes around
PHP interfering with the passing of arguments, or just because the "PHP Executable Path" doesn't accept arguments, this didn't work.
So I thought to myself, 'how can I proxy a request to WSL's PHP as a single command?' A Windows batch file!
So I set about writing a simple batch file and this is the result I got
@echo off bash.exe -c "php %*"
Just 2 lines of code! The first line turns
echo off so that the command isn't echoed back. The second line simply executes
bash.exe passing in the
-c argument for the interop and running
php with any included arguments.
To test if it works I changed my "PHP Executable Path" in the
linter-php settings to
C:\\Users\\myusername\\path\\to\\php.bat, opened up a PHP file, screwed something up, and bam! The red squiggly of death was there to greet me instead of an annoying error popup. I have never been so happy to see a linter error.
As a result of this journey I've decided to create a Git repo to host batch files such as this. It's located at https://github.com/watzon/wsl-proxy.