We’ve gone to some lengths at work to automate, and have a continuous delivery style pipeline for all things build and deployment related. It’s well on its way, but not ‘perfect’ yet. Maybe perfection isn’t attainable, or maybe when you have a red button on the desk that when pushed does *everything*. None-the-less aiming for perfection will continue to drive us to improve.
So here I wanted to discuss what steps I took to get a nice JSLint Visual Studio plugin to form part of our build process. It was a bit of fussing about getting it to work, and it’s an example of still being imperfect, but for now it serves the build pipeline well enough.
There is an easily accessible Visual Studio plugin called exactly what you would expect “JSLint for Visual Studio 2010” and here is the direct link for it on the VS Gallery for your installation pleasure.
But what about continuous integration?
For us it wasn’t enough, we wanted our build process which runs as psake scripts to fail if JSLint rules were broken.
<Target Name="AfterBuild"> <Message Text="Running jslint..." Importance="Normal" /> <Exec Command=""..\jslint\JSLint.CLI.exe" .\Scripts\ " /> </Target>
So the search for command lines tools began. I found some existing command line tools, some which had more complex dependencies, others which seemed to be more ‘primitive’, i.e. did not report on errors the IDE based JSLint plugin was reporting.
There were 2 main objectives driving the choice of the tool
- Similarity and accuracy to JSLint.com and the Visual Studio extension
- Ease of setup
I then had an idea…
Take the core logic of the Visual Studio extension and wrap it in a very simple console application to execute as part of the build process.
With the approach I took, it seems even option 2 was difficult to achieve (consumed some time), but at least it had the least external dependencies to the other options out there.
The very first step was to obtain and install the VS2010 SDK, as this was an project which referenced many interop assemblies for interacting with the IDE. It needs to be the Service Pack 1 SDK in fact, and here’s a direct link. Once I was able to compile the extension it was then a matter of understanding how it operates and how to access a method to perform the ‘linting‘.
There were 2 major hacks to get access to some inner workings of the extension to operate:
- Making some ‘protected/internal’ methods and properties public
- Modifying where the JSLint logic obtained the settings file from (JSLintOptions.xml).
Locating JSLintOptions.xml proved somewhat difficult at first, as it was tucked away hiding in the Roaming section of my user folder on Windows (\Users\*\AppData\Roaming\). These hacks could greatly benefit from some re-factoring effort if I have ever have the time, or someone else is so inclined. But after an initial attempt to refactor out the most core of logic things fell apart in the land of SDK dependencies, so I rolled back and opted for a less elegant approach which was the 2 hacks listed above.
The logic for the console application is then trivially simple:
- Read .js files.
- Using the JSLinter class method Lint() supply the .js file content/
- Write errors to console
Show me the code!
If you want to see the hacks I had to make to get this to work head on over to this git repository on BitBucket. I offer no warranty it may be fragile so manipulate with caution.
If you just want the command line executable, then it’s built and stored in the repository in the /output folder, if I make any updates to the executable, I’ll also update that executable.
Areas for improvement in the console app:
- Taking path locations as input parameters/external file of locations
- Taking alternate settings files for rules to ignore/include
- General tidyup
The final hiccup is not directly related to the use of the command line tool itself, but building the command line tool from source as part of a more comprehensive-all-inclusive build process. Adding commands in the .csproj file post-build settings was not sufficient. The build and copy of the executable needs run as a directive in the targets ‘afterbuild’ section of the .csproj file.
This led to a conflict between MSBuild and the VS2010 SDK, which was very frustrating and currently isn’t solved yet. The question is up on StackOverflow.