From 29741906b21142bfe8291083f03b0e1c574499fb Mon Sep 17 00:00:00 2001 From: DavHau Date: Wed, 2 Mar 2022 18:58:53 +0700 Subject: [PATCH] Handle edge cases with npm workspaces: - fixes #93 - package.json workspaces is an attrset instead of list - workspaces pointing to non-existent directory - workspaces pointing to a directory whithout a package.json --- src/discoverers/nodejs/default.nix | 52 +++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/src/discoverers/nodejs/default.nix b/src/discoverers/nodejs/default.nix index b67e9e68..755309da 100644 --- a/src/discoverers/nodejs/default.nix +++ b/src/discoverers/nodejs/default.nix @@ -43,19 +43,63 @@ let if l.hasSuffix "*" glob then let prefix = l.removeSuffix "*" glob; - dirNames = dlib.listDirs "${tree.fullPath}/${prefix}"; + path = "${tree.fullPath}/${prefix}"; + + dirNames = + if l.pathExists path + then dlib.listDirs path + else + l.trace + "WARNING: Detected workspace ${glob} does not exist." + []; + + existingWsPaths = + l.filter + (wsPath: + if l.pathExists "${path}/${wsPath}/package.json" + then true + else + let + notExistingPath = + dlib.sanitizeRelativePath "${prefix}/${wsPath}"; + in + l.trace + "WARNING: Detected workspace ${notExistingPath} does not exist." + false) + dirNames; in - l.map (dname: "${prefix}/${dname}") dirNames + l.map (dname: "${prefix}/${dname}") existingWsPaths + else - [ glob ]; + if l.pathExists "${tree.fullPath}/${glob}/package.json" + then [ glob ] + else + l.trace + "WARNING: Detected workspace ${glob} does not exist." + []; # collect project info for workspaces defined by current package.json getWorkspaces = tree: parentInfo: let packageJson = tree.files."package.json".jsonContent; + workspacesRaw = packageJson.workspaces or []; + + workspacesFlattened = + if l.isAttrs workspacesRaw + then + l.flatten + (l.mapAttrsToList + (category: workspaces: workspaces) + workspacesRaw) + + else if l.isList workspacesRaw + then workspacesRaw + + else throw "Error parsing workspaces in ${tree.files."package.json".relPath}"; + in l.flatten - (l.forEach (packageJson.workspaces or []) + (l.forEach workspacesFlattened (glob: let workspacePaths = getWorkspacePaths glob tree;