@@ -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/" ;
@@ -828,17 +829,92 @@ tslintRulesFiles.forEach(function(ruleFile, i) {
828829 compileFile ( tslintRulesOutFiles [ i ] , [ ruleFile ] , [ ruleFile ] , [ ] , /*useBuiltCompiler*/ true , /*noOutFile*/ true , /*generateDeclarations*/ false , path . join ( builtLocalDirectory , "tslint" ) ) ;
829830} ) ;
830831
832+ function getLinterOptions ( ) {
833+ return {
834+ configuration : require ( "./tslint.json" ) ,
835+ formatter : "prose" ,
836+ formattersDirectory : undefined ,
837+ rulesDirectory : "built/local/tslint"
838+ } ;
839+ }
840+
841+ function lintFileContents ( options , path , contents ) {
842+ var ll = new Linter ( path , contents , options ) ;
843+ return ll . lint ( ) ;
844+ }
845+
846+ function lintFile ( options , path ) {
847+ var contents = fs . readFileSync ( path , "utf8" ) ;
848+ return lintFileContents ( options , path , contents ) ;
849+ }
850+
851+ function lintFileAsync ( options , path , cb ) {
852+ fs . readFile ( path , "utf8" , function ( err , contents ) {
853+ if ( err ) {
854+ return cb ( err ) ;
855+ }
856+ var result = lintFileContents ( options , path , contents ) ;
857+ cb ( undefined , result ) ;
858+ } ) ;
859+ }
860+
861+ var lintTargets = compilerSources . concat ( harnessCoreSources ) ;
862+
831863// if the codebase were free of linter errors we could make jake runtests
832864// run this task automatically
833865desc ( "Runs tslint on the compiler sources" ) ;
834866task ( "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 ) ;
867+ var lintOptions = getLinterOptions ( ) ;
839868 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 ) ) ;
869+ var result = lintFile ( lintOptions , lintTargets [ i ] ) ;
870+ if ( result . failureCount > 0 ) {
871+ console . log ( result . output ) ;
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