Search code examples
node.jslessnpmcruisecontrol.netnant

Using nant to compile LESS via exec


I have a continuous integration server running CruiseControl.NET on Windows Server 2012. The service runs as user ccnet. I have logged on to the server via RDP, opened a command window, and verified the PATH contains C:\Tools\NodeJS.

I installed less globally, since I have a bunch of projects that I'm starting to use LESS in, and for the CI server, it makes sense to just have a single instance of it, rather than have to install it into every single project (the projects don't need it to run locally; we use LessJS in development with flags that remove it when not running in debug mode).

C:\Tools\NodeJS>npm install less -g
C:\Users\ccnet\AppData\Roaming\npm\lessc -> C:\Users\ccnet\AppData\Roaming\npm\node_modules\less\bin\lessc
less@1.7.3 C:\Users\ccnet\AppData\Roaming\npm\node_modules\less
├── graceful-fs@2.0.3
... etc...

I can invoke lessc manually:

C:\CruiseControl\MyProject\private\working>lessc.cmd Website\Content\MyProject.less MyProject.css
C:\CruiseControl\MyProject\private\working>dir MyProject.css
 ...
06/24/2014  11:52 AM           159,145 MyProject.css

But when I try to run this via exec in nant, I get the infamous "module not found":

module.js:340
throw err;
^
Error: Cannot find module 'c:\CruiseControl\MyProject\private\working\node_modules\less\bin\lessc'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.runMain (module.js:492:10)
at process.startup.processNextTick.process._tickCallback (node.js:244:9)

Clearly it's looking in the wrong place for less. But why? My PATH is correct as noted. It works from command line. The workingdir attribute is set to the same folder as in the command-line example.

Is there a better way to set this up for a CI scenario?


Solution

  • I was able to fix the problem by tricking nant.

    Realizing that it ran fine from a command prompt, I simply told nant to invoke a command prompt, with the /c parameter, followed by lessc and all the parameters I wanted to pass to it:

    <exec program="cmd.exe" workingdir="${buildfolder}" failonerror="true">
        <arg line="/c lessc.cmd --clean-css Website\Content\Site.less Website\Content\Site.min.css" />
    </exec>