Skip to content

Commit

Permalink
fix(node): Do not follow cyclic directory links
Browse files Browse the repository at this point in the history
This implements a proper solution for the `maxDepth`-related work-around
introduced for PNPM in 18d8903 to fix a similar issue for Yarn if the
`node_modules` directory hierarchy contains cyclic links. This is done
by maintaining a temporary set of visited "real" directories.

The issue was interesting to debug as the infinite loop caused by
circular links was only triggered when actually evaluating the lazy
sequence created by `File.walk()`.

Fixes #6531.

Signed-off-by: Sebastian Schuberth <[email protected]>
  • Loading branch information
sschuberth committed Jan 24, 2024
1 parent c6793a6 commit 360dbe1
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 14 deletions.
12 changes: 5 additions & 7 deletions plugins/package-managers/node/src/main/kotlin/Npm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,6 @@ open class Npm(

private val npmViewCache = ConcurrentHashMap<String, Deferred<JsonNode>>()

/**
* Search depth in the `node_modules` directory for `package.json` files used for collecting all packages of the
* projects.
*/
protected open val modulesSearchDepth = Int.MAX_VALUE

protected open fun hasLockFile(projectDir: File) = NodePackageManager.NPM.hasLockFile(projectDir)

/**
Expand Down Expand Up @@ -246,7 +240,11 @@ open class Npm(

logger.info { "Searching for 'package.json' files in '$nodeModulesDir'..." }

val nodeModulesFiles = nodeModulesDir.walk().maxDepth(modulesSearchDepth).filter {
val visitedDirs = mutableSetOf<File>()

val nodeModulesFiles = nodeModulesDir.walk().onEnter { dir ->
!dir.isSymbolicLink() || visitedDirs.add(dir.realFile())
}.filter {
it.isFile && it.name == "package.json" &&
isValidNodeModulesDirectory(nodeModulesDir, nodeModulesDirForPackageJson(it))
}
Expand Down
7 changes: 0 additions & 7 deletions plugins/package-managers/node/src/main/kotlin/Pnpm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,6 @@ class Pnpm(
) = Pnpm(type, analysisRoot, analyzerConfig, repoConfig)
}

/**
* PNPM symlinks workspace modules in the `node_modules` directory, which will result in cyclic symlinks of
* `node_module` directories. Limit the search depth to '2' in this case as all packages are in a direct
* subdirectory of the `node_modules` directory, thanks to the `--shamefully-hoist` install option.
*/
override val modulesSearchDepth = 2

override fun hasLockFile(projectDir: File) = NodePackageManager.PNPM.hasLockFile(projectDir)

override fun File.isWorkspaceDir() = realFile() in findWorkspaceSubmodules(analysisRoot)
Expand Down

0 comments on commit 360dbe1

Please sign in to comment.