jscs.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /* jshint node: true */
  2. 'use strict';
  3. module.exports = function( grunt ) {
  4. // Register our custom jscs task.
  5. grunt.registerTask( 'jscs', 'JavaScript Code Style checker', function() {
  6. task.call( this, grunt );
  7. } );
  8. };
  9. var defaultConfig = {
  10. 'requireCurlyBraces': [
  11. 'if', 'else', 'for', 'while', 'do', 'switch', 'try', 'catch'
  12. ],
  13. 'requireSpaceAfterKeywords': [
  14. 'if', 'else', 'for', 'while', 'do', 'switch', 'return', 'try', 'catch'
  15. ],
  16. 'requireSpaceBeforeBlockStatements': true,
  17. 'requireParenthesesAroundIIFE': true,
  18. 'requireSpacesInConditionalExpression': {
  19. 'afterTest': true,
  20. 'beforeConsequent': true,
  21. 'afterConsequent': true,
  22. 'beforeAlternate': true
  23. },
  24. 'requireSpacesInFunctionExpression': {
  25. 'beforeOpeningCurlyBrace': true
  26. },
  27. 'disallowSpacesInFunctionExpression': {
  28. 'beforeOpeningRoundBrace': true
  29. },
  30. 'requireBlocksOnNewline': true,
  31. 'requireSpacesInsideObjectBrackets': 'all',
  32. 'requireSpacesInsideArrayBrackets': 'all',
  33. 'disallowSpaceAfterObjectKeys': true,
  34. 'requireCommaBeforeLineBreak': true,
  35. 'requireOperatorBeforeLineBreak': [
  36. '?', '=', '+', '-', '/', '*', '==', '===', '!=', '!==', '>', '>=', '<', '<=', '|', '||', '&', '&&', '^', '+=', '*=',
  37. '-=', '/=', '^='
  38. ],
  39. 'requireSpaceBeforeBinaryOperators': [
  40. '+', '-', '/', '*', '=', '==', '===', '!=', '!==', '>', '>=', '<', '<=', '|', '||', '&', '&&', '^', '+=', '*=', '-=',
  41. '/=', '^='
  42. ],
  43. 'requireSpaceAfterBinaryOperators': [
  44. '+', '-', '/', '*', '=', '==', '===', '!=', '!==', '>', '>=', '<', '<=', '|', '||', '&', '&&', '^', '+=', '*=', '-=',
  45. '/=', '^='
  46. ],
  47. 'disallowSpaceAfterPrefixUnaryOperators': [
  48. '++', '--', '+', '-', '~', '!'
  49. ],
  50. 'disallowSpaceBeforePostfixUnaryOperators': [
  51. '++', '--'
  52. ],
  53. 'disallowKeywords': [
  54. 'with'
  55. ],
  56. 'validateLineBreaks': 'LF',
  57. 'validateQuoteMarks': {
  58. 'mark': '\'',
  59. 'escape': true
  60. },
  61. 'validateIndentation': '\t',
  62. 'disallowMixedSpacesAndTabs': true,
  63. 'disallowTrailingWhitespace': true,
  64. 'disallowKeywordsOnNewLine': [
  65. 'else', 'catch'
  66. ],
  67. 'maximumLineLength': 120,
  68. 'safeContextKeyword': [
  69. 'that'
  70. ],
  71. 'requireDotNotation': true,
  72. 'disallowYodaConditions': true
  73. };
  74. var Vow = require( 'vow' ),
  75. Jscs = require( 'jscs' ),
  76. tools = require( './res/tools' );
  77. function task( grunt ) {
  78. // Checking is asynchronous.
  79. var done = this.async();
  80. // Get the list of files that will end up in the next commit.
  81. var files = tools.getGitDirtyFiles();
  82. // Reduce the files list to *.js.
  83. files = files.filter( function( file ) {
  84. // Accepts .js files only
  85. return file && ( /\.js$/ ).test( file );
  86. } );
  87. // Create and configure the Checker.
  88. var checker = new Jscs();
  89. checker.registerDefaultRules();
  90. checker.configure( defaultConfig );
  91. // Get the check promises for each file.
  92. var checks = files.map( function( file ) {
  93. // Returns a check promise for each file.
  94. return checker.checkPath( file );
  95. } );
  96. // Once the promises are done...
  97. Vow.allResolved( checks ).spread( function() {
  98. var results, errorCount = 0;
  99. // grunt.async() hide errors, so better to catch them.
  100. try {
  101. results = Array.prototype.filter.call( arguments, function( promise ) {
  102. return promise && promise.isFulfilled();
  103. } ).map( function( promise ) {
  104. // Take the jscs error object out of each promise.
  105. return promise.valueOf()[ 0 ];
  106. } );
  107. // Loop throw all files with errors.
  108. results.forEach( function( fileErrors ) {
  109. // Loop through all errors in the file.
  110. fileErrors.getErrorList().forEach( function( error ) {
  111. errorCount++;
  112. console.log( fileErrors.explainError( error, true ) );
  113. console.log( '' );
  114. } );
  115. } );
  116. } catch ( e ) {
  117. console.log( e );
  118. done( false );
  119. }
  120. if ( errorCount ) {
  121. grunt.log.error( errorCount + ' code style errors found!' );
  122. } else {
  123. grunt.log.ok( results.length + ' files without code style errors.' );
  124. }
  125. done( !errorCount );
  126. } );
  127. }