From 193b852534d0f5a5a8424e9eae2387722ef98cd8 Mon Sep 17 00:00:00 2001 From: DavHau Date: Wed, 2 Mar 2022 15:33:54 +0700 Subject: [PATCH] yarn-translator: enable workspace support --- src/discoverers/nodejs/default.nix | 2 +- .../nodejs/pure/yarn-lock/default.nix | 98 +++++++++++++------ src/utils/translator2.nix | 33 ++++--- 3 files changed, 92 insertions(+), 41 deletions(-) diff --git a/src/discoverers/nodejs/default.nix b/src/discoverers/nodejs/default.nix index cd458e50..b67e9e68 100644 --- a/src/discoverers/nodejs/default.nix +++ b/src/discoverers/nodejs/default.nix @@ -73,7 +73,7 @@ let translators = l.unique ( - (lib.filter (trans: trans == "package-lock") parentInfo.translators) + (lib.filter (trans: l.elem trans ["package-lock" "yarn-lock"]) parentInfo.translators) ++ (getTranslatorNames "${tree.fullPath}/${wsRelPath}") ); subsystemInfo = { diff --git a/src/translators/nodejs/pure/yarn-lock/default.nix b/src/translators/nodejs/pure/yarn-lock/default.nix index 70256945..2e224ccc 100644 --- a/src/translators/nodejs/pure/yarn-lock/default.nix +++ b/src/translators/nodejs/pure/yarn-lock/default.nix @@ -23,7 +23,7 @@ let ... }@args: let - # filteredProjects = nodejsUtils.filterProjects projects; + filteredProjects = nodejsUtils.filterProjects projects; parser = import ./parser.nix { inherit lib; }; @@ -41,9 +41,9 @@ let yarnLock = parser.parse (getYarnLock proj).content; relPath = proj.relPath; - # workspaces = proj.subsystemInfo.workspaces or []; + workspaces = proj.subsystemInfo.workspaces or []; }) - projects; + filteredProjects; in allProjectsTranslated; @@ -58,7 +58,7 @@ let # subsystem specific yarnLock, relPath, - # workspaces, + workspaces, # extraArgs name, @@ -71,24 +71,22 @@ let b = builtins; dev = ! noDev; + defaultPackage = + if name != "{automatic}" then + name + else + packageJson.name or (throw ( + "Could not identify package name. " + + "Please specify extra argument 'name'" + )); + packageJson = (tree.getNodeFromPath "package.json").jsonContent; packageJsonDeps = nodejsUtils.getPackageJsonDeps packageJson noDev; - # workspacesPackageJson = utils.getWorkspacePackageJson tree workspaces; + workspacesPackageJson = nodejsUtils.getWorkspacePackageJson tree workspaces; - # workspaceYarnEntries = workspace - # l.map - # (ws: - # let - # json = - # (tree.getNodeFromPath "${wsRelPath}/package.json").jsonContent; - # in { - - # } - # ) - # workspacesPackageJson."${workspace}".; in utils.simpleTranslate2 @@ -97,6 +95,48 @@ let ... }: let + makeWorkspaceExtraObject = workspace: let + json = workspacesPackageJson."${workspace}"; + name = json.name or workspace; + version = json.version or "unknown"; + in + { + inherit name version; + + dependencies = + l.mapAttrsToList + (depName: semVer: let + yarnName = "${depName}@${semVer}"; + depObject = objectsByKey.yarnName."${yarnName}"; + in + if exportedWorkspacePackages ? "${depName}" + then + { + name = depName; + version = exportedWorkspacePackages."${depName}"; + } + else {name = depName; version = depObject.version;}) + (nodejsUtils.getPackageJsonDeps json noDev); + + sourceSpec = { + type = "path"; + path = workspace; + rootName = defaultPackage; + rootVersion = packageJson.version or "unknown"; + }; + }; + + extraObjects = l.map makeWorkspaceExtraObject workspaces; + + exportedWorkspacePackages = + l.listToAttrs + (l.map + (wsObject: + l.nameValuePair + wsObject.name + wsObject.version) + extraObjects); + getSourceType = rawObj: finalObj: let dObj = rawObj; in @@ -133,20 +173,11 @@ let in rec { - inherit translatorName; - - defaultPackage = - if name != "{automatic}" then - name - else - packageJson.name or (throw ( - "Could not identify package name. " - + "Please specify extra argument 'name'" - )); + inherit defaultPackage extraObjects translatorName; exportedPackages = - { "${defaultPackage}" = packageJson.version or "unknown"; }; - # // (nodejsUtils.getWorkspacePackages tree workspaces); + { "${defaultPackage}" = packageJson.version or "unknown"; } + // exportedWorkspacePackages; subsystemName = "nodejs"; @@ -176,7 +207,16 @@ let lib.head split; version = rawObj: finalObj: - rawObj.version; + if l.hasInfix "@git+" rawObj.yarnName + then + let + split = l.splitString "@git+" rawObj.yarnName; + gitUrl = l.last split; + in + # l.strings.sanitizeDerivationName + "${rawObj.version}@git+${gitUrl}" + + else rawObj.version; dependencies = rawObj: finalObj: let dependencies = let diff --git a/src/utils/translator2.nix b/src/utils/translator2.nix index 4b9ea9ae..d76c568f 100644 --- a/src/utils/translator2.nix +++ b/src/utils/translator2.nix @@ -62,7 +62,7 @@ let merged // {"${keyFunc finalObj.rawObj finalObj}" = finalObj;}) {} - finalObjects) + finalObjects') final.keys; @@ -86,13 +86,13 @@ let allDependencies = l.foldl' (result: finalObj: - lib.recursiveUpdate - result - { - "${finalObj.name}" = { - "${finalObj.version}" = finalObj; - }; - }) + lib.recursiveUpdate + result + { + "${finalObj.name}" = { + "${finalObj.version}" = finalObj; + }; + }) {} finalObjects; @@ -132,10 +132,21 @@ let cyclicDependencies = # TODO: inefficient! Implement some kind of early cutoff let + depGraphWithFakeRoot = + l.recursiveUpdate + dependencyGraph + { + __fake-entry.__fake-version = + l.mapAttrsToList + dlib.nameVersionPair + exportedPackages; + }; + findCycles = node: prevNodes: cycles: let - children = dependencyGraph."${node.name}"."${node.version}"; + children = + depGraphWithFakeRoot."${node.name}"."${node.version}"; cyclicChildren = lib.filter @@ -169,8 +180,8 @@ let cyclesList = findCycles (dlib.nameVersionPair - defaultPackage - exportedPackages."${defaultPackage}") + "__fake-entry" + "__fake-version") {} []; in