1

I would like to have access to the many available plugins and tasks in the grunt ecosystem to make my life easier, but I would like control over when and how each task is run. Most importantly, I want a way to run grunt tasks programmatically instead of running grunt from the command line in a folder with a Gruntfile. So I started poking around grunt-cli and grunt for a "way in."

From the source code of GruntJS:

// Expose the task interface. I've never called this manually, and have no idea
// how it will work. But it might.
grunt.tasks = function(tasks, options, done) {
    ...

As you can see, Mr. Allman cautions us about the interface... my question is, has anyone gotten this to work?

My experiments, so far, have led me to believe the best way to programmatically control grunt is by mimicking the command line call with a child process:

$ npm install grunt-cli //notice no -g flag

// From runner.js
var exec =require('child_process').exec

exec('node_modules/.bin/grunt-cli tasks to run', {
  cwd: 'path/to/directory/with/a/gruntfile'
}, function() { /* do stuff here */ });

This seems dirty so I'm thinking about simply writing my own task-runner that exposes an interface for grunt tasks. However, I don't want to dup work if someone has had success with grunt.tasks() despite Mr. Allman's warnings.

srquinn
  • 10,134
  • 2
  • 48
  • 54

2 Answers2

2

The obvious answer seems like it should be write a grunt task to do whatever you want to do :)

Then you can use grunt.task.run() to control other grunt tasks: http://www.gruntjs.org/article/grunt_task.html

You can also update their configs dynamically before running them very easily by messing with grunt.config

There's also this answer which may answer your question: How can I run a grunt task from within a grunt task?

Also check out grunt.task.start() which is not publicy documented, but it seems to kick off all of the tasks https://github.com/gruntjs/grunt/blob/master/lib/util/task.js#L246 (hat tip: @jibsales)

Community
  • 1
  • 1
Jamund Ferguson
  • 16,721
  • 3
  • 42
  • 50
  • 1
    While this is good for running grunt tasks from within grunt tasks, I'm trying to avoid running `grunt` from the command line to initiate everything. I'm updating my question so this is more clear. – srquinn Nov 27 '13 at 17:19
  • What specifically are you trying to avoid? Is it installing grunt globally? grunt is just a node program.... – Jamund Ferguson Nov 27 '13 at 17:26
  • Hmmm... on second thought the links in your answer might have got the right synapses firing now. Hang tight, tests are needed. – srquinn Nov 27 '13 at 17:38
  • You may even be able to just do `var grunt = require('grunt'); grunt.task.run()....` – Jamund Ferguson Nov 27 '13 at 17:48
  • Thats exactly what I was figuring... still testing – srquinn Nov 27 '13 at 17:51
  • Probably will have to do something like call `grunt.loadTasks()` or `grunt.loadNPMTasks` first, but I bet it will work – Jamund Ferguson Nov 27 '13 at 17:53
  • Hazaa!!! You were semi-correct. `grunt.task.run()` doesn't run the task, only queues it. You have to call `grunt.task.start()` just as `grunt.tasks()` does here: https://github.com/gruntjs/grunt/blob/master/lib/grunt.js#L155 – srquinn Nov 27 '13 at 18:02
  • 2
    I'll mark your answer correct if you add the need to call `grunt.task.start()` – srquinn Nov 27 '13 at 18:05
  • Here we are a full year later and I'm needed this answer myself :-p Will update, thanks @jibsales – Jamund Ferguson Jan 13 '15 at 04:02
-1

Maybe this would help you to write a custom handler : https://www.npmjs.com/package/rungrunttask

Usage details

var RunGruntTask = require('rungrunttask').RunGruntTask;
var taskname = 'some grunt task such as backup database every 24hours';
RunGruntTask(taskname);
Gautam Anand
  • 19
  • 1
  • 3