Skip to content

Instantly share code, notes, and snippets.

@jbmoelker
Last active January 3, 2016 00:39
Show Gist options
  • Save jbmoelker/8384456 to your computer and use it in GitHub Desktop.
Save jbmoelker/8384456 to your computer and use it in GitHub Desktop.
The Grunt Task Wizard prompts user all available grunt tasks, and asks the user for optional arguments to run the task with. When prompt closes `task-wizard:run-task` is executed, which runs the selected task with the given arguments.This way users don't need to know tasks by heart, just type: `grunt task-wizard` to get started. To make it even …
var grunt = require('grunt');
/**
* Prompt, utility to configure and run grunt-prompt.
* @see https://github.com/dylang/grunt-prompt
*
* @example
* var prompt = require('prompt');
* prompt('create-component')
* .addQuestion({
* config: 'myTask.newComponentName',
* type: 'input',
* message: 'Enter name for new component'
* })
* .addQuestion({
* config: 'myTask.newComponentDependencies',
* type: 'checkbox',
* message: 'Select dependencies',
* choices: [ ... ]
* })
* .open(['create-component','register-component']);
* // opens prompt with two questions and
* // runs create-component and register-component after,
* // in which `myTask` config is available.
*/
/**
* This utility helps to construct a Prompt using grunt-promt:
* @see https://github.com/dylang/grunt-prompt#grunt-prompt-
* @param {String} name name of task to run after prompt
* @constructor
*/
function Prompt (name) {
'use strict';
this.name = name;
this.questions = [];
}
/**
* Add a question to this prompt. Each question can be
* configured using the same options as in grunt-prompt:
* @see https://github.com/dylang/grunt-prompt#options
* @param {Object} question
*/
Prompt.prototype.addQuestion = function (question) {
'use strict';
var prompt = this;
prompt.questions.push(question);
return prompt;
};
/**
* Creates config options and registers prompt under its name.
* @returns {Prompt}
*/
Prompt.prototype.register = function () {
'use strict';
var prompt = this;
var config = {
options: {
questions: prompt.questions
}
};
grunt.config('prompt.' + prompt.name, config);
return prompt;
};
/**
* Opens prompt with constructed questions and runs task
* corresponding with the prompt's name.
* @param {Array} [nextTasks] Tasks to run after prompt.
* By default runs task with name of this prompt.
*/
Prompt.prototype.open = function (nextTasks) {
'use strict';
var prompt = this;
prompt.register();
var tasks = nextTasks || [prompt.name];
tasks.unshift('prompt:' + prompt.name);
grunt.task.run(tasks);
};
/**
* Create and return a new prompt with given name.
* @param {String} name
* @returns {Prompt}
*/
function createPrompt (name) {
'use strict';
return new Prompt(name);
}
module.exports = createPrompt;
var prompt = require('prompt');
/**
* Task Wizard prompts user all available grunt tasks, and
* asks the user for optional arguments to run the task with.
* When prompt closes `task-wizard:run-task` is executed,
* which runs the selected task with the given arguments.
* This way users don't need to know tasks by heart, just
* type: `grunt task-wizard` to get started. To make it even
* easier for your users you can make this the default task
* by setting `grunt.registerTask('default', ['task-wizard']);`
* at the end of you `Gruntfile.js`.
*/
module.exports = function (grunt) {
'use strict';
grunt.registerTask(
'task-wizard',
'Execute any grunt task using wizard (prompt).',
/**
* Just follow the wizard after running `task-wizard` without any arguments.
* The wizard will set taskWizard config properties based on answers and will
* run itself again for the next step. So don't bother entering task params manually.
* @param {String} [action] Action to perform.
* Expects wither 'run-task' or undefined.
* If no argument is given prompts to select task
*/
function (action) {
var wizard = grunt.config('taskWizard');
/**
* Return pretty list of tasks to choose from with task name and info.
* @returns {Array} tasks to choose from
*/
function getTaskChoices () {
var tasks = grunt.task._tasks;
return Object.keys(tasks)
.sort()
.map(function (name) {
var task = tasks[name];
if (task.multi) {
name += '*';
}
return {
name: (name.magenta + ': ' + task.info),
value: task.name
};
});
}
/**
* Builds a prompt for 'select-task' with questions to
* * select task category
* * select task to execute (per category)
* * enter arguments (if not project task)
* Open the prompt and run selected task after completion.
*/
function promptForTask () {
prompt('select-task')
.addQuestion({
config: 'taskWizard.selectedTaskName',
type: 'list',
message: 'Select a task to execute',
choices: getTaskChoices()
})
.addQuestion({
config: 'taskWizard.taskArguments',
type: 'input',
message: 'Enter argument(s)'
})
.open(['task-wizard:run-task']);
}
/**
* Get selected task and arguments stored in grunt config by prompt.
* Run selected task with these arguments.
*/
function runTaskWithArguments () {
var command = wizard.selectedTaskName;
command += (wizard.taskArguments) ? ':' + wizard.taskArguments : '';
grunt.task.run(command);
}
if(action === 'run-task'){
runTaskWithArguments();
} else {
promptForTask();
}
}
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment