Skip to content

Commit

Permalink
refactor(pnpm): Make Pnpm separate from Npm
Browse files Browse the repository at this point in the history
Stop inheriting from `Npm` and rely entirely on the output of `pnpm`
commands to figure out the necessary information. For example, do not
re-construct the dependency from the file structure within
`node_modles`, but rely on `pnpm list` instead. This reduces complexity
and makes the implementation easy to understand, maintain or change.

From the diff of the expected result files it becomes aparent that this
change contains the following fixes:

1. htmlparser2 now dependends on domutils 1.7.0 instead of 1.5.1, which
   is inline with the dependency tree output by `pnpm list --depth 1000`
2. The cyclic reference from the workspace root project to itself is now
   included.

Also note that it good to drop the `--shamefully-hoist` command line
option, because it is not needed and its use is discouraged. Omiting it
may also reduce the amount of warnings.

Signed-off-by: Frank Viernau <[email protected]>
  • Loading branch information
fviernau committed Oct 25, 2024
1 parent 69895ae commit 9d3df9a
Show file tree
Hide file tree
Showing 6 changed files with 272 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ project:
- id: "NPM::domhandler:2.4.2"
dependencies:
- id: "NPM::domelementtype:1.3.1"
- id: "NPM::domutils:1.5.1"
- id: "NPM::domutils:1.7.0"
dependencies:
- id: "NPM::dom-serializer:0.1.1"
dependencies:
Expand Down Expand Up @@ -477,6 +477,36 @@ packages:
url: "https://github.com/FB55/domutils.git"
revision: "7d4bd16cd36ffce62362ef91616806ea27e30d95"
path: ""
- id: "NPM::domutils:1.7.0"
purl: "pkg:npm/[email protected]"
authors:
- "Felix Boehm"
declared_licenses:
- "BSD-2-Clause"
declared_licenses_processed:
spdx_expression: "BSD-2-Clause"
description: "utilities for working with htmlparser2's dom"
homepage_url: "https://github.com/FB55/domutils#readme"
binary_artifact:
url: ""
hash:
value: ""
algorithm: ""
source_artifact:
url: "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz"
hash:
value: "56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
algorithm: "SHA-1"
vcs:
type: "Git"
url: "git://github.com/FB55/domutils.git"
revision: "34f193ca17d11a98d9310b1965efe5f73d32d79f"
path: ""
vcs_processed:
type: "Git"
url: "https://github.com/FB55/domutils.git"
revision: "34f193ca17d11a98d9310b1965efe5f73d32d79f"
path: ""
- id: "NPM::eachr:3.3.0"
purl: "pkg:npm/[email protected]"
authors:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ analyzer:
- id: "NPM::json-stable-stringify:1.0.1"
dependencies:
- id: "NPM::jsonify:0.0.0"
- id: "PNPM::pnpm-workspaces:1.0.1"
linkage: "PROJECT_DYNAMIC"
dependencies:
- id: "NPM::json-stable-stringify:1.0.1"
dependencies:
- id: "NPM::jsonify:0.0.0"
- id: "PNPM::pnpm-workspaces:1.0.1"
linkage: "PROJECT_DYNAMIC"
- id: "PNPM::testing-pnpm-package-a:1.0.2"
definition_file_path: "plugins/package-managers/node/src/funTest/assets/projects/synthetic/pnpm/workspaces/src/packages/package-a/package.json"
authors:
Expand Down
4 changes: 2 additions & 2 deletions plugins/package-managers/node/src/main/kotlin/Npm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ open class Npm(
}
}

