@@ -4,6 +4,7 @@ var fs = require("fs");
44var os = require ( "os" ) ;
55var path = require ( "path" ) ;
66var child_process = require ( "child_process" ) ;
7+ var Linter = require ( "tslint" ) ;
78
89// Variables
910var compilerDirectory = "src/compiler/" ;
@@ -812,7 +813,6 @@ task("update-sublime", ["local", serverFile], function() {
812813var tslintRuleDir = "scripts/tslint" ;
813814var tslintRules = ( [
814815 "nextLineRule" ,
815- "noInferrableTypesRule" ,
816816 "noNullRule" ,
817817 "booleanTriviaRule"
818818] ) ;
@@ -828,17 +828,93 @@ tslintRulesFiles.forEach(function(ruleFile, i) {
828828 compileFile ( tslintRulesOutFiles [ i ] , [ ruleFile ] , [ ruleFile ] , [ ] , /*useBuiltCompiler*/ true , /*noOutFile*/ true , /*generateDeclarations*/ false , path . join ( builtLocalDirectory , "tslint" ) ) ;
829829} ) ;
830830
831+ function getLinterOptions ( ) {
832+ return {
833+ configuration : require ( "./tslint.json" ) ,
834+ formatter : "prose" ,
835+ formattersDirectory : undefined ,
836+ rulesDirectory : "built/local/tslint"
837+ } ;
838+ }
839+
840+ function lintFileContents ( options , path , contents ) {
841+ var ll = new Linter ( path , contents , options ) ;
842+ return ll . lint ( ) ;
843+ }
844+
845+ function lintFile ( options , path ) {
846+ var contents = fs . readFileSync ( path , "utf8" ) ;
847+ return lintFileContents ( options , path , contents ) ;
848+ }
849+
850+ function lintFileAsync ( options , path , cb ) {
851+ fs . readFile ( path , "utf8" , function ( err , contents ) {
852+ if ( err ) {
853+ return cb ( err ) ;
854+ }
855+ var result = lintFileContents ( options , path , contents ) ;
856+ cb ( undefined , result ) ;
857+ } ) ;
858+ }
859+
860+ var lintTargets = compilerSources . concat ( harnessCoreSources ) ;
861+
831862// if the codebase were free of linter errors we could make jake runtests
832863// run this task automatically
833864desc ( "Runs tslint on the compiler sources" ) ;
834865task ( "lint" , [ "build-rules" ] , function ( ) {
835- function success ( f ) { return function ( ) { console . log ( 'SUCCESS: No linter errors in ' + f + '\n' ) ; } } ;
836- function failure ( f ) { return function ( ) { console . log ( 'FAILURE: Please fix linting errors in ' + f + '\n' ) } } ;
837-
838- var lintTargets = compilerSources . concat ( harnessCoreSources ) ;
866+ var lintOptions = getLinterOptions ( ) ;
839867 for ( var i in lintTargets ) {
840- var f = lintTargets [ i ] ;
841- var cmd = 'tslint --rules-dir built/local/tslint -c tslint.json ' + f ;
842- exec ( cmd , success ( f ) , failure ( f ) ) ;
868+ var result = lintFile ( lintOptions , lintTargets [ i ] ) ;
869+ if ( result . failureCount > 0 ) {
870+ console . log ( result . output ) ;
871+ fail ( 'Linter errors.' , result . failureCount ) ;
872+ }
843873 }
844- } , { async : true } ) ;
874+ } ) ;
875+
876+ /**
877+ * This is required because file watches on Windows get fires _twice_
878+ * when a file changes on some node/windows version configuations
879+ * (node v4 and win 10, for example). By not running a lint for a file
880+ * which already has a pending lint, we avoid duplicating our work.
881+ * (And avoid printing duplicate results!)
882+ */
883+ var lintSemaphores = { } ;
884+
885+ function lintWatchFile ( filename ) {
886+ fs . watch ( filename , { persistent : true } , function ( event ) {
887+ if ( event !== "change" ) {
888+ return ;
889+ }
890+
891+ if ( ! lintSemaphores [ filename ] ) {
892+ lintSemaphores [ filename ] = true ;
893+ lintFileAsync ( getLinterOptions ( ) , filename , function ( err , result ) {
894+ delete lintSemaphores [ filename ] ;
895+ if ( err ) {
896+ console . log ( err ) ;
897+ return ;
898+ }
899+ if ( result . failureCount > 0 ) {
900+ console . log ( "***Lint failure***" ) ;
901+ for ( var i = 0 ; i < result . failures . length ; i ++ ) {
902+ var failure = result . failures [ i ] ;
903+ var start = failure . startPosition . lineAndCharacter ;
904+ var end = failure . endPosition . lineAndCharacter ;
905+ console . log ( "warning " + filename + " (" + ( start . line + 1 ) + "," + ( start . character + 1 ) + "," + ( end . line + 1 ) + "," + ( end . character + 1 ) + "): " + failure . failure ) ;
906+ }
907+ console . log ( "*** Total " + result . failureCount + " failures." ) ;
908+ }
909+ } ) ;
910+ }
911+ } ) ;
912+ }
913+
914+ desc ( "Watches files for changes to rerun a lint pass" ) ;
915+ task ( "lint-server" , [ "build-rules" ] , function ( ) {
916+ console . log ( "Watching ./src for changes to linted files" ) ;
917+ for ( var i = 0 ; i < lintTargets . length ; i ++ ) {
918+ lintWatchFile ( lintTargets [ i ] ) ;
919+ }
920+ } ) ;
0 commit comments