diff --git a/Gruntfile.js b/Gruntfile.js index 78df843..8996547 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -10,6 +10,8 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-contrib-compress'); grunt.loadNpmTasks('grunt-contrib-clean'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-jscs-checker'); grunt.loadNpmTasks('lumbar'); // Parse config files @@ -44,9 +46,11 @@ module.exports = function(grunt) { ----------------------------------------------------------------------------------------------------*/ grunt.registerTask('modules', 'Build the FullCalendar modules', [ + 'jscs:srcModules', 'clean:modules', 'lumbar:build', 'concat:moduleVariables', + 'jshint:builtModules', 'uglify:modules' ]); @@ -87,6 +91,8 @@ module.exports = function(grunt) { ----------------------------------------------------------------------------------------------------*/ grunt.registerTask('languages', [ + 'jscs:srcLanguages', + 'jshint:srcLanguages', 'clean:languages', 'generateLanguages', 'uglify:languages' @@ -300,9 +306,27 @@ module.exports = function(grunt) { + /* Linting and Code Style Checking + ----------------------------------------------------------------------------------------------------*/ + + grunt.registerTask('check', 'Lint and check code style', [ + 'jscs', + 'jshint:srcModules', + 'jshint:srcLanguages', + 'lumbar:build', + 'jshint:builtModules', + 'jshint:tests', + ]); + + // configs located elsewhere + config.jshint = require('./jshint.conf'); + config.jscs = require('./jscs.conf'); + + + // finally, give grunt the config object... grunt.initConfig(config); - + // load everything in the ./tasks/ directory grunt.loadTasks('tasks'); }; diff --git a/jscs.conf.js b/jscs.conf.js new file mode 100644 index 0000000..2c94549 --- /dev/null +++ b/jscs.conf.js @@ -0,0 +1,48 @@ +module.exports = { + + options: { + requireCurlyBraces: [ 'if', 'else', 'for', 'while', 'do', 'try', 'catch' ], + requireSpacesInFunctionExpression: { 'beforeOpeningCurlyBrace': true }, + disallowSpacesInFunctionExpression: { 'beforeOpeningRoundBrace': true }, + disallowSpacesInsideParentheses: true, + requireSpacesInsideObjectBrackets: 'all', + disallowQuotedKeysInObjects: 'allButReserved', + disallowSpaceAfterObjectKeys: true, + requireCommaBeforeLineBreak: true, + requireOperatorBeforeLineBreak: [ '?', '+', '-', '/', '*', '=', '==', '===', '!=', '!==', '>', '>=', '<', '<=' ], + disallowLeftStickedOperators: [ '?' ], + requireRightStickedOperators: [ '!' ], + requireLeftStickedOperators: [ ',' ], + disallowRightStickedOperators: [ ':' ], + disallowSpaceAfterPrefixUnaryOperators: [ '++', '--', '+', '-', '~', '!' ], + disallowSpaceBeforePostfixUnaryOperators: [ '++', '--' ], + requireCamelCaseOrUpperCaseIdentifiers: true, + disallowKeywords: [ 'with' ], + disallowMultipleLineStrings: true, + requireDotNotation: true, + requireParenthesesAroundIIFE: true + }, + + srcModules: [ + 'src/**/*.js', + '!**/intro.js', + '!**/outro.js' + ], + + srcLanguages: 'lang/*.js', + + tests: { + options: { + // more restrictions. + // we eventually want these to apply to all other code too. + requireSpaceAfterKeywords: [ 'if', 'else', 'for', 'while', 'do', 'switch', 'return', 'try', 'catch' ], + requireSpacesInsideArrayBrackets: 'all', + requireKeywordsOnNewLine: [ 'else', 'catch' ], + disallowTrailingWhitespace: true, + validateQuoteMarks: '\'', + maximumLineLength: 120 + }, + src: 'tests/automated/*.js' + } + +}; \ No newline at end of file diff --git a/jshint.conf.js b/jshint.conf.js new file mode 100644 index 0000000..bfb27d6 --- /dev/null +++ b/jshint.conf.js @@ -0,0 +1,44 @@ +module.exports = { + + options: { + browser: true, + globals: { + define: true, + moment: true, + jQuery: true + }, + bitwise: true, + camelcase: true, + curly: true, + forin: true, + freeze: true, + immed: true, + noarg: true, + smarttabs: true, + trailing: true, + eqnull: true, + '-W032': true, // Unnecessary semicolon. (lumbar's ;;) + '-W008': true // A leading decimal point can be confused with a dot (ex: .5) + }, + + srcModules: [ + 'src/**/*.js', + '!**/intro.js', + '!**/outro.js' + ], + + builtModules: { + options: { + // Built modules are ready to be checked for... + undef: true, // use of undeclared globals + unused: 'vars', // functions/variables (excluding function arguments) that are never used + latedef: 'nofunc' // variables that are referenced before their `var` statement + }, + src: 'build/out/{fullcalendar,gcal}.js' + }, + + srcLanguages: 'lang/*.js', + + tests: 'tests/automated/*.js' + +}; \ No newline at end of file diff --git a/package.json b/package.json index af60176..26f33cc 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ "grunt-contrib-copy": "~0.4.0", "grunt-contrib-compress": "~0.4.0", "grunt-contrib-clean": "~0.4.0", + "grunt-contrib-jshint": "~0.8.0", + "grunt-jscs-checker": "~0.3.2", "lumbar": "~2.0.0-beta19" }, "scripts": {