@@ -379,6 +379,9 @@ namespace ts {
379
379
/*@internal */
380
380
export const ignoredPaths = [ "/node_modules/." , "/.git" , "/.#" ] ;
381
381
382
+ /*@internal */
383
+ export let sysLog : ( s : string ) => void = noop ;
384
+
382
385
/*@internal */
383
386
export interface RecursiveDirectoryWatcherHost {
384
387
watchDirectory : HostWatchDirectory ;
@@ -730,6 +733,7 @@ namespace ts {
730
733
731
734
const nodeVersion = getNodeMajorVersion ( ) ;
732
735
const isNode4OrLater = nodeVersion ! >= 4 ;
736
+ const isLinuxOrMacOs = process . platform === "linux" || process . platform === "darwin" ;
733
737
734
738
const platform : string = _os . platform ( ) ;
735
739
const useCaseSensitiveFileNames = isFileSystemCaseSensitive ( ) ;
@@ -1029,6 +1033,12 @@ namespace ts {
1029
1033
1030
1034
function fsWatch ( fileOrDirectory : string , entryKind : FileSystemEntryKind . File | FileSystemEntryKind . Directory , callback : FsWatchCallback , recursive : boolean , fallbackPollingWatchFile : HostWatchFile , pollingInterval ?: number ) : FileWatcher {
1031
1035
let options : any ;
1036
+ let lastDirectoryPartWithDirectorySeparator : string | undefined ;
1037
+ let lastDirectoryPart : string | undefined ;
1038
+ if ( isLinuxOrMacOs ) {
1039
+ lastDirectoryPartWithDirectorySeparator = fileOrDirectory . substr ( fileOrDirectory . lastIndexOf ( directorySeparator ) ) ;
1040
+ lastDirectoryPart = lastDirectoryPartWithDirectorySeparator . slice ( directorySeparator . length ) ;
1041
+ }
1032
1042
/** Watcher for the file system entry depending on whether it is missing or present */
1033
1043
let watcher = ! fileSystemEntryExists ( fileOrDirectory , entryKind ) ?
1034
1044
watchMissingFileSystemEntry ( ) :
@@ -1046,6 +1056,7 @@ namespace ts {
1046
1056
* @param createWatcher
1047
1057
*/
1048
1058
function invokeCallbackAndUpdateWatcher ( createWatcher : ( ) => FileWatcher ) {
1059
+ sysLog ( `sysLog:: ${ fileOrDirectory } :: Changing watcher to ${ createWatcher === watchPresentFileSystemEntry ? "Present" : "Missing" } FileSystemEntryWatcher` ) ;
1049
1060
// Call the callback for current directory
1050
1061
callback ( "rename" , "" ) ;
1051
1062
@@ -1072,11 +1083,12 @@ namespace ts {
1072
1083
}
1073
1084
}
1074
1085
try {
1075
-
1076
1086
const presentWatcher = _fs . watch (
1077
1087
fileOrDirectory ,
1078
1088
options ,
1079
- callback
1089
+ isLinuxOrMacOs ?
1090
+ callbackChangingToMissingFileSystemEntry :
1091
+ callback
1080
1092
) ;
1081
1093
// Watch the missing file or directory or error
1082
1094
presentWatcher . on ( "error" , ( ) => invokeCallbackAndUpdateWatcher ( watchMissingFileSystemEntry ) ) ;
@@ -1090,11 +1102,24 @@ namespace ts {
1090
1102
}
1091
1103
}
1092
1104
1105
+ function callbackChangingToMissingFileSystemEntry ( event : "rename" | "change" , relativeName : string | undefined ) {
1106
+ // because relativeName is not guaranteed to be correct we need to check on each rename with few combinations
1107
+ // Eg on ubuntu while watching app/node_modules the relativeName is "node_modules" which is neither relative nor full path
1108
+ return event === "rename" &&
1109
+ ( ! relativeName ||
1110
+ relativeName === lastDirectoryPart ||
1111
+ relativeName . lastIndexOf ( lastDirectoryPartWithDirectorySeparator ! ) === relativeName . length - lastDirectoryPartWithDirectorySeparator ! . length ) &&
1112
+ ! fileSystemEntryExists ( fileOrDirectory , entryKind ) ?
1113
+ invokeCallbackAndUpdateWatcher ( watchMissingFileSystemEntry ) :
1114
+ callback ( event , relativeName ) ;
1115
+ }
1116
+
1093
1117
/**
1094
1118
* Watch the file or directory using fs.watchFile since fs.watch threw exception
1095
1119
* Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
1096
1120
*/
1097
1121
function watchPresentFileSystemEntryWithFsWatchFile ( ) : FileWatcher {
1122
+ sysLog ( `sysLog:: ${ fileOrDirectory } :: Changing to fsWatchFile` ) ;
1098
1123
return fallbackPollingWatchFile ( fileOrDirectory , createFileWatcherCallback ( callback ) , pollingInterval ) ;
1099
1124
}
1100
1125
0 commit comments