tools.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /* jshint node: true */
  2. 'use strict';
  3. var dirtyFiles,
  4. ignoreList;
  5. module.exports = {
  6. /**
  7. * Check if a task (including its optional target) is in the queue of tasks to be executed by grunt.
  8. * @param grunt {Object} The grunt object.
  9. * @param task {String} The task name. May optionally include the target (e.g. 'task:target').
  10. * @returns {Boolean} "true" if the task is in the queue.
  11. */
  12. checkTaskInQueue: function( grunt, task ) {
  13. var cliTasks = grunt.cli.tasks;
  14. // Check if the task has been called directly.
  15. var isDirectCall = ( cliTasks.indexOf( task ) > -1 );
  16. // Check if this is a "default" call and that the task is inside "default".
  17. var isDefaultTask = ( cliTasks.indexOf( 'default' ) > -1 ) || !cliTasks.length,
  18. // Hacking grunt hard.
  19. isTaskInDefault = isDefaultTask && ( grunt.task._tasks.default.info.indexOf( '"' + task + '"' ) > -1 );
  20. return isDirectCall || isTaskInDefault;
  21. },
  22. /**
  23. * Configures a multi-task and defines targets that are queued to be run by grunt.
  24. * @param grunt {Object} The grunt object.
  25. * @param options {Object} A list of options for the method. See the jscs and jshint tasks for example.
  26. */
  27. setupMultitaskConfig: function( grunt, options ) {
  28. var task = options.task,
  29. taskConfig = {},
  30. config = taskConfig[ task ] = {
  31. options: options.defaultOptions
  32. };
  33. // "all" is the default target to be used if others are not to be run.
  34. var all = options.targets.all,
  35. isAll = true;
  36. delete options.targets.all;
  37. Object.getOwnPropertyNames( options.targets ).forEach( function( target ) {
  38. if ( this.checkTaskInQueue( grunt, task + ':' + target ) ) {
  39. config[ target ] = options.targets[ target ]();
  40. isAll = false;
  41. }
  42. }, this );
  43. if ( isAll ) {
  44. config.all = all();
  45. }
  46. // Append .gitignore entries to the ignore list.
  47. if ( options.addGitIgnore ) {
  48. var ignoreProp = task + '.options.' + options.addGitIgnore,
  49. ignores = grunt.config.get( ignoreProp ) || [];
  50. ignores = ignores.concat( this.getGitIgnore( grunt ) );
  51. grunt.config.set( ignoreProp, ignores );
  52. }
  53. // Merge over configurations set in gruntfile.js.
  54. grunt.config.merge( taskConfig );
  55. },
  56. /**
  57. * Gets the list of ignores from .gitignore.
  58. * @param grunt {Object} The grunt object.
  59. * @returns {Array} The list of ignores.
  60. */
  61. getGitIgnore: function( grunt ) {
  62. if ( !ignoreList ) {
  63. ignoreList = grunt.file.read( '.gitignore' );
  64. ignoreList = ignoreList
  65. // Remove comment lines.
  66. .replace( /^#.*$/gm, '' )
  67. // Transform into array.
  68. .split( /\n+/ )
  69. // Remove empty entries.
  70. .filter( function( path ) {
  71. return !!path;
  72. } );
  73. }
  74. return ignoreList;
  75. },
  76. /**
  77. * Gets the list of files that are supposed to be included in the next git commit.
  78. * @returns {Array} A list of file paths.
  79. */
  80. getGitDirtyFiles: function() {
  81. // Cache it, so it is executed only once when running multiple tasks.
  82. if ( !dirtyFiles ) {
  83. dirtyFiles = this
  84. // Compare the state of index with HEAD.
  85. .shExec( 'git diff-index --name-only HEAD' )
  86. // Remove trailing /n, to avoid empty entry.
  87. .replace( /\s*$/, '' )
  88. // Transform into array.
  89. .split( '\n' );
  90. // If nothing is returned, the array will one one empty string only.
  91. if ( dirtyFiles.length == 1 && !dirtyFiles[ 0 ] ) {
  92. dirtyFiles = [];
  93. }
  94. }
  95. return dirtyFiles;
  96. },
  97. /**
  98. * Executes a shell command.
  99. * @param command {String} The command to be executed.
  100. * @returns {String} The command output.
  101. */
  102. shExec: function( command ) {
  103. var sh = require( 'shelljs' );
  104. sh.config.silent = true;
  105. var ret = sh.exec( command );
  106. if ( ret.code ) {
  107. throw new Error(
  108. 'Error while executing `' + command + '`:\n\n' +
  109. ret.output
  110. );
  111. }
  112. return ret.output;
  113. }
  114. };