GruntJs:how to bypass a task in grunt build process - gruntjs

is there a way to bypass the task in the grunt build process using options??
In below example i want to bypass the test and do only package and buildArtifacts tasks.
Example:
grunt.registerTask('test', [
'karma:continuous' ,
'e2e-test'
]);
grunt.registerTask('build', function (target) {
grunt.task.run(['force:on','package','test','force:off','buildArtifacts']);
});

Afterall its a .js file, i think you can write a custom js function to edit what you want to run based on "option"

As earlier said, you can edit the Gruntfile.js to create a new task.
grunt.registerTask('build-bypass-test', ['package','buildArtifacts']);
On command link just execute the below command.
grunt build-bypass-test
Updated Answer
var test = grunt.option('test');
grunt.registerTask('build',function() {
if(test) {
grunt.log.writeln('Running without test');
grunt.task.run(['force:on','package','force:off','buildArtifacts']);
} else {
grunt.log.writeln('Running with test');
grunt.task.run(['force:on','package','test','force:off','buildArtifacts']);
}
});
Hope this helps you. :)

Related

Global grunt task error handling

Grunt will output exit codes and that's fantastic for scripts executing grunt tasks but I want the ability to handle failed grunt tasks after grunt completes them.
I was expecting to find some type of error handling function that I could set in the initConfig somewhere but I don't see anything. Likewise, even a "finally" function would work nicely.
Basically, I have an alias task that is a set of tasks that I execute and one of them temporarily changes content of a file and I write the content back to disk after everything completes. I want to still be able to at least attempt to write the content back to disk even if tasks after the mutation occurs, fail.
Something to this affect would be great.
grunt.initConfig({
onError: function (error) {
// execute my file cleanup
},
// this is essentially a "finally" function that executes once grunt
// finishes with all tasks.
onComplete: function () {
// execute my file cleanup
}
});
I am pretty sure, that there is no such feature. But it is a popular request: 1, 2.
What can be done by now? You can write a custom grunt-task, something like the following:
var errorCb = function() { callback(); }
var doneCb = function() { callback(); }
grunt.initConfig({
task_runner: {
before: ...,
beforeEach: ...,
run: ['other_task1', 'other_task2'],
after: ...,
afterEach: ...,
onError: errorCb,
onComplete: doneCb
},
other_tasks: { ... }
});
And register your task:
grunt.registerTask('task_runner', "Tasks' lifecycle", function(task, message) {
// foreach task in tasks: grunt.task.run(task)
...
// except(`grunt.util.error`)
});
As I know, there is no beatiful way to get the result of a task run. So here comes the monkey-patching. It is possible to hook these functions: grunt.fail and grunt.log.error.
Here's some inspiration: 1, 2. Also, have a look at grunt-then.
All in all, I can not say that it is an easy task. I hope someday Grunt will have events (by now: "Note that Grunt doesn't yet emit any events, but can still be useful in your own tasks.").
P.S. Have you considered Gulp for your project?
P.S.S If you are going to write your custom task, feel free to ask me for a contribution.

How to Gulp-Watch Multiple files?

