From 628c84c831b6a66cb286e8a82012a31a44ff10b8 Mon Sep 17 00:00:00 2001 From: Jaka Hudoklin Date: Sat, 24 Jan 2015 22:54:03 +0100 Subject: [PATCH] nodePackages: refactor, add support for overrides --- .../web/nodejs/build-node-package.nix | 112 +++++++++++------- pkgs/top-level/all-packages.nix | 8 +- pkgs/top-level/node-packages.nix | 65 +++++++--- 3 files changed, 121 insertions(+), 64 deletions(-) diff --git a/pkgs/development/web/nodejs/build-node-package.nix b/pkgs/development/web/nodejs/build-node-package.nix index a76d45e52740..729ee8b93650 100644 --- a/pkgs/development/web/nodejs/build-node-package.nix +++ b/pkgs/development/web/nodejs/build-node-package.nix @@ -1,6 +1,32 @@ { stdenv, runCommand, nodejs, neededNatives}: -args @ { name, src, deps ? {}, peerDependencies ? [], flags ? [], preShellHook ? "", postShellHook ? "", resolvedDeps ? {}, bin ? null, ... }: +{ + name, src, + + # List or attribute set of dependencies + deps ? {}, + + # List or attribute set of peer depencies + peerDependencies ? [], + + # Whether package is binary or library + bin ? null, + + # Flags passed to npm install + flags ? [], + + # Command to be run before shell hook + preShellHook ? "", + + # Command to be run after shell hook + postShellHook ? "", + + # Attribute set of already resolved deps (internal), + # for avoiding infinite recursion + resolvedDeps ? {}, + + ... +} @ args: with stdenv.lib; @@ -12,6 +38,9 @@ let mv *node* $out ''; + # Package name without version + pkgName = (builtins.parseDrvName name).name; + # Convert deps to attribute set attrDeps = if isAttrs deps then deps else (listToAttrs (map (dep: nameValuePair dep.name dep) deps)); @@ -22,10 +51,7 @@ let # Recursive dependencies that we want to avoid with shim creation recursiveDeps = removeAttrs attrDeps (attrNames requiredDeps); - peerDeps = listToAttrs (concatMap (dep: map (name: { - inherit name; - value = dep; - }) (filter (nm: !(elem nm (args.passthru.names or []))) dep.names)) (peerDependencies)); + peerDeps = filter (dep: dep.pkgName != pkgName) peerDependencies; self = let # Pass resolved dependencies to dependencies of this package @@ -121,29 +147,29 @@ let # Symlink or copy dependencies for node modules # copy is needed if dependency has recursive dependencies, # because node can't follow symlinks while resolving recursive deps. - ${concatStrings (concatMap (dep: map (name: + ${concatMapStrings (dep: if dep.recursiveDeps == [] then '' - ln -sv ${dep}/lib/node_modules/${name} node_modules/ + ln -sv ${dep}/lib/node_modules/${dep.pkgName} node_modules/ '' else '' - cp -R ${dep}/lib/node_modules/${name} node_modules/ + cp -R ${dep}/lib/node_modules/${dep.pkgName} node_modules/ '' - ) dep.names) deps)} + ) deps} # Symlink peer dependencies - ${concatStrings (mapAttrsToList (name: dep: '' - ln -sv ${dep}/lib/node_modules/${name} node_modules/ - '') peerDeps)} + ${concatMapStrings (dep: '' + ln -sv ${dep}/lib/node_modules/${dep.pkgName} node_modules/ + '') peerDeps} # Create shims for recursive dependenceies - ${concatStrings (concatMap (dep: map (name: '' - mkdir -p node_modules/${name} - cat > node_modules/${name}/package.json < node_modules/${dep.pkgName}/package.json </dev/null || true @@ -214,19 +238,21 @@ let runHook postInstall ''; - preFixup = concatStringsSep "\n" (map (src: '' + preFixup = '' find $out -type f -print0 | xargs -0 sed -i 's|${src}|${src.name}|g' - '') src); + ''; shellHook = '' ${preShellHook} export PATH=${nodejs}/bin:$(pwd)/node_modules/.bin:$PATH mkdir -p node_modules - ${concatStrings (concatMap (dep: map (name: '' - ln -sfv ${dep}/lib/node_modules/${name} node_modules/ - '') dep.names) deps)} + ${concatMapStrings (dep: '' + ln -sfv ${dep}/lib/node_modules/${dep.pkgName} node_modules/ + '') deps} ${postShellHook} ''; + + passthru.pkgName = pkgName; } // (filterAttrs (n: v: n != "deps" && n != "resolvedDeps") args) // { name = "${ if bin == true then "bin-" else if bin == false then "node-" else "" diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 1e45eda1757f..5c917d9cf7f2 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -1664,11 +1664,9 @@ let nodejs = callPackage ../development/web/nodejs { }; nodejs-unstable = callPackage ../development/web/nodejs { unstableVersion = true; }; - nodePackages = recurseIntoAttrs (callPackage ./node-packages.nix { - inherit pkgs stdenv nodejs fetchurl fetchgit; - neededNatives = [python] ++ lib.optional (lib.elem system lib.platforms.linux) utillinux; - self = pkgs.nodePackages; - }); + nodePackages = recurseIntoAttrs ( + callPackage ./node-packages.nix { self = nodePackages; } + ); ldapvi = callPackage ../tools/misc/ldapvi { }; diff --git a/pkgs/top-level/node-packages.nix b/pkgs/top-level/node-packages.nix index 9127dfbbb435..e8f0a9997c98 100644 --- a/pkgs/top-level/node-packages.nix +++ b/pkgs/top-level/node-packages.nix @@ -1,23 +1,56 @@ -{ pkgs, stdenv, nodejs, fetchurl, fetchgit, neededNatives, self, generated ? ./node-packages-generated.nix }: +{ + stdenv, pkgs, nodejs + + # Self-reference +, self + + # Needed natives for installation +, neededNatives ? [pkgs.python] ++ stdenv.lib.optionals stdenv.isLinux [ pkgs.utillinux ] + + # Attribute set of generated packages +, generated ? pkgs.callPackage ./node-packages-generated.nix { inherit self; } + + # Attribute set of overrides +, overrides ? {} +, ... +} @ args: + +with stdenv.lib; rec { - nativeDeps = { - "node-expat" = [ pkgs.expat ]; - "node-stringprep" = [ pkgs.icu pkgs.which ]; - "rbytes" = [ pkgs.openssl ]; - "phantomjs" = [ pkgs.phantomjs ]; - "node-protobuf" = [ pkgs.protobuf ]; - }; + overrides = { + phantomjs.buildInputs = [ pkgs.phantomjs ]; + "node-expat".buildInputs = [ pkgs.expat ]; + "node-stringprep".buildInputs = [ pkgs.icu pkgs.which ]; + "node-protobuf".buildInputs = [ pkgs.protobuf ]; + "rbytes".buildInputs = [ pkgs.openssl ]; + } // args.overrides or {}; - buildNodePackage = import ../development/web/nodejs/build-node-package.nix { - inherit stdenv nodejs neededNatives; - inherit (pkgs) runCommand; - }; + # Apply overrides and back compatiblity transformations + buildNodePackage = {...} @ args: + let + pkg = makeOverridable ( + pkgs.callPackage ../development/web/nodejs/build-node-package.nix { + inherit nodejs neededNatives; + } + ) (args // { + # Backwards compatibility + src = if isList args.src then head args.src else args.src; + pkgName = (builtins.parseDrvName args.name).name; + }); + override = overrides.${args.name} or overrides.${pkg.pkgName} or {}; + + in pkg.override override; + + # Backwards compatibility patchSource = fn: srcAttrs: fn srcAttrs; - - # Backwards compat - patchLatest = patchSource fetchurl; + patchLatest = patchSource pkgs.fetchurl; /* Put manual packages below here (ideally eventually managed by npm2nix */ -} // import generated { inherit self fetchurl fetchgit; inherit (pkgs) lib; } +} // ( + if isAttrs generated then generated + + # Backwards compatiblity + else pkgs.callPackage generated { inherit self; } +)