packages feed

yarn2nix-0.5.0: nix-lib/default.nix

{ lib, pkgs }:

let
  # Build an attrset of node dependencies suitable for the `nodeBuildInputs`
  # argument of `buildNodePackage`. The input is the path of a dependency
  # file generated by the `yarn2nix` utility from a `yarn.lock` file,
  # in turn the output of the `yarn` tool for an npm package.
  buildNodeDeps = lockDotNix: lib.fix
    (lib.extends
      (import lockDotNix { inherit (pkgs) fetchurl fetchgit; })
      (self: {
        # wrap the invocation in the fix point, to construct the
        # list of { name, drv } needed by buildNodePackage
        # from the templates.
        # It is basically a manual paramorphism, carrying parts of the
        # information of the previous layer (the original package name).
        _buildNodePackage = { name, ... }@args:
          { inherit name; drv = buildNodePackage args; };
      }));

  # Build a package template generated by the `yarn2nix --template`
  # utility from a yarn package. The first input is the path to the
  # template nix file, the second input is all node dependencies
  # needed by the template, in the form generated by `buildNodeDeps`.
  callTemplate = yarn2nixTemplate: allDeps:
    pkgs.callPackage yarn2nixTemplate {
      inherit buildNodePackage removePrefixes;
    } allDeps;


  buildNodePackage = import ./buildNodePackage.nix {
    inherit linkNodeDeps;
    inherit (pkgs) stdenv nodejs;
  };

  # Link together a `node_modules` folder that can be used
  # by npm’s module system to call dependencies.
  # Also link executables of all dependencies into `.bin`.
  # TODO: copy manpages & docs as well
  # type: String -> ListOf { name: String, drv : Drv } -> Drv
  linkNodeDeps = name: packageDeps:
    pkgs.runCommand (name + "-node_modules") {} ''
      mkdir -p $out/.bin
      ${lib.concatMapStringsSep "\n"
        (dep: ''
          echo "linking node dependency ${dep.name}"
          ln -sT ${dep.drv} "$out/${dep.name}"
          ${ # TODO: remove static building once RPATHs are fixed
             pkgs.haskell.lib.justStaticExecutables
               pkgs.haskellPackages.yarn2nix}/bin/setup-node-package-paths \
            bin \
            --to=$out/.bin \
            --package=$out/${dep.name}
        '')
        packageDeps}
    '';

  # Filter out files/directories with one of the given prefix names
  # from the given path.
  # type: ListOf File -> Path -> Drv
  removePrefixes = prfxs: path:
    let
      hasPrefix = file: prfx: lib.hasPrefix ((builtins.toPath path) + "/" + prfx) file;
      hasAnyPrefix = file: lib.any (hasPrefix file) prfxs;
    in
      builtins.filterSource (file: _: ! (hasAnyPrefix file)) path;

in {
  inherit buildNodeDeps callTemplate removePrefixes;
}