I have something like this:
gulp.task('default', ['css', 'browser-sync'] , function() {
gulp.watch(['sass/**/*.scss', 'layouts/*.css'], function() {
gulp.run('css');
});
});
but it does not work, because it watches two directories, the sass and the layouts directory for changes.
How do I make it work, so that gulp watches anything that happens inside those directories?
gulp.task('default', ['css', 'browser-sync'] , function() {
gulp.watch(['sass/**/*.scss', 'layouts/**/*.css'], ['css']);
});
sass/**/*.scss and layouts/**/*.css will watch every directory and subdirectory for any changes to .scssand .css files that change. If you want to change that to any file make the last bit *.*
You can write a watch like this.
gulp.task('watch', function() {
gulp.watch('path/to/file', ['gulp task name for css/scss']);
gulp.watch('path/to/file', ['gulp task name for js']);
});
This way you can set up as many tasks as you want via the file path of what you want to watch followed by the name of the task you created. Then you can write your default like this:
gulp.task('default', ['gulp task name for css/scss', 'gulp task name for js']);
If you want to simply watch for various file changes, then just watch files using glob like *.css in your task.
One problem that has arisen for multiple people (including me) is that adding a gulp.filter outside of the task causes gulp.watch to fail after the first pass. So if you have something like this:
var filter = gulpFilter(['fileToExclude.js'])
gulp.task('newTask', function(){ ...
Then you need to change it to:
gulp.task('newTask', function(){
var filter = gulpFilter(['fileToExclude.js'])
The filter has to be included in the task function. Hope that helps someone.
This works for me (Gulp 4):
function watchSass() {
return gulp.watch(sassGlob, { ignoreInitial: false }, buildCss)
}
function watchImages() {
return gulp.watch(imagesGlob, copyImages)
}
exports.watch = gulp.parallel(watchSass, watchImages)
#A.J Alger's answer worked for me when using Gulp v3.x.
But starting with Gulp 4, The following appears to work for me.
Notice that each task has to return a value or call "done()". The main task in this example is 'watchSrc' which in parallel calls the other tasks.
gulp.task('watchHtml', function(){
return watch('src/**/*.html', function () {
gulp.src('src/**/*')
.pipe(gulp.dest(BUILD_DIR))
})
})
gulp.task('watchJS', function(){
return watch('src/**/*.js', 'devJS')
})
gulp.task('watchCSS', function(){
return watch(['src/**/*.css', 'src/**/*.scss'], 'buildStyles')
})
gulp.task('watchSrc', gulp.parallel('watchHtml', 'watchJS', 'watchCSS'), function(done)
{
done()
})
As of gulp 4, this is another option:
const { watch, series, parallel } = require('gulp');
function watchTask(cb) {
// this will execute all task on any changes
watch(['src/**/*'],
series(parallel(jsTask, htmlTask, assetTask),
));
// this will run specific task based on file type or folder
watch(['src/**/*.js'], series(jsTask));
watch(['src/**/*.html'], series(htmlTask));
watch(['assets/**/*'], series(assetTask));
}
exports.default = series(parallel(jsTask, htmlTask, assetTask), watchTask);
If you convert your tasks into functions
function task1(){
return gulp...
...
}
There are then 2 useful methods you can use:
GULP.SERIES will run the tasks synchronously
gulp.task('default', gulp.series(task1,task2));
GULP.PARALLEL will run them asynchronously
gulp.task('default', gulp.parallel(task1,task2));

How can I skip a grunt task if a directory is empty

I'm using grunt-contrib's concat and uglify modules to process some javascript. Currently if src/js/ is empty, they will still create an (empty) concat'd file, along with the minified version and a source map.
I want to task to detect if the src/js/ folder is empty before proceeding, and if it is, then the task should skip (not fail). Any ideas how to do this?
The solution may not be the prettiest, but could give you an idea. You'll need to run something like npm install --save-dev glob first. This is based on part of the Milkshake project you mentioned.
grunt.registerTask('build_js', function(){
// get first task's `src` config property and see
// if any file matches the glob pattern
if (grunt.config('concat').js.src.some(function(src){
return require('glob').sync(src).length;
})) {
// if so, run the task chain
grunt.task.run([
'trimtrailingspaces:js'
, 'concat:js'
, 'uglify:yomama'
]);
}
});
A gist for comparison: https://gist.github.com/kosmotaur/61bff2bc807b28a9fcfa
With this plugin:
https://www.npmjs.org/package/grunt-file-exists
You can check file existence. (I didn't try, but the source looks like supporting grunt expands. (*, ** ...)
For example like this::
grunt.initConfig({
fileExists: {
scripts: ['a.js', 'b.js']
},
});
grunt.registerTask('conditionaltask', [
'fileExists',
'maintask',
]);
But maybe if the file doesn't exist it will fail with error instead of simple skip.
(I didn't test it.)
If this is a problem you can modify a bit the source of this plugin to run the related task if the file exists:
The config:
grunt.initConfig({
fileExists: {
scripts: ['a.js', 'b.js'],
options: {tasks: ['maintask']}
},
});
grunt.registerTask('conditionaltask', [
'fileExists',
]);
And you should add this:
grunt.task.run(options.tasks);
In this file:
https://github.com/alexeiskachykhin/grunt-file-exists/blob/master/tasks/fileExists.js
after this line:
grunt.log.ok();
Maybe this is just a more up-to-date answer as the others are more than a year old, but you don't need a plugin for this; you can use grunt.file.expand to test if files matching a certain globbing pattern exist.
Update of #Kosmotaur's answer (path is just hard-code here though for simplicity):
grunt.registerTask('build_js', function(){
// if any file matches the glob pattern
if (grunt.file.expand("subdir/**/*.js").length) { /** new bit here **/
// if so, run the task chain
grunt.task.run([
'trimtrailingspaces:js'
, 'concat:js'
, 'uglify:yomama'
]);
}
});

Prevent `grunt-watch` from looping when there is a syntax error in less files?

I'm using grunt-watch to re-build my less style sheets:
watch: {
less: {
files: ['media/less/**/*.less'],
tasks: ['less'],
options: {
atBegin: true,
spawn: false
}
}
}
But if there is a syntax error in any of the .less files, the task just loops, trying to re-build the .less files every second… which makes debugging fairly difficult, because the error messages scroll past very quickly.
Is there any way fix that, so grunt-watch will only re-run the task once the .less files have been changed again?
This is using:
grunt#0.4.2
grunt-contrib-less#0.8.3
grunt-contrib-watch#0.5.3
I think the issue you're describing is this one, which was fixed in master but hasn't yet been released (as of 2013/12/17).
Well, for debugging purposes you could do a simple envelope of the less task with a custom task:
grunt.registerTask('myless', 'my less task', function() {
// do whatever debugging you want and stop the loop if needed.
grunt.task.run(['less']);
});
Then use your myless task in the watch.
UPDATE:
the idea is that since any repeated call to less now goes through your code - you can do whatever needed to either provide a more concrete output or preven repeated calls if failing is "desired" outcome and should fail, but not loop.
UPDATE 2:
Something like this:
watch: {
`less`: {
files: ['**/*.less'], // or whatever the extension is
tasks: ['myless'] // your envelope task
}
}
var flag;
grunt.registerTask('myless', 'My LESS task', function() {
if(flag === true) {
// if you are here - it means watch just invoked you repeatedly
// do whatever you need to analyze the issue (includig running an additional task)
flag = false;
return; // you exit task without altering any less files again -
// that should NOT trigger watch again
} else {
flag = true;
grunt.task.run(['less']);
}
});

Is it possible to run a task after the watch task?

I have a PHP-based project that won't run on grunt-php. Instead, I use grunt-exec to run my MAMP server for development.
exec: {
serverup: {
command: '/Applications/MAMP/bin/start.sh'
},
serverdown: {
command: '/Applications/MAMP/bin/stop.sh'
}
}
In my custom development task, I run the MAMP start script just before my watch task. Then, I'm trying to stop the MAMP server after I've exited the watch task.
grunt.registerTask('default', ['jshint', 'concat', 'compass:dev', 'exec:serverup', 'watch', 'exec:serverdown']);
However, if I exit the task with Ctrl-C, the exec:serverdown task never seems to run. Is there any way to make this work? Since the server never goes down, that port is tied up until I manually run the stop script, and I get errors if I try to run the default task again before bringing it down.
If not, is there some other way I could accomplish the same thing?
You could listen on SIGINT and run the script:
var exec = require('child_process').exec;
process.on('SIGINT', function () {
exec('/Applications/MAMP/bin/stop.sh', function () {
process.exit();
});
});
module.exports = function (grunt) {};

Resources