8
0

jscs.js 3.8 KB

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