Executing Shell commands synchronously with grunt.
This plugin requires Grunt ~0.4.0
If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
npm install grunt-wxi-shell --save-dev
Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
grunt.loadNpmTasks('grunt-wxi-shell');
*This plugin was designed to work with Grunt 0.4.x. If you're still using grunt v0.3.x it's strongly recommended that you upgrade.
In your project's Gruntfile, add a section named wxi_shell
to the data object passed into grunt.initConfig()
.
# this is coffeescript
wxi_shell:
one:
options:
cwd: 'components/bootstrap'
returnOutput: true
chained: true
exitSuccess: [0,2]
commands:
[
"make"
,
"make bootstrap"
]
Or JavaScript:
wxi_shell: {
one: {
options: {
cwd: 'components/bootstrap',
returnOutput: true,
chained: true,
exitSuccess: [0, 2]
},
commands: ["make", "make bootstrap"]
}
}
};
-
cwd
:string
cwd
, is where a command should be run. Default is the project root (where Gruntfile is present). This works by puttingcd foo/bar &&
before the command to be run.
You can check out the project at aponxi/npm-execxi.
-
chained
:bool
chained
, which istrue
by default, is an option that can stop running commands after one of them failed. To see if it failed, it checks the exit code of the command that is run. -
returnOutput
:bool
returnOutput
is alsotrue
by default. This is what returns the output in an array, parsing them line by line. I supply with this option because sometimes you might run a command that only returns server's IP address or sometimes you can run a command that just outputs very long lines and a very long text. I added the ability to opt out so that when unnecessary you might set it to false. -
exitSuccess
:Array(int[,int, ...])
exitSuccess
is an array that contains a collection of error codes that you deem to be a successful exit. All programs use different exit codes, sometimes they give a warning and exit with2
. In situations like those, I find myself wanting to allow exiting with2
for that group of commands to be treated as if command was successfully run. This allows the chained commands to continue.By default only
0
exit codes are known to be successful runs. If you supply withexitSuccess
option you will be overriding that. So, by your definition; a program that fails to run can still be a success. -
prettyPrint
:bool
prettyPrint
istrue
by default. This gives the console output its color. Sometimes I find that I need to redirect output into a log file, and don't want the ANSI escape characters such as\033[0;32m
to appear in the log. This will give you a colorless output in console messages. -
verbose
:bool
verbose
istrue
by default. It is used for outputting the command's output as well as giving information on the status (such as "Running Command [1/3]"). There may be times when you just want to quietly utilize the shell command's output. Setting this tofalse
will save you from headaches. I usually turn it off when I'm conducting tests, because if I don't, it's a real mess.
If you specify cwd then the commands are run as cd "your/directory" && ls
if you dont' then they are run in the project root.
CoffeeScript:
"use strict"
module.exports = (grunt) ->
# Project configuration.
grunt.initConfig
# Configuration to be run (and then tested).
wxi_shell:
make:
options:
cwd: 'components/bootstrap'
returnOutput: on
chained: on
exitSuccess: [0,2]
commands:
[
"make"
,
"make bootstrap"
]
clean:
options:
cwd: 'components/bootstrap'
returnOutput: on
chained: on
exitSuccess: [0, 2]
commands:
[
"make clean"
]
# Actually load this plugin's task(s).
grunt.loadTasks "tasks"
# plugin's task(s), then test the result.
grunt.registerTask "clean", ["wxi_shell:clean"]
grunt.registerTask "test", ["clean", "wxi_shell:make"]
# By default
grunt.registerTask "default", ["test"]
Or Javascript:
"use strict";
module.exports = function(grunt) {
grunt.initConfig({
wxi_shell: {
make: {
options: {
cwd: 'components/bootstrap',
returnOutput: true,
chained: true,
exitSuccess: [0, 2]
},
commands: ["make", "make bootstrap"]
},
clean: {
options: {
cwd: 'components/bootstrap',
returnOutput: true,
chained: true,
exitSuccess: [0, 2]
},
commands: ["make clean"]
}
}
});
grunt.loadTasks("tasks");
grunt.registerTask("clean", ["wxi_shell:clean"]);
grunt.registerTask("test", ["clean", "wxi_shell:make"]);
return grunt.registerTask("default", ["test"]);
};
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [grunt][].
- Changed the way commands are executed by using aponxi/npm-execxi
- Tested, and it works.
- Added bootstrap as component to test tasks on it
- Noticed that when sys command returned stderr the sysExec() method threw and error. Disabled that to output only the stdout
- now stderr is outputted via grunt.warn() method.
- Task no longer async
- That fixed the bug #1 that didn't run two tasks that were defined.
- Added ok() after task is done.
- Wrote the basics of the task. It successfully executes shell commands.
I should note that the method I'm using right now is temporary... It was good when I was using grunt-shell however I couldn't do the same thing when defining config dynamically. This method saves stuff to a file and then gets it back which I don't like. Need to fix this.- The method I mentioned is good for build tasks. But not good for usual server side stuff.