protected open fun getRemotePackageDetails(workingDir: File, packageName: String): PackageJson? {
internal open fun getRemotePackageDetails(workingDir: File, packageName: String): PackageJson? {
npmViewCache[packageName]?.let { return it }

return runCatching {
Expand Down Expand Up @@ -603,7 +603,7 @@ internal fun parsePackage(
return module
}

private fun parseProject(packageJsonFile: File, analysisRoot: File, managerName: String): Project {
internal fun parseProject(packageJsonFile: File, analysisRoot: File, managerName: String): Project {
Npm.logger.debug { "Parsing project info from '$packageJsonFile'." }

val packageJson = parsePackageJson(packageJsonFile)
Expand Down
48 changes: 48 additions & 0 deletions plugins/package-managers/node/src/main/kotlin/pnpm/ModuleInfo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (C) 2024 The ORT Project Authors (see <https://github.com/oss-review-toolkit/ort/blob/main/NOTICE>)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
* License-Filename: LICENSE
*/

package org.ossreviewtoolkit.plugins.packagemanagers.node.pnpm

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json

private val JSON = Json { ignoreUnknownKeys = true }

Check warning on line 25 in plugins/package-managers/node/src/main/kotlin/pnpm/ModuleInfo.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/ModuleInfo.kt#L25

Added line #L25 was not covered by tests

internal fun parsePnpmList(json: String): List<ModuleInfo> = JSON.decodeFromString(json)

Check warning on line 27 in plugins/package-managers/node/src/main/kotlin/pnpm/ModuleInfo.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/ModuleInfo.kt#L27

Added line #L27 was not covered by tests

@Serializable
internal data class ModuleInfo(
val name: String,
val version: String,
val path: String,
val private: Boolean,
val dependencies: Map<String, Dependency> = emptyMap(),
val devDependencies: Map<String, Dependency> = emptyMap(),
val optionalDependencies: Map<String, Dependency> = emptyMap()
) {
@Serializable
data class Dependency(
val from: String,
val version: String,
val resolved: String? = null,
val path: String,
val dependencies: Map<String, Dependency> = emptyMap(),
val optionalDependencies: Map<String, Dependency> = emptyMap()
)

Check warning on line 47 in plugins/package-managers/node/src/main/kotlin/pnpm/ModuleInfo.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/ModuleInfo.kt#L29-L47

Added lines #L29 - L47 were not covered by tests
}
113 changes: 102 additions & 11 deletions plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 The ORT Project Authors (see <https://github.com/oss-review-toolkit/ort/blob/main/NOTICE>)
* Copyright (C) 2024 The ORT Project Authors (see <https://github.com/oss-review-toolkit/ort/blob/main/NOTICE>)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,14 +21,24 @@ package org.ossreviewtoolkit.plugins.packagemanagers.node.pnpm

import java.io.File

import org.apache.logging.log4j.kotlin.logger

import org.ossreviewtoolkit.analyzer.AbstractPackageManagerFactory
import org.ossreviewtoolkit.analyzer.PackageManager
import org.ossreviewtoolkit.analyzer.PackageManagerResult
import org.ossreviewtoolkit.model.DependencyGraph
import org.ossreviewtoolkit.model.ProjectAnalyzerResult
import org.ossreviewtoolkit.model.config.AnalyzerConfiguration
import org.ossreviewtoolkit.model.config.RepositoryConfiguration
import org.ossreviewtoolkit.plugins.packagemanagers.node.Npm
import org.ossreviewtoolkit.model.utils.DependencyGraphBuilder
import org.ossreviewtoolkit.plugins.packagemanagers.node.PackageJson
import org.ossreviewtoolkit.plugins.packagemanagers.node.parsePackageJson
import org.ossreviewtoolkit.plugins.packagemanagers.node.parseProject
import org.ossreviewtoolkit.plugins.packagemanagers.node.utils.NodePackageManager
import org.ossreviewtoolkit.plugins.packagemanagers.node.utils.NpmDetection
import org.ossreviewtoolkit.utils.common.CommandLineTool
import org.ossreviewtoolkit.utils.common.Os
import org.ossreviewtoolkit.utils.common.realFile
import org.ossreviewtoolkit.utils.common.stashDirectories

import org.semver4j.RangesList
import org.semver4j.RangesListFactory
Expand All @@ -41,7 +51,7 @@ class Pnpm(
analysisRoot: File,
analyzerConfig: AnalyzerConfiguration,
repoConfig: RepositoryConfiguration
) : Npm(name, analysisRoot, analyzerConfig, repoConfig) {
) : PackageManager(name, analysisRoot, analyzerConfig, repoConfig), CommandLineTool {

Check warning on line 54 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L54

Added line #L54 was not covered by tests
class Factory : AbstractPackageManagerFactory<Pnpm>("PNPM") {
override val globsForDefinitionFiles = listOf("package.json", "pnpm-lock.yaml")

Expand All @@ -52,35 +62,116 @@ class Pnpm(
) = Pnpm(type, analysisRoot, analyzerConfig, repoConfig)

Check warning on line 62 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L62

Added line #L62 was not covered by tests
}

override fun hasLockfile(projectDir: File) = NodePackageManager.PNPM.hasLockfile(projectDir)
private val handler = PnpmDependencyHandler(this)
private val graphBuilder by lazy { DependencyGraphBuilder(handler) }
private val packageDetailsCache = mutableMapOf<String, PackageJson>()

Check warning on line 67 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L65-L67

Added lines #L65 - L67 were not covered by tests

override fun resolveDependencies(definitionFile: File, labels: Map<String, String>): List<ProjectAnalyzerResult> =
stashDirectories(definitionFile.resolveSibling("node_modules")).use {
resolveDependencies(definitionFile)
}

Check warning on line 72 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L70-L72

Added lines #L70 - L72 were not covered by tests

private fun resolveDependencies(definitionFile: File): List<ProjectAnalyzerResult> {
val workingDir = definitionFile.parentFile
installDependencies(workingDir)

Check warning on line 76 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L75-L76

Added lines #L75 - L76 were not covered by tests

val workspaceModuleDirs = getWorkspaceModuleDirs(workingDir)
handler.setWorkspaceModuleDirs(workspaceModuleDirs)

Check warning on line 79 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L78-L79

Added lines #L78 - L79 were not covered by tests

val moduleInfosForScope = Scope.entries.associateWith { scope -> listModules(workingDir, scope) }

Check warning on line 81 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L81

Added line #L81 was not covered by tests

return workspaceModuleDirs.map { projectDir ->
val project = parseProject(projectDir.resolve("package.json"), analysisRoot, managerName)

Check warning on line 84 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L83-L84

Added lines #L83 - L84 were not covered by tests

val scopeNames = Scope.entries.mapTo(mutableSetOf()) { scope ->
val scopeName = scope.toString()
val qualifiedScopeName = DependencyGraph.qualifyScope(project, scope.toString())
val moduleInfo = moduleInfosForScope.getValue(scope).single { it.path == projectDir.absolutePath }

Check warning on line 89 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L86-L89

Added lines #L86 - L89 were not covered by tests

override fun File.isWorkspaceDir() = realFile() in findWorkspaceSubmodules(analysisRoot)
moduleInfo.getScopeDependencies(scope).forEach { dependency ->
graphBuilder.addDependency(qualifiedScopeName, dependency)
}

Check warning on line 93 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L91-L93

Added lines #L91 - L93 were not covered by tests

override fun loadWorkspaceSubmodules(moduleDir: File): Set<File> {
val process = run(moduleDir, "list", "--recursive", "--depth=-1", "--parseable")
scopeName

Check warning on line 95 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L95

Added line #L95 was not covered by tests
}

return process.stdout.lines().filter { it.isNotEmpty() }.mapTo(mutableSetOf()) { File(it) }
ProjectAnalyzerResult(
project = project.copy(scopeNames = scopeNames),
packages = emptySet(),
issues = emptyList()
)

Check warning on line 102 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L98-L102

Added lines #L98 - L102 were not covered by tests
}
}

override fun command(workingDir: File?) = if (Os.isWindows) "pnpm.cmd" else "pnpm"

private fun getWorkspaceModuleDirs(workingDir: File): Set<File> {
val json = run(workingDir, "list", "--json", "--only-projects", "--recursive").stdout

Check warning on line 109 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L109

Added line #L109 was not covered by tests

return parsePnpmList(json).mapTo(mutableSetOf()) { File(it.path) }

Check warning on line 111 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L111

Added line #L111 was not covered by tests
}

private fun listModules(workingDir: File, scope: Scope): List<ModuleInfo> {
val scopeOption = when (scope) {
Scope.DEPENDENCIES -> "--prod"
Scope.DEV_DEPENDENCIES -> "--dev"

Check warning on line 117 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L116-L117

Added lines #L116 - L117 were not covered by tests
}

val json = run(workingDir, "list", "--json", "--recursive", "--depth", "10000", scopeOption).stdout

Check warning on line 120 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L120

Added line #L120 was not covered by tests

return parsePnpmList(json)

Check warning on line 122 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L122

Added line #L122 was not covered by tests
}

override fun createPackageManagerResult(projectResults: Map<File, List<ProjectAnalyzerResult>>) =
PackageManagerResult(projectResults, graphBuilder.build(), graphBuilder.packages())

Check warning on line 126 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L126

Added line #L126 was not covered by tests

override fun getVersionRequirement(): RangesList = RangesListFactory.create("5.* - 9.*")

Check warning on line 128 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L128

Added line #L128 was not covered by tests

override fun mapDefinitionFiles(definitionFiles: List<File>) =
NpmDetection(definitionFiles).filterApplicable(NodePackageManager.PNPM)

Check warning on line 131 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L131

Added line #L131 was not covered by tests

override fun runInstall(workingDir: File) =
private fun installDependencies(workingDir: File) =
run(
"install",
"--ignore-pnpmfile",
"--ignore-scripts",
"--frozen-lockfile", // Use the existing lockfile instead of updating an outdated one.
"--shamefully-hoist", // Build a similar node_modules structure as NPM and Yarn does.
workingDir = workingDir
)

Check warning on line 140 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L134-L140

Added lines #L134 - L140 were not covered by tests

override fun beforeResolution(definitionFiles: List<File>) =
// We do not actually depend on any features specific to a PNPM version, but we still want to stick to a
// fixed major version to be sure to get consistent results.
checkVersion()

Check warning on line 145 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L145

Added line #L145 was not covered by tests

internal fun getRemotePackageDetails(workingDir: File, packageName: String): PackageJson? {
packageDetailsCache[packageName]?.let { return it }

return runCatching {
val process = run(workingDir, "info", "--json", packageName)

Check warning on line 151 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L150-L151

Added lines #L150 - L151 were not covered by tests

parsePackageJson(process.stdout)

Check warning on line 153 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L153

Added line #L153 was not covered by tests
}.onFailure { e ->
logger.warn { "Error getting details for $packageName in directory $workingDir: ${e.message.orEmpty()}" }
}.getOrNull()?.also {
packageDetailsCache[packageName] = it
}

Check warning on line 158 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L157-L158

Added lines #L157 - L158 were not covered by tests
}
}

private enum class Scope(val descriptor: String) {
DEPENDENCIES("dependencies"),
DEV_DEPENDENCIES("devDependencies");

Check warning on line 164 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L162-L164

Added lines #L162 - L164 were not covered by tests

override fun toString(): String = descriptor
}

Check warning on line 167 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L166-L167

Added lines #L166 - L167 were not covered by tests

private fun ModuleInfo.getScopeDependencies(scope: Scope) =
when (scope) {
Scope.DEPENDENCIES -> buildList {
addAll(dependencies.values)
addAll(optionalDependencies.values)
}

Check warning on line 174 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L171-L174

Added lines #L171 - L174 were not covered by tests

Scope.DEV_DEPENDENCIES -> devDependencies.values.toList()
}

Check warning on line 177 in plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/Pnpm.kt#L176-L177

Added lines #L176 - L177 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (C) 2024 The ORT Project Authors (see <https://github.com/oss-review-toolkit/ort/blob/main/NOTICE>)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
* License-Filename: LICENSE
*/

package org.ossreviewtoolkit.plugins.packagemanagers.node.pnpm

import java.io.File

import org.ossreviewtoolkit.model.Identifier
import org.ossreviewtoolkit.model.Issue
import org.ossreviewtoolkit.model.Package
import org.ossreviewtoolkit.model.PackageLinkage
import org.ossreviewtoolkit.model.utils.DependencyHandler
import org.ossreviewtoolkit.plugins.packagemanagers.node.PackageJson
import org.ossreviewtoolkit.plugins.packagemanagers.node.parsePackage
import org.ossreviewtoolkit.plugins.packagemanagers.node.parsePackageJson
import org.ossreviewtoolkit.plugins.packagemanagers.node.pnpm.ModuleInfo.Dependency
import org.ossreviewtoolkit.utils.common.realFile

internal class PnpmDependencyHandler(private val pnpm: Pnpm) : DependencyHandler<Dependency> {
private val workspaceModuleDirs = mutableSetOf<File>()
private val packageJsonCache = mutableMapOf<File, PackageJson>()

Check warning on line 37 in plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt#L35-L37

Added lines #L35 - L37 were not covered by tests

private fun Dependency.isProject() = File(path).realFile().absoluteFile in workspaceModuleDirs

Check warning on line 39 in plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt#L39

Added line #L39 was not covered by tests

fun setWorkspaceModuleDirs(dirs: Collection<File>) {
workspaceModuleDirs.apply {
clear()
addAll(dirs)
}
}

Check warning on line 46 in plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt#L42-L46

Added lines #L42 - L46 were not covered by tests

override fun identifierFor(dependency: Dependency): Identifier {
val type = pnpm.managerName.takeIf { dependency.isProject() } ?: "NPM"
val namespace = dependency.from.substringBeforeLast("/", "")
val name = dependency.from.substringAfterLast("/")

Check warning on line 51 in plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt#L50-L51

Added lines #L50 - L51 were not covered by tests
val version = if (dependency.isProject()) {
readPackageJson(dependency.packageJsonFile).version.orEmpty()
} else {
dependency.version.takeUnless { it.startsWith("link:") || it.startsWith("file:") }.orEmpty()
}

return Identifier(type, namespace, name, version)

Check warning on line 58 in plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt#L58

Added line #L58 was not covered by tests
}

override fun dependenciesFor(dependency: Dependency): List<Dependency> =
(dependency.dependencies + dependency.optionalDependencies).values.toList()

Check warning on line 62 in plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt#L62

Added line #L62 was not covered by tests

override fun linkageFor(dependency: Dependency): PackageLinkage =
PackageLinkage.DYNAMIC.takeUnless { dependency.isProject() } ?: PackageLinkage.PROJECT_DYNAMIC

override fun createPackage(dependency: Dependency, issues: MutableCollection<Issue>): Package? =
dependency.takeUnless { it.isProject() }?.let {
parsePackage(
workingDir = it.workingDir,
packageJsonFile = it.packageJsonFile,
getRemotePackageDetails = pnpm::getRemotePackageDetails
)
}

Check warning on line 74 in plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt#L69-L74

Added lines #L69 - L74 were not covered by tests

private fun readPackageJson(packageJsonFile: File): PackageJson =
packageJsonCache.getOrPut(packageJsonFile.realFile()) { parsePackageJson(packageJsonFile) }

Check warning on line 77 in plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt#L77

Added line #L77 was not covered by tests
}

private val Dependency.workingDir: File get() = File(path)
private val Dependency.packageJsonFile: File get() = File(path, "package.json")

Check warning on line 81 in plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt

View check run for this annotation

Codecov / codecov/patch

plugins/package-managers/node/src/main/kotlin/pnpm/PnpmDependencyHandler.kt#L80-L81

Added lines #L80 - L81 were not covered by tests

0 comments on commit 9d3df9a

Please sign in to comment.