@@ -4,7 +4,6 @@ var fs = require("fs");
44var os = require ( "os" ) ;
55var path = require ( "path" ) ;
66var child_process = require ( "child_process" ) ;
7- var Linter = require ( "tslint" ) ;
87var fold = require ( "travis-fold" ) ;
98var runTestsInParallel = require ( "./scripts/mocha-parallel" ) . runTestsInParallel ;
109
@@ -1054,36 +1053,6 @@ task("build-rules-end", [] , function() {
10541053 if ( fold . isTravis ( ) ) console . log ( fold . end ( "build-rules" ) ) ;
10551054} ) ;
10561055
1057- function getLinterOptions ( ) {
1058- return {
1059- configuration : require ( "./tslint.json" ) ,
1060- formatter : "prose" ,
1061- formattersDirectory : undefined ,
1062- rulesDirectory : "built/local/tslint"
1063- } ;
1064- }
1065-
1066- function lintFileContents ( options , path , contents ) {
1067- var ll = new Linter ( path , contents , options ) ;
1068- console . log ( "Linting '" + path + "'." ) ;
1069- return ll . lint ( ) ;
1070- }
1071-
1072- function lintFile ( options , path ) {
1073- var contents = fs . readFileSync ( path , "utf8" ) ;
1074- return lintFileContents ( options , path , contents ) ;
1075- }
1076-
1077- function lintFileAsync ( options , path , cb ) {
1078- fs . readFile ( path , "utf8" , function ( err , contents ) {
1079- if ( err ) {
1080- return cb ( err ) ;
1081- }
1082- var result = lintFileContents ( options , path , contents ) ;
1083- cb ( undefined , result ) ;
1084- } ) ;
1085- }
1086-
10871056var lintTargets = compilerSources
10881057 . concat ( harnessSources )
10891058 // Other harness sources
@@ -1094,75 +1063,78 @@ var lintTargets = compilerSources
10941063 . concat ( [ "Gulpfile.ts" ] )
10951064 . concat ( [ nodeServerInFile , perftscPath , "tests/perfsys.ts" , webhostPath ] ) ;
10961065
1066+ function sendNextFile ( files , child , callback , failures ) {
1067+ var file = files . pop ( ) ;
1068+ if ( file ) {
1069+ console . log ( "Linting '" + file + "'." ) ;
1070+ child . send ( { kind : "file" , name : file } ) ;
1071+ }
1072+ else {
1073+ child . send ( { kind : "close" } ) ;
1074+ callback ( failures ) ;
1075+ }
1076+ }
1077+
1078+ function spawnLintWorker ( files , callback ) {
1079+ var child = child_process . fork ( "./scripts/parallel-lint" ) ;
1080+ var failures = 0 ;
1081+ child . on ( "message" , function ( data ) {
1082+ switch ( data . kind ) {
1083+ case "result" :
1084+ if ( data . failures > 0 ) {
1085+ failures += data . failures ;
1086+ console . log ( data . output ) ;
1087+ }
1088+ sendNextFile ( files , child , callback , failures ) ;
1089+ break ;
1090+ case "error" :
1091+ console . error ( data . error ) ;
1092+ failures ++ ;
1093+ sendNextFile ( files , child , callback , failures ) ;
1094+ break ;
1095+ }
1096+ } ) ;
1097+ sendNextFile ( files , child , callback , failures ) ;
1098+ }
10971099
10981100desc ( "Runs tslint on the compiler sources. Optional arguments are: f[iles]=regex" ) ;
10991101task ( "lint" , [ "build-rules" ] , function ( ) {
11001102 if ( fold . isTravis ( ) ) console . log ( fold . start ( "lint" ) ) ;
11011103 var startTime = mark ( ) ;
1102- var lintOptions = getLinterOptions ( ) ;
11031104 var failed = 0 ;
11041105 var fileMatcher = RegExp ( process . env . f || process . env . file || process . env . files || "" ) ;
11051106 var done = { } ;
11061107 for ( var i in lintTargets ) {
11071108 var target = lintTargets [ i ] ;
11081109 if ( ! done [ target ] && fileMatcher . test ( target ) ) {
1109- var result = lintFile ( lintOptions , target ) ;
1110- if ( result . failureCount > 0 ) {
1111- console . log ( result . output ) ;
1112- failed += result . failureCount ;
1113- }
1114- done [ target ] = true ;
1110+ done [ target ] = fs . statSync ( target ) . size ;
11151111 }
11161112 }
1117- measure ( startTime ) ;
1118- if ( fold . isTravis ( ) ) console . log ( fold . end ( "lint" ) ) ;
1119- if ( failed > 0 ) {
1120- fail ( 'Linter errors.' , failed ) ;
1121- }
1122- } ) ;
11231113
1124- /**
1125- * This is required because file watches on Windows get fires _twice_
1126- * when a file changes on some node/windows version configuations
1127- * (node v4 and win 10, for example). By not running a lint for a file
1128- * which already has a pending lint, we avoid duplicating our work.
1129- * (And avoid printing duplicate results!)
1130- */
1131- var lintSemaphores = { } ;
1132-
1133- function lintWatchFile ( filename ) {
1134- fs . watch ( filename , { persistent : true } , function ( event ) {
1135- if ( event !== "change" ) {
1136- return ;
1137- }
1114+ var workerCount = ( process . env . workerCount && + process . env . workerCount ) || os . cpus ( ) . length ;
11381115
1139- if ( ! lintSemaphores [ filename ] ) {
1140- lintSemaphores [ filename ] = true ;
1141- lintFileAsync ( getLinterOptions ( ) , filename , function ( err , result ) {
1142- delete lintSemaphores [ filename ] ;
1143- if ( err ) {
1144- console . log ( err ) ;
1145- return ;
1146- }
1147- if ( result . failureCount > 0 ) {
1148- console . log ( "***Lint failure***" ) ;
1149- for ( var i = 0 ; i < result . failures . length ; i ++ ) {
1150- var failure = result . failures [ i ] ;
1151- var start = failure . startPosition . lineAndCharacter ;
1152- var end = failure . endPosition . lineAndCharacter ;
1153- console . log ( "warning " + filename + " (" + ( start . line + 1 ) + "," + ( start . character + 1 ) + "," + ( end . line + 1 ) + "," + ( end . character + 1 ) + "): " + failure . failure ) ;
1154- }
1155- console . log ( "*** Total " + result . failureCount + " failures." ) ;
1156- }
1157- } ) ;
1158- }
1116+ var names = Object . keys ( done ) . sort ( function ( namea , nameb ) {
1117+ return done [ namea ] - done [ nameb ] ;
11591118 } ) ;
1160- }
11611119
1162- desc ( "Watches files for changes to rerun a lint pass" ) ;
1163- task ( "lint-server" , [ "build-rules" ] , function ( ) {
1164- console . log ( "Watching ./src for changes to linted files" ) ;
1165- for ( var i = 0 ; i < lintTargets . length ; i ++ ) {
1166- lintWatchFile ( lintTargets [ i ] ) ;
1120+ for ( var i = 0 ; i < workerCount ; i ++ ) {
1121+ spawnLintWorker ( names , finished ) ;
11671122 }
1168- } ) ;
1123+
1124+ var completed = 0 ;
1125+ var failures = 0 ;
1126+ function finished ( fails ) {
1127+ completed ++ ;
1128+ failures += fails ;
1129+ if ( completed === workerCount ) {
1130+ measure ( startTime ) ;
1131+ if ( fold . isTravis ( ) ) console . log ( fold . end ( "lint" ) ) ;
1132+ if ( failures > 0 ) {
1133+ fail ( 'Linter errors.' , failed ) ;
1134+ }
1135+ else {
1136+ complete ( ) ;
1137+ }
1138+ }
1139+ }
1140+ } , { async : true } ) ;
0 commit comments