@@ -392,21 +392,37 @@ namespace ts {
392
392
getModifiedTime ( fileName : string ) : Date | undefined ;
393
393
setModifiedTime ( fileName : string , date : Date ) : void ;
394
394
deleteFile ( fileName : string ) : void ;
395
+
396
+ reportDiagnostic : DiagnosticReporter ; // Technically we want to move it out and allow steps of actions on Solution, but for now just merge stuff in build host here
397
+ reportSolutionBuilderStatus : DiagnosticReporter ;
395
398
}
396
399
397
400
export interface SolutionBuilderWithWatchHost extends SolutionBuilderHost , WatchHost {
398
401
}
399
402
400
- export function createSolutionBuilderHost ( system = sys ) {
403
+ /**
404
+ * Create a function that reports watch status by writing to the system and handles the formating of the diagnostic
405
+ */
406
+ export function createBuilderStatusReporter ( system : System , pretty ?: boolean ) : DiagnosticReporter {
407
+ return diagnostic => {
408
+ let output = pretty ? `[${ formatColorAndReset ( new Date ( ) . toLocaleTimeString ( ) , ForegroundColorEscapeSequences . Grey ) } ] ` : `${ new Date ( ) . toLocaleTimeString ( ) } - ` ;
409
+ output += `${ flattenDiagnosticMessageText ( diagnostic . messageText , system . newLine ) } ${ system . newLine + system . newLine } ` ;
410
+ system . write ( output ) ;
411
+ } ;
412
+ }
413
+
414
+ export function createSolutionBuilderHost ( system = sys , reportDiagnostic ?: DiagnosticReporter , reportSolutionBuilderStatus ?: DiagnosticReporter ) {
401
415
const host = createCompilerHost ( { } , /*setParentNodes*/ undefined , system ) as SolutionBuilderHost ;
402
416
host . getModifiedTime = system . getModifiedTime ? path => system . getModifiedTime ! ( path ) : ( ) => undefined ;
403
417
host . setModifiedTime = system . setModifiedTime ? ( path , date ) => system . setModifiedTime ! ( path , date ) : noop ;
404
418
host . deleteFile = system . deleteFile ? path => system . deleteFile ! ( path ) : noop ;
419
+ host . reportDiagnostic = reportDiagnostic || createDiagnosticReporter ( system ) ;
420
+ host . reportSolutionBuilderStatus = reportSolutionBuilderStatus || createBuilderStatusReporter ( system ) ;
405
421
return host ;
406
422
}
407
423
408
- export function createSolutionBuilderWithWatchHost ( system = sys , reportWatchStatus ?: WatchStatusReporter ) {
409
- const host = createSolutionBuilderHost ( system ) as SolutionBuilderWithWatchHost ;
424
+ export function createSolutionBuilderWithWatchHost ( system = sys , reportDiagnostic ?: DiagnosticReporter , reportSolutionBuilderStatus ?: DiagnosticReporter , reportWatchStatus ?: WatchStatusReporter ) {
425
+ const host = createSolutionBuilderHost ( system , reportDiagnostic , reportSolutionBuilderStatus ) as SolutionBuilderWithWatchHost ;
410
426
const watchHost = createWatchHost ( system , reportWatchStatus ) ;
411
427
host . onWatchStatusChange = watchHost . onWatchStatusChange ;
412
428
host . watchFile = watchHost . watchFile ;
@@ -422,7 +438,7 @@ namespace ts {
422
438
* TODO: use SolutionBuilderWithWatchHost => watchedSolution
423
439
* use SolutionBuilderHost => Solution
424
440
*/
425
- export function createSolutionBuilder ( host : SolutionBuilderHost , buildHost : BuildHost , rootNames : ReadonlyArray < string > , defaultOptions : BuildOptions ) {
441
+ export function createSolutionBuilder ( host : SolutionBuilderHost , rootNames : ReadonlyArray < string > , defaultOptions : BuildOptions ) {
426
442
const hostWithWatch = host as SolutionBuilderWithWatchHost ;
427
443
const configFileCache = createConfigFileCache ( host ) ;
428
444
let context = createBuildContext ( defaultOptions ) ;
@@ -445,6 +461,10 @@ namespace ts {
445
461
startWatching
446
462
} ;
447
463
464
+ function reportStatus ( message : DiagnosticMessage , ...args : string [ ] ) {
465
+ host . reportSolutionBuilderStatus ( createCompilerDiagnostic ( message , ...args ) ) ;
466
+ }
467
+
448
468
function startWatching ( ) {
449
469
const graph = getGlobalDependencyGraph ( ) ! ;
450
470
if ( ! graph . buildQueue ) {
@@ -743,7 +763,7 @@ namespace ts {
743
763
verboseReportProjectStatus ( next , status ) ;
744
764
745
765
if ( status . type === UpToDateStatusType . UpstreamBlocked ) {
746
- if ( context . options . verbose ) buildHost . verbose ( Diagnostics . Skipping_build_of_project_0_because_its_dependency_1_has_errors , resolved , status . upstreamProjectName ) ;
766
+ if ( context . options . verbose ) reportStatus ( Diagnostics . Skipping_build_of_project_0_because_its_dependency_1_has_errors , resolved , status . upstreamProjectName ) ;
747
767
continue ;
748
768
}
749
769
@@ -780,7 +800,7 @@ namespace ts {
780
800
if ( temporaryMarks [ projPath ] ) {
781
801
if ( ! inCircularContext ) {
782
802
hadError = true ;
783
- buildHost . error ( Diagnostics . Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0 , circularityReportStack . join ( "\r\n" ) ) ;
803
+ reportStatus ( Diagnostics . Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0 , circularityReportStack . join ( "\r\n" ) ) ;
784
804
return ;
785
805
}
786
806
}
@@ -812,11 +832,11 @@ namespace ts {
812
832
813
833
function buildSingleProject ( proj : ResolvedConfigFileName ) : BuildResultFlags {
814
834
if ( context . options . dry ) {
815
- buildHost . message ( Diagnostics . A_non_dry_build_would_build_project_0 , proj ) ;
835
+ reportStatus ( Diagnostics . A_non_dry_build_would_build_project_0 , proj ) ;
816
836
return BuildResultFlags . Success ;
817
837
}
818
838
819
- if ( context . options . verbose ) buildHost . verbose ( Diagnostics . Building_project_0 , proj ) ;
839
+ if ( context . options . verbose ) reportStatus ( Diagnostics . Building_project_0 , proj ) ;
820
840
821
841
let resultFlags = BuildResultFlags . None ;
822
842
resultFlags |= BuildResultFlags . DeclarationOutputUnchanged ;
@@ -850,7 +870,7 @@ namespace ts {
850
870
if ( syntaxDiagnostics . length ) {
851
871
resultFlags |= BuildResultFlags . SyntaxErrors ;
852
872
for ( const diag of syntaxDiagnostics ) {
853
- buildHost . errorDiagnostic ( diag ) ;
873
+ host . reportDiagnostic ( diag ) ;
854
874
}
855
875
context . projectStatus . setValue ( proj , { type : UpToDateStatusType . Unbuildable , reason : "Syntactic errors" } ) ;
856
876
return resultFlags ;
@@ -862,7 +882,7 @@ namespace ts {
862
882
if ( declDiagnostics . length ) {
863
883
resultFlags |= BuildResultFlags . DeclarationEmitErrors ;
864
884
for ( const diag of declDiagnostics ) {
865
- buildHost . errorDiagnostic ( diag ) ;
885
+ host . reportDiagnostic ( diag ) ;
866
886
}
867
887
context . projectStatus . setValue ( proj , { type : UpToDateStatusType . Unbuildable , reason : "Declaration file errors" } ) ;
868
888
return resultFlags ;
@@ -874,7 +894,7 @@ namespace ts {
874
894
if ( semanticDiagnostics . length ) {
875
895
resultFlags |= BuildResultFlags . TypeErrors ;
876
896
for ( const diag of semanticDiagnostics ) {
877
- buildHost . errorDiagnostic ( diag ) ;
897
+ host . reportDiagnostic ( diag ) ;
878
898
}
879
899
context . projectStatus . setValue ( proj , { type : UpToDateStatusType . Unbuildable , reason : "Semantic errors" } ) ;
880
900
return resultFlags ;
@@ -913,11 +933,11 @@ namespace ts {
913
933
914
934
function updateOutputTimestamps ( proj : ParsedCommandLine ) {
915
935
if ( context . options . dry ) {
916
- return buildHost . message ( Diagnostics . A_non_dry_build_would_build_project_0 , proj . options . configFilePath ! ) ;
936
+ return reportStatus ( Diagnostics . A_non_dry_build_would_build_project_0 , proj . options . configFilePath ! ) ;
917
937
}
918
938
919
939
if ( context . options . verbose ) {
920
- buildHost . verbose ( Diagnostics . Updating_output_timestamps_of_project_0 , proj . options . configFilePath ! ) ;
940
+ reportStatus ( Diagnostics . Updating_output_timestamps_of_project_0 , proj . options . configFilePath ! ) ;
921
941
}
922
942
923
943
const now = new Date ( ) ;
@@ -970,18 +990,18 @@ namespace ts {
970
990
function cleanAllProjects ( ) {
971
991
const resolvedNames : ReadonlyArray < ResolvedConfigFileName > | undefined = getAllProjectsInScope ( ) ;
972
992
if ( resolvedNames === undefined ) {
973
- buildHost . message ( Diagnostics . Skipping_clean_because_not_all_projects_could_be_located ) ;
993
+ reportStatus ( Diagnostics . Skipping_clean_because_not_all_projects_could_be_located ) ;
974
994
return ExitStatus . DiagnosticsPresent_OutputsSkipped ;
975
995
}
976
996
977
997
const filesToDelete = getFilesToClean ( resolvedNames ) ;
978
998
if ( filesToDelete === undefined ) {
979
- buildHost . message ( Diagnostics . Skipping_clean_because_not_all_projects_could_be_located ) ;
999
+ reportStatus ( Diagnostics . Skipping_clean_because_not_all_projects_could_be_located ) ;
980
1000
return ExitStatus . DiagnosticsPresent_OutputsSkipped ;
981
1001
}
982
1002
983
1003
if ( context . options . dry ) {
984
- buildHost . message ( Diagnostics . A_non_dry_build_would_delete_the_following_files_Colon_0 , filesToDelete . map ( f => `\r\n * ${ f } ` ) . join ( "" ) ) ;
1004
+ reportStatus ( Diagnostics . A_non_dry_build_would_delete_the_following_files_Colon_0 , filesToDelete . map ( f => `\r\n * ${ f } ` ) . join ( "" ) ) ;
985
1005
return ExitStatus . Success ;
986
1006
}
987
1007
@@ -1001,7 +1021,7 @@ namespace ts {
1001
1021
if ( host . fileExists ( fullPathWithTsconfig ) ) {
1002
1022
return fullPathWithTsconfig as ResolvedConfigFileName ;
1003
1023
}
1004
- buildHost . error ( Diagnostics . File_0_not_found , relName ( fullPath ) ) ;
1024
+ host . reportDiagnostic ( createCompilerDiagnostic ( Diagnostics . File_0_not_found , relName ( fullPath ) ) ) ;
1005
1025
return undefined ;
1006
1026
}
1007
1027
@@ -1039,7 +1059,7 @@ namespace ts {
1039
1059
// Up to date, skip
1040
1060
if ( defaultOptions . dry ) {
1041
1061
// In a dry build, inform the user of this fact
1042
- buildHost . message ( Diagnostics . Project_0_is_up_to_date , projName ) ;
1062
+ reportStatus ( Diagnostics . Project_0_is_up_to_date , projName ) ;
1043
1063
}
1044
1064
continue ;
1045
1065
}
@@ -1051,7 +1071,7 @@ namespace ts {
1051
1071
}
1052
1072
1053
1073
if ( status . type === UpToDateStatusType . UpstreamBlocked ) {
1054
- if ( context . options . verbose ) buildHost . verbose ( Diagnostics . Skipping_build_of_project_0_because_its_dependency_1_has_errors , projName , status . upstreamProjectName ) ;
1074
+ if ( context . options . verbose ) reportStatus ( Diagnostics . Skipping_build_of_project_0_because_its_dependency_1_has_errors , projName , status . upstreamProjectName ) ;
1055
1075
continue ;
1056
1076
}
1057
1077
@@ -1076,23 +1096,19 @@ namespace ts {
1076
1096
for ( const name of graph . buildQueue ) {
1077
1097
names . push ( name ) ;
1078
1098
}
1079
- if ( context . options . verbose ) buildHost . verbose ( Diagnostics . Projects_in_this_build_Colon_0 , names . map ( s => "\r\n * " + relName ( s ) ) . join ( "" ) ) ;
1099
+ if ( context . options . verbose ) reportStatus ( Diagnostics . Projects_in_this_build_Colon_0 , names . map ( s => "\r\n * " + relName ( s ) ) . join ( "" ) ) ;
1080
1100
}
1081
1101
1082
1102
function relName ( path : string ) : string {
1083
1103
return convertToRelativePath ( path , host . getCurrentDirectory ( ) , f => host . getCanonicalFileName ( f ) ) ;
1084
1104
}
1085
1105
1086
- function reportVerbose ( message : DiagnosticMessage , ...args : string [ ] ) {
1087
- buildHost . verbose ( message , ...args ) ;
1088
- }
1089
-
1090
1106
/**
1091
1107
* Report the up-to-date status of a project if we're in verbose mode
1092
1108
*/
1093
1109
function verboseReportProjectStatus ( configFileName : string , status : UpToDateStatus ) {
1094
1110
if ( ! context . options . verbose ) return ;
1095
- return formatUpToDateStatus ( configFileName , status , relName , reportVerbose ) ;
1111
+ return formatUpToDateStatus ( configFileName , status , relName , reportStatus ) ;
1096
1112
}
1097
1113
}
1098
1114
0 commit comments