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;
}