I am trying to build padloc but nothing seems to work. node2nix seems to fail at random derivations, being impossible to debug, npmlock2nix seems abandoned, so I’m left with two options. Either fetchNpmDeps
or importNpmLock
. fetchNpmDeps
doesn’t seem to be able to download the right dependencies, since when I start the build, it still misses some and I have no clue how to add them at that point as they’re not available in nixpkgs (e.g. ts-loader). importNpmLock
, on the other hand, doesn’t seem to really work at all. I can found no documentation apart from here and it really doesn’t seem to be used anywhere in nixpkgs.
Here is what I have tried with importNpmLock
:
{ pkgs, lib, buildNpmPackage, fetchNpmDeps, importNpmLock, npmHooks, ... }:
buildNpmPackage rec {
pname = "padloc";
version = "4.3.0";
env.ELECTRON_SKIP_BINARY_DOWNLOAD = 1;
# env.CYPRESS_INSTALL_BINARY = "0";
env.PL_PWA_URL = "https://10.10.10.10:8429";
src = pkgs.fetchzip {
url = "https://github.com/padloc/padloc/archive/refs/tags/v${version}.zip";
sha256 = "sha256-2G3uOmWKA6ZZJKyZhJu/B3jq9x+Bx/fb1zDSmzf0a0w=";
};
# npmFlags = [ "--ignore-scripts" "--prefer-offline" ];
npmFlags = [ "--ignore-scripts" ];
makeCacheWritable = true;
npmDeps = importNpmLock {
npmRoot = src;
package = lib.importJSON "${src}/package.json";
packageLock = lib.importJSON "${src}/package-lock.json";
};
npmConfigHook = importNpmLock.npmConfigHook;
npmBuildScript = "electron:build";
nativeBuildInputs = with pkgs; [
nodePackages.webpack
nodePackages.webpack-cli
];
}
What this will do is just spit an error saying:
in pure evaluation mode, 'fetchTree' requires a locked input, at «none»:0
So, is there any way in Nix to build a project like that?
I’ve researched a bit more and I’ve finally made importNpmLock
work:
buildNpmPackage rec {
pname = "padloc";
version = "4.3.0";
env.ELECTRON_SKIP_BINARY_DOWNLOAD = 1;
# env.CYPRESS_INSTALL_BINARY = "0";
env.PL_PWA_URL = "https://10.10.10.10:8429";
src = pkgs.fetchzip {
url = "https://github.com/padloc/padloc/archive/refs/tags/v${version}.zip";
sha256 = "sha256-2G3uOmWKA6ZZJKyZhJu/B3jq9x+Bx/fb1zDSmzf0a0w=";
};
# npmFlags = [ "--ignore-scripts" "--prefer-offline" ];
npmFlags = [ "--ignore-scripts" ];
# makeCacheWritable = true;
npmDeps = importNpmLock {
npmRoot = src;
fetcherOpts = {
"node_modules/maildev" = {
url = "https://git@github.com/padloc/maildev.git";
rev = "a3ac6bf682dfb7cbb08b8b86e7b8afc9e5e41c66";
};
"maildev" = {
url = "https://git@github.com/padloc/maildev.git";
rev = "a3ac6bf682dfb7cbb08b8b86e7b8afc9e5e41c66";
};
};
};
npmConfigHook = importNpmLock.npmConfigHook;
npmBuildScript = "electron:build";
nativeBuildInputs = with pkgs; [
nodePackages.webpack
nodePackages.webpack-cli
];
}
Now the problem is, npm install will not work. It won’t because some packages, such as maildev, have binaries. And apparently npm automatically tries to chmod those binaries, but since they come from other derivations it can’t and it will just give Permission Denied:
npm error code EPERM
npm error syscall chmod
npm error path /build/source/node_modules/maildev/bin/maildev
npm error errno -1
npm error Error: EPERM: operation not permitted, chmod '/build/source/node_modules/maildev/bin/maildev'
npm error at async chmod (node:internal/fs/promises:1085:10)
npm error at async Promise.all (index 0)
npm error at async Promise.all (index 0)
npm error at async #createBinLinks (/nix/store/v14k93caffbf0xz2g7bqr964grxxqlmj-nodejs-20.15.1/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arbo>
npm error at async Promise.allSettled (index 0)
npm error at async #linkAllBins (/nix/store/v14k93caffbf0xz2g7bqr964grxxqlmj-nodejs-20.15.1/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arboris>
npm error at async #build (/nix/store/v14k93caffbf0xz2g7bqr964grxxqlmj-nodejs-20.15.1/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/rebu>
npm error at async Arborist.rebuild (/nix/store/v14k93caffbf0xz2g7bqr964grxxqlmj-nodejs-20.15.1/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arb>
npm error at async [reifyPackages] (/nix/store/v14k93caffbf0xz2g7bqr964grxxqlmj-nodejs-20.15.1/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arbo>
npm error at async Arborist.reify (/nix/store/v14k93caffbf0xz2g7bqr964grxxqlmj-nodejs-20.15.1/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arbor>
npm error errno: -1,
npm error code: 'EPERM',
npm error syscall: 'chmod',
npm error path: '/build/source/node_modules/maildev/bin/maildev'
npm error }
If I use:
npmFlags = [ "--ignore-scripts" "--no-bin-links" ];
then npm install
will work but the actual build will fail because there are no binaries.
With --no-bin-links
we can also find out that the dependency maildev
is indeed basically a symlink to the derivation:
# inside the build
ls -ahl node_modules
lrwxrwxrwx 1 nixbld nixbld 58 Oct 4 00:13 maildev -> ../../../nix/store/rbi112hv5sf2kiqmq12bdzrzsb9xhar1-source
ls -ahl /nix/store/rbi112hv5sf2kiqmq12bdzrzsb9xhar1-source/bin/maildev
-r-xr-xr-x 1 root root 237 1 gen 1970 /nix/store/rbi112hv5sf2kiqmq12bdzrzsb9xhar1-source/bin/maildev
So it tries to chmod a file in another derivation and fails. I have no idea whether this is the right path, but I’ll keep logging here what works and what doesn’t.