[Nix-dev] Infinite recursion with npm2nix

Shea Levy shea at shealevy.com
Tue Apr 15 15:27:54 CEST 2014


Hi Colin,

I've added pure-0.5.0-rc-1 to nixpkgs, can you try using that as a
dependency?

Thanks,
Shea

On Mon, Apr 14, 2014 at 10:01:44AM -0500, Colin Putney wrote:
> Hi folks,
> 
> In my on-going quest to package up my node applications, I've run into a
> noob-trap that has me completely stumped.
> 
> The app is a web app, so it has both client- and server-side code. One of
> the dependencies is Yahoo's Pure CSS library. PureCSS, in turn relies on
> Grunt for its build process. I've created the following nix expressions:
> 
> $ cat purecss.nix
> { pkgs ? import <nixpkgs> {} }:
> 
> with pkgs.stdenv.lib;
> 
> let
> 
>   name = "pure-css";
>   version = "v0.5.0-rc-1";
> 
>   # pull in the code for building npm packages
>   nodePackages = import ./purecss-npm-packages.nix {
>     inherit pkgs;
>     inherit (pkgs) stdenv nodejs fetchurl fetchgit;
>     neededNatives = [ pkgs.python ] ++ pkgs.lib.optional
> pkgs.stdenv.isLinux pkgs.utillinux;
>     self = nodePackages;
>   };
> 
>   buildModules = [
>      nodePackages."bower"
>      nodePackages."grunt"
>      nodePackages."grunt-cli"
>      nodePackages."grunt-contrib-cssmin"
>      nodePackages."grunt-contrib-clean"
>      nodePackages."grunt-contrib-copy"
>      nodePackages."grunt-contrib-concat"
>      nodePackages."grunt-contrib-compress"
>      nodePackages."grunt-contrib-csslint"
>      nodePackages."grunt-contrib-watch"
>      nodePackages."grunt-css-selectors"
>      nodePackages."grunt-pure-grids"
>      nodePackages."grunt-stripmq"
>   ];
> 
> in pkgs.stdenv.mkDerivation {
> 
>   name = "${name}-${version}";
> 
>   src = pkgs.fetchgit {
>     url = https://github.com/yui/pure;
>     rev = "refs/tags/v0.5.0-rc-1";
>     sha256 =
> "049ac2ef812771852978d11cd5aecac2dd561e97bb16ad89c79eb1e10aa57672";
>   };
> 
>   buildInputs = buildModules;
> 
>   buildCommand = ''
>     cp -r $src src
>     chmod +w src
>     cd src
>     grunt
>   '';
> 
> }
> 
> 
> $ cat purecss-npm-packages.nix
> { pkgs, stdenv, nodejs, fetchurl, fetchgit, neededNatives, self }:
> 
> rec {
> 
>   nativeDeps = {};
> 
>   buildNodePackage = import
> "${pkgs.path}/pkgs/development/web/nodejs/build-node-package.nix" {
>     inherit stdenv nodejs neededNatives;
>     inherit (pkgs) runCommand;
>   };
> 
>   patchSource = fn: srcAttrs:
>     let src = fn srcAttrs; in pkgs.runCommand src.name {} ''
>       mkdir unpack
>       cd unpack
>       unpackFile ${src}
>       chmod -R +w */
>       mv */ package 2>/dev/null || true
>       sed -i -e "s/:\s*\"latest\"/:  \"*\"/" -e
> "s/:\s*\"\(https\?\|git\(\+\(ssh\|http\|https\)\)\?\):\/\/[^\"]*\"/:
> \"*\"/" package/package.json
>       mv */ $out
>     '';
> 
>   # Backwards compat
>   patchLatest = patchSource fetchurl;
> 
> } // import ./purecss-npm-generated.nix { inherit self fetchurl fetchgit;
> inherit (pkgs) lib; }
> 
> 
> The file purecss-npm-generated.nix is about 4000 lines of nix expressions
> generated by npm2nix.
> 
> 
> 
> Now, the problem is this:
> 
> error: while evaluating the attribute `nativeBuildInputs' of the derivation
> `pure-css-v0.5.0-rc-1' at
> /Users/colin/Better/usul/edric/harah/purecss.nix:36:3:
> while evaluating the attribute `deps' of the derivation
> `node-grunt-css-selectors-1.0.0' at
> /Users/colin/Better/usul/edric/harah/purecss-npm-generated.nix:1807:5:
> while evaluating the attribute `deps' of the derivation
> `node-rework-0.20.2' at
> /Users/colin/Better/usul/edric/harah/purecss-npm-generated.nix:3389:5:
> while evaluating the attribute `nativeBuildInputs' of the derivation
> `node-rework-inherit-0.2.1' at
> /Users/colin/Better/usul/edric/harah/purecss-npm-generated.nix:3426:5:
> infinite recursion encountered
> 
> 
> The relevant section of the generated code is here:
> 
> 
>   by-spec."rework".">= 0.15.0" =
>     self.by-version."rework"."0.20.2";
>   by-version."rework"."0.20.2" = lib.makeOverridable self.buildNodePackage {
>     name = "node-rework-0.20.2";
>     src = [
>       (fetchurl {
>         url = "http://registry.npmjs.org/rework/-/rework-0.20.2.tgz";
>         name = "rework-0.20.2.tgz";
>         sha1 = "b64b082a1660cf33c874729353ead5341c100d23";
>       })
>     ];
>     buildInputs =
>       (self.nativeDeps."rework" or []);
>     deps = [
>       self.by-version."css"."1.6.0"
>       self.by-version."commander"."1.0.4"
>       self.by-version."color-parser"."0.1.0"
>       self.by-version."hsb2rgb"."1.0.2"
>       self.by-version."mime"."1.2.11"
>       self.by-version."debug"."0.8.0"
>       self.by-version."rework-inherit"."0.2.1"
>       self.by-version."rework-visit"."1.0.0"
>       self.by-version."convert-source-map"."0.3.3"
>       self.by-version."rework"."0.20.2"
>     ];
>     peerDependencies = [
>     ];
>     passthru.names = [ "rework" ];
>   };
>   by-spec."rework".">=0.18.0" =
>     self.by-version."rework"."0.20.2";
>   by-spec."rework".">=0.20.2-0 <0.21.0-0" =
>     self.by-version."rework"."0.20.2";
>   by-spec."rework".">=0.20.2-0 >=0.20.2-0 <0.21.0-0" =
>     self.by-version."rework"."0.20.2";
>   by-spec."rework"."~0.20.2" =
>     self.by-version."rework"."0.20.2";
>   by-spec."rework-inherit"."0.2.1" =
>     self.by-version."rework-inherit"."0.2.1";
>   by-version."rework-inherit"."0.2.1" = lib.makeOverridable
> self.buildNodePackage {
>     name = "node-rework-inherit-0.2.1";
>     src = [
>       (fetchurl {
>         url = "
> http://registry.npmjs.org/rework-inherit/-/rework-inherit-0.2.1.tgz";
>         name = "rework-inherit-0.2.1.tgz";
>         sha1 = "fdd01a199b0a86ef909436fb373f7b343936f185";
>       })
>     ];
>     buildInputs =
>       (self.nativeDeps."rework-inherit" or []);
>     deps = [
>       self.by-version."debug"."0.8.0"
>     ];
>     peerDependencies = [
>       self.by-version."rework"."0.20.2"
>     ];
>     passthru.names = [ "rework-inherit" ];
>   };
> 
> 
> 
> And sure enough, we have circular dependencies: rework depends
> rework-inherit via it's "deps" attribute, while rework-inherit depends on
> rework via "peerDependencies". For confirmation, I commented out the
> contents of rework-inherit's peerDependencies, and sure enough, the
> infinite recursion goes away. (But then the build fails, because
> rework-inherit is missing a dependency.)
> 
> What's puzzling to me is that clearly peerDependencies are an important
> feature of npm. Both npm2nix and buildNodePackage explicitly support them
> and npm packages can be correctly installed without them. But if they cause
> infinite recursion in this trivial way, how could that code ever work? Is
> there a way to avoid infinite recursion?
> 
> Thanks in advance,
> 
> Colin

> _______________________________________________
> nix-dev mailing list
> nix-dev at lists.science.uu.nl
> http://lists.science.uu.nl/mailman/listinfo/nix-dev



More information about the nix-dev mailing list