mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Merge pull request #22976 from Microsoft/childWatches
Do not watch child directories of the sym link folders
This commit is contained in:
commit
4e76dec0b4
@ -334,9 +334,10 @@ namespace ts {
|
||||
/*@internal*/
|
||||
export interface RecursiveDirectoryWatcherHost {
|
||||
watchDirectory: HostWatchDirectory;
|
||||
getAccessileSortedChildDirectories(path: string): ReadonlyArray<string>;
|
||||
getAccessibleSortedChildDirectories(path: string): ReadonlyArray<string>;
|
||||
directoryExists(dir: string): boolean;
|
||||
filePathComparer: Comparer<string>;
|
||||
realpath(s: string): string;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -392,9 +393,14 @@ namespace ts {
|
||||
function watchChildDirectories(parentDir: string, existingChildWatches: ChildWatches, callback: DirectoryWatcherCallback): ChildWatches {
|
||||
let newChildWatches: DirectoryWatcher[] | undefined;
|
||||
enumerateInsertsAndDeletes<string, DirectoryWatcher>(
|
||||
host.directoryExists(parentDir) ? host.getAccessileSortedChildDirectories(parentDir) : emptyArray,
|
||||
host.directoryExists(parentDir) ? mapDefined(host.getAccessibleSortedChildDirectories(parentDir), child => {
|
||||
const childFullName = getNormalizedAbsolutePath(child, parentDir);
|
||||
// Filter our the symbolic link directories since those arent included in recursive watch
|
||||
// which is same behaviour when recursive: true is passed to fs.watch
|
||||
return host.filePathComparer(childFullName, host.realpath(childFullName)) === Comparison.EqualTo ? childFullName : undefined;
|
||||
}) : emptyArray,
|
||||
existingChildWatches,
|
||||
(child, childWatcher) => host.filePathComparer(getNormalizedAbsolutePath(child, parentDir), childWatcher.dirName),
|
||||
(child, childWatcher) => host.filePathComparer(child, childWatcher.dirName),
|
||||
createAndAddChildDirectoryWatcher,
|
||||
closeFileWatcher,
|
||||
addChildDirectoryWatcher
|
||||
@ -406,7 +412,7 @@ namespace ts {
|
||||
* Create new childDirectoryWatcher and add it to the new ChildDirectoryWatcher list
|
||||
*/
|
||||
function createAndAddChildDirectoryWatcher(childName: string) {
|
||||
const result = createDirectoryWatcher(getNormalizedAbsolutePath(childName, parentDir), callback);
|
||||
const result = createDirectoryWatcher(childName, callback);
|
||||
addChildDirectoryWatcher(result);
|
||||
}
|
||||
|
||||
@ -601,14 +607,7 @@ namespace ts {
|
||||
exit(exitCode?: number): void {
|
||||
process.exit(exitCode);
|
||||
},
|
||||
realpath(path: string): string {
|
||||
try {
|
||||
return _fs.realpathSync(path);
|
||||
}
|
||||
catch {
|
||||
return path;
|
||||
}
|
||||
},
|
||||
realpath,
|
||||
debugMode: some(<string[]>process.execArgv, arg => /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg)),
|
||||
tryEnableSourceMapsForHost() {
|
||||
try {
|
||||
@ -699,8 +698,9 @@ namespace ts {
|
||||
const watchDirectoryRecursively = createRecursiveDirectoryWatcher({
|
||||
filePathComparer: useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive,
|
||||
directoryExists,
|
||||
getAccessileSortedChildDirectories: path => getAccessibleFileSystemEntries(path).directories,
|
||||
watchDirectory
|
||||
getAccessibleSortedChildDirectories: path => getAccessibleFileSystemEntries(path).directories,
|
||||
watchDirectory,
|
||||
realpath
|
||||
});
|
||||
|
||||
return (directoryName, callback, recursive) => {
|
||||
@ -1043,6 +1043,15 @@ namespace ts {
|
||||
return filter<string>(_fs.readdirSync(path), dir => fileSystemEntryExists(combinePaths(path, dir), FileSystemEntryKind.Directory));
|
||||
}
|
||||
|
||||
function realpath(path: string): string {
|
||||
try {
|
||||
return _fs.realpathSync(path);
|
||||
}
|
||||
catch {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
function getModifiedTime(path: string) {
|
||||
try {
|
||||
return _fs.statSync(path).mtime;
|
||||
|
||||
@ -2358,6 +2358,50 @@ declare module "fs" {
|
||||
it("uses non recursive dynamic polling when renaming file in subfolder", () => {
|
||||
verifyRenamingFileInSubFolder(TestFSWithWatch.Tsc_WatchDirectory.DynamicPolling);
|
||||
});
|
||||
|
||||
it("when there are symlinks to folders in recursive folders", () => {
|
||||
const cwd = "/home/user/projects/myproject";
|
||||
const file1: FileOrFolder = {
|
||||
path: `${cwd}/src/file.ts`,
|
||||
content: `import * as a from "a"`
|
||||
};
|
||||
const tsconfig: FileOrFolder = {
|
||||
path: `${cwd}/tsconfig.json`,
|
||||
content: `{ "compilerOptions": { "extendedDiagnostics": true, "traceResolution": true }}`
|
||||
};
|
||||
const realA: FileOrFolder = {
|
||||
path: `${cwd}/node_modules/reala/index.d.ts`,
|
||||
content: `export {}`
|
||||
};
|
||||
const realB: FileOrFolder = {
|
||||
path: `${cwd}/node_modules/realb/index.d.ts`,
|
||||
content: `export {}`
|
||||
};
|
||||
const symLinkA: FileOrFolder = {
|
||||
path: `${cwd}/node_modules/a`,
|
||||
symLink: `${cwd}/node_modules/reala`
|
||||
};
|
||||
const symLinkB: FileOrFolder = {
|
||||
path: `${cwd}/node_modules/b`,
|
||||
symLink: `${cwd}/node_modules/realb`
|
||||
};
|
||||
const symLinkBInA: FileOrFolder = {
|
||||
path: `${cwd}/node_modules/reala/node_modules/b`,
|
||||
symLink: `${cwd}/node_modules/b`
|
||||
};
|
||||
const symLinkAInB: FileOrFolder = {
|
||||
path: `${cwd}/node_modules/realb/node_modules/a`,
|
||||
symLink: `${cwd}/node_modules/a`
|
||||
};
|
||||
const files = [file1, tsconfig, realA, realB, symLinkA, symLinkB, symLinkBInA, symLinkAInB];
|
||||
const environmentVariables = createMap<string>();
|
||||
environmentVariables.set("TSC_WATCHDIRECTORY", TestFSWithWatch.Tsc_WatchDirectory.NonRecursiveWatchDirectory);
|
||||
const host = createWatchedSystem(files, { environmentVariables, currentDirectory: cwd });
|
||||
createWatchOfConfigFile("tsconfig.json", host);
|
||||
checkWatchedDirectories(host, emptyArray, /*recursive*/ true);
|
||||
checkWatchedDirectories(host, [cwd, `${cwd}/node_modules`, `${cwd}/node_modules/@types`, `${cwd}/node_modules/reala`, `${cwd}/node_modules/realb`,
|
||||
`${cwd}/node_modules/reala/node_modules`, `${cwd}/node_modules/realb/node_modules`, `${cwd}/src`], /*recursive*/ false);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -312,18 +312,20 @@ interface Array<T> {}`
|
||||
const watchDirectory: HostWatchDirectory = (directory, cb) => this.watchFile(directory, () => cb(directory), PollingInterval.Medium);
|
||||
this.customRecursiveWatchDirectory = createRecursiveDirectoryWatcher({
|
||||
directoryExists: path => this.directoryExists(path),
|
||||
getAccessileSortedChildDirectories: path => this.getDirectories(path),
|
||||
getAccessibleSortedChildDirectories: path => this.getDirectories(path),
|
||||
filePathComparer: this.useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive,
|
||||
watchDirectory
|
||||
watchDirectory,
|
||||
realpath: s => this.realpath(s)
|
||||
});
|
||||
}
|
||||
else if (tscWatchDirectory === Tsc_WatchDirectory.NonRecursiveWatchDirectory) {
|
||||
const watchDirectory: HostWatchDirectory = (directory, cb) => this.watchDirectory(directory, fileName => cb(fileName), /*recursive*/ false);
|
||||
this.customRecursiveWatchDirectory = createRecursiveDirectoryWatcher({
|
||||
directoryExists: path => this.directoryExists(path),
|
||||
getAccessileSortedChildDirectories: path => this.getDirectories(path),
|
||||
getAccessibleSortedChildDirectories: path => this.getDirectories(path),
|
||||
filePathComparer: this.useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive,
|
||||
watchDirectory
|
||||
watchDirectory,
|
||||
realpath: s => this.realpath(s)
|
||||
});
|
||||
}
|
||||
else if (tscWatchDirectory === Tsc_WatchDirectory.DynamicPolling) {
|
||||
@ -331,9 +333,10 @@ interface Array<T> {}`
|
||||
const watchDirectory: HostWatchDirectory = (directory, cb) => watchFile(directory, () => cb(directory), PollingInterval.Medium);
|
||||
this.customRecursiveWatchDirectory = createRecursiveDirectoryWatcher({
|
||||
directoryExists: path => this.directoryExists(path),
|
||||
getAccessileSortedChildDirectories: path => this.getDirectories(path),
|
||||
getAccessibleSortedChildDirectories: path => this.getDirectories(path),
|
||||
filePathComparer: this.useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive,
|
||||
watchDirectory
|
||||
watchDirectory,
|
||||
realpath: s => this.realpath(s)
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -649,7 +652,7 @@ interface Array<T> {}`
|
||||
|
||||
const realpath = this.realpath(path);
|
||||
if (path !== realpath) {
|
||||
return this.getRealFsEntry(isFsEntry, realpath as Path);
|
||||
return this.getRealFsEntry(isFsEntry, this.toPath(realpath));
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user