Search code examples
windowsgruntjsdosgrunt-shell

Grunt/Batch : how to execute shell commands within the gruntfile.js directory?


I know this is a common question but all answers I tried didn't work. What's strange is that a friend tried this script on his Windows and actually got the current directory (the one containing the gruntfile.js). I tried to see the differences but I also didn't find any.

module.exports = function(grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        shell: {
            test: {
                command: 'dir'
            }
        }
    });

    grunt.loadNpmTasks('grunt-shell');
};

Here is what I get :

D:\Websites\AUB>grunt shell:test
Running "shell:test" (shell) task
 Volume in drive D is Data
 Volume Serial Number is 6E7B-40AB

 Directory of D:\Websites

04/22/2015  04:53 PM    <DIR>          .
04/22/2015  04:53 PM    <DIR>          ..
04/20/2015  11:04 AM    <DIR>          .sublime
03/30/2015  12:52 PM    <DIR>          .template
04/24/2015  07:55 AM    <DIR>          AUB

I tried to use the trick from this post but the it didn't work (I stay in Websites directory) :

command: 'set WORKING_DIRECTORY=%cd% && dir'

I also tried to find something useful with "Get directory containing the currently executed batch script", but I don't see how to use it since I got errors :

command: 'cd %~dp0 && dir'

which returns :

D:\Websites\AUB>grunt shell:test
Running "shell:test" (shell) task
The system cannot find the path specified.
Warning: Command failed: C:\WINDOWS\system32\cmd.exe /s /c "cd %~dp0 && dir"
The system cannot find the path specified.
 Use --force to continue.

Aborted due to warnings.

As a side-note, any other package I'm using straight from Grunt (clean, copy, rename, uglify, etc) is working just fine and grunt-exec has the same behaviour.


Solution

  • This sounds strange as usually all plugins work relative to your Gruntfile:

    http://gruntjs.com/api/grunt.file

    Note: all file paths are relative to the Gruntfile unless the current working directory is changed with grunt.file.setBase or the --base command-line option.

    You could retrieve the current work manually:

    var cwd process.cwd()
    
    // Or to get a file inside the cwd    
    
    var pathOfGruntfile = require('path').resolve('./Gruntfile.js');
    

    and use it in your Gruntfile:

    module.exports = function(grunt) {
    
        grunt.initConfig({
            pkg: grunt.file.readJSON('package.json'),
            cwd: process.cwd(),
    
            shell: {
                test: {
                    command: 'cd "<%= cwd %>";dir'
                }
            }
        });
    
        grunt.loadNpmTasks('grunt-shell');
    };