Only watch directories up to workspace root (#709)

* Don't watch beyond workspace root

* Catch errors when adding paths to chokidar watcher

* Normalize paths

* wip
master
Brad Cornes 2023-01-27 11:24:28 +00:00 committed by GitHub
parent 7fdf6c437d
commit 8c152bd650
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 11 deletions

View File

@ -346,16 +346,22 @@ function changeAffectsFile(change: string, files: string[]): boolean {
// We need to add parent directories to the watcher: // We need to add parent directories to the watcher:
// https://github.com/microsoft/vscode/issues/60813 // https://github.com/microsoft/vscode/issues/60813
function getWatchPatternsForFile(file: string): string[] { function getWatchPatternsForFile(file: string, root: string): string[] {
let tmp: string let tmp: string
let dir = path.dirname(file) let dir = path.dirname(file)
let patterns: string[] = [file, dir] let patterns: string[] = [file, dir]
if (dir === root) {
return patterns
}
while (true) { while (true) {
dir = path.dirname((tmp = dir)) dir = path.dirname((tmp = dir))
if (tmp === dir) { if (tmp === dir) {
break break
} else { } else {
patterns.push(dir) patterns.push(dir)
if (dir === root) {
break
}
} }
} }
return patterns return patterns
@ -440,8 +446,8 @@ async function createProjectService(
deps = getModuleDependencies(projectConfig.configPath) deps = getModuleDependencies(projectConfig.configPath)
} catch {} } catch {}
watchPatterns([ watchPatterns([
...getWatchPatternsForFile(projectConfig.configPath), ...getWatchPatternsForFile(projectConfig.configPath, projectConfig.folder),
...deps.flatMap((dep) => getWatchPatternsForFile(dep)), ...deps.flatMap((dep) => getWatchPatternsForFile(dep, projectConfig.folder)),
]) ])
} }
@ -459,7 +465,7 @@ async function createProjectService(
let file = normalizePath(change.file) let file = normalizePath(change.file)
let isConfigFile = changeAffectsFile(file, [projectConfig.configPath]) let isConfigFile = changeAffectsFile(file, [projectConfig.configPath])
let isDependency = changeAffectsFile(change.file, state.dependencies ?? []) let isDependency = changeAffectsFile(file, state.dependencies ?? [])
let isPackageFile = minimatch(file, `**/${PACKAGE_LOCK_GLOB}`, { dot: true }) let isPackageFile = minimatch(file, `**/${PACKAGE_LOCK_GLOB}`, { dot: true })
if (!isConfigFile && !isDependency && !isPackageFile) continue if (!isConfigFile && !isDependency && !isPackageFile) continue
@ -564,7 +570,7 @@ async function createProjectService(
throw new SilentError('No config file found.') throw new SilentError('No config file found.')
} }
watchPatterns(getWatchPatternsForFile(configPath)) watchPatterns(getWatchPatternsForFile(configPath, projectConfig.folder))
const pnpPath = findUp.sync( const pnpPath = findUp.sync(
(dir) => { (dir) => {
@ -576,7 +582,7 @@ async function createProjectService(
if (findUp.sync.exists(pnpFile)) { if (findUp.sync.exists(pnpFile)) {
return pnpFile return pnpFile
} }
if (dir === folder) { if (dir === path.normalize(folder)) {
return findUp.stop return findUp.stop
} }
}, },
@ -1062,7 +1068,11 @@ async function createProjectService(
// } // }
state.dependencies = getModuleDependencies(state.configPath) state.dependencies = getModuleDependencies(state.configPath)
// chokidarWatcher?.add(state.dependencies) // chokidarWatcher?.add(state.dependencies)
watchPatterns((state.dependencies ?? []).flatMap((dep) => getWatchPatternsForFile(dep))) watchPatterns(
(state.dependencies ?? []).flatMap((dep) =>
getWatchPatternsForFile(dep, projectConfig.folder)
)
)
state.configId = getConfigId(state.configPath, state.dependencies) state.configId = getConfigId(state.configPath, state.dependencies)
@ -1515,7 +1525,7 @@ async function getConfigFileFromCssFile(cssFile: string): Promise<string | null>
if (!match) { if (!match) {
return null return null
} }
return path.resolve(path.dirname(cssFile), match.groups.config.slice(1, -1)) return normalizePath(path.resolve(path.dirname(cssFile), match.groups.config.slice(1, -1)))
} }
function getPackageRoot(cwd: string, rootDir: string) { function getPackageRoot(cwd: string, rootDir: string) {
@ -1526,7 +1536,7 @@ function getPackageRoot(cwd: string, rootDir: string) {
if (findUp.sync.exists(pkgJson)) { if (findUp.sync.exists(pkgJson)) {
return pkgJson return pkgJson
} }
if (dir === rootDir) { if (dir === path.normalize(rootDir)) {
return findUp.stop return findUp.stop
} }
}, },
@ -1606,7 +1616,7 @@ class TW {
let ignore = globalSettings.tailwindCSS.files.exclude let ignore = globalSettings.tailwindCSS.files.exclude
let configFileOrFiles = globalSettings.tailwindCSS.experimental.configFile let configFileOrFiles = globalSettings.tailwindCSS.experimental.configFile
let base = normalizeFileNameToFsPath(this.initializeParams.rootPath) let base = normalizePath(normalizeFileNameToFsPath(this.initializeParams.rootPath))
let cssFileConfigMap: Map<string, string> = new Map() let cssFileConfigMap: Map<string, string> = new Map()
let configTailwindVersionMap: Map<string, string> = new Map() let configTailwindVersionMap: Map<string, string> = new Map()
@ -1640,7 +1650,7 @@ class TW {
([relativeConfigPath, relativeDocumentSelectorOrSelectors]) => { ([relativeConfigPath, relativeDocumentSelectorOrSelectors]) => {
return { return {
folder: base, folder: base,
configPath: path.resolve(userDefinedConfigBase, relativeConfigPath), configPath: normalizePath(path.resolve(userDefinedConfigBase, relativeConfigPath)),
documentSelector: [].concat(relativeDocumentSelectorOrSelectors).map((selector) => ({ documentSelector: [].concat(relativeDocumentSelectorOrSelectors).map((selector) => ({
priority: DocumentSelectorPriority.USER_CONFIGURED, priority: DocumentSelectorPriority.USER_CONFIGURED,
pattern: normalizePath(path.resolve(userDefinedConfigBase, selector)), pattern: normalizePath(path.resolve(userDefinedConfigBase, selector)),

View File

@ -2,11 +2,13 @@ import fs from 'fs'
import path from 'path' import path from 'path'
import resolve from 'resolve' import resolve from 'resolve'
import detective from 'detective' import detective from 'detective'
import normalizePath from 'normalize-path'
export function getModuleDependencies(modulePath: string): string[] { export function getModuleDependencies(modulePath: string): string[] {
return _getModuleDependencies(modulePath) return _getModuleDependencies(modulePath)
.map(({ file }) => file) .map(({ file }) => file)
.filter((file) => file !== modulePath) .filter((file) => file !== modulePath)
.map((file) => normalizePath(file))
} }
function createModule(file) { function createModule(file) {