-
-
Notifications
You must be signed in to change notification settings - Fork 126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: nodejs: link direct bins #227
fix: nodejs: link direct bins #227
Conversation
ab629a3
to
5adc175
Compare
4fb8366
to
d3beb8b
Compare
# Derivation building the ./node_modules directory in isolation. | ||
# This is used for the devShell of the current package. | ||
# We do not want to build the full package for the devShell. | ||
nodeModulesDir = pkgs.runCommandLocal "node_modules-${pname}" {} '' | ||
# symlink direct dependencies to ./node_modules | ||
mkdir $out | ||
${l.concatStringsSep "\n" ( | ||
l.forEach nodeDeps | ||
(pkg: '' | ||
for dir in $(ls ${pkg}/lib/node_modules/); do | ||
if [[ $dir == @* ]]; then | ||
mkdir -p $out/$dir | ||
ln -s ${pkg}/lib/node_modules/$dir/* $out/$dir/ | ||
else | ||
ln -s ${pkg}/lib/node_modules/$dir $out/ | ||
fi | ||
done | ||
'') | ||
)} | ||
|
||
# symlink transitive executables to ./node_modules/.bin | ||
mkdir $out/.bin | ||
for dep in ${l.toString nodeDeps}; do | ||
for binDir in $(ls -d $dep/lib/node_modules/.bin 2>/dev/null ||:); do | ||
ln -sf $binDir/* $out/.bin/ | ||
done | ||
done | ||
''; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused, removing
src = ""; | ||
dontUnpack = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to read package.json
to see what the direct dependencies are, to give priority to linking their bins.
@@ -6,7 +6,6 @@ | |||
import sys | |||
|
|||
|
|||
out = os.environ.get('out') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused, removing
os.symlink(origin, f"{root}/{module}/{submodule}") | ||
if not os.path.exists(f"{root}/{module}/{submodule}"): | ||
os.symlink(origin, f"{root}/{module}/{submodule}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could crash the build if the symlink already exists
@@ -26,15 +25,11 @@ def get_package_json(path): | |||
return package_json_cache[path] | |||
|
|||
def install_direct_dependencies(): | |||
add_to_bin_path = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused, removing
if force and os.path.exists(source): | ||
os.remove(source) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using force=True
, overwrite symlinks with direct dep bins
def symlink_direct_bins(): | ||
deps = [] | ||
package_json_file = get_package_json(f"{os.path.abspath('.')}") | ||
|
||
if package_json_file: | ||
if 'devDependencies' in package_json_file and package_json_file['devDependencies']: | ||
for dep,_ in package_json_file['devDependencies'].items(): | ||
deps.append(dep) | ||
if 'dependencies' in package_json_file and package_json_file['dependencies']: | ||
for dep,_ in package_json_file['dependencies'].items(): | ||
deps.append(dep) | ||
|
||
for name in deps: | ||
package_location = f"{root}/{name}" | ||
package_json = get_package_json(package_location) | ||
symlink_bin(f"{bin_dir}", package_location, package_json, force=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Read package.json
, get deps, link their bins, overwriting existing
# dump bin paths | ||
with open(f"{os.environ.get('TMP')}/ADD_BIN_PATH", 'w') as f: | ||
f.write(':'.join(add_to_bin_path)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused, removing
You might be interested in #195 - there the node_modules are always trees of symlinks and generated separately from the packages (makeModules function), and the .bin directories are correctly populated (I think). individual node modules have bin/ so that they work as nix packages and makeWrapper etc work as expected, and the combined node_modules then symlinks those together into node_modules/.bin/ |
I could reproduce the problem using your I used this flake.nix: {
inputs.dream2nix.url = "github:tinybeachthor/dream2nix/fix-nodejs-link-direct-bins";
outputs = inp: let
pkgs = inp.dream2nix.inputs.nixpkgs.legacyPackages.x86_64-linux;
package_json = builtins.toFile "package.json" ''
{
"devDependencies": {
"svgo": "^2.2.2",
"cssnano": "^4.1.10"
}
}
'';
in
inp.dream2nix.lib.makeFlakeOutputs {
systemsFromFile = ./nix_systems;
config.projectRoot = ./.;
source = pkgs.runCommand "src" {} ''
mkdir $out
cp ${package_json} $out/package.json
'';
};
} after running $ ls -lah node_modules/.bin/
total 0
drwxr-xr-x 2 grmpf users 200 Aug 9 15:10 .
drwxr-xr-x 162 grmpf users 3.2K Aug 9 15:10 ..
lrwxrwxrwx 1 grmpf users 85 Aug 9 15:10 browserslist -> ../gv0wz6r2k2i2cgmrmdip0az1al52x5sj-cssnano-4.1.11/lib/node_modules/.bin/browserslist
lrwxrwxrwx 1 grmpf users 90 Aug 9 15:10 browserslist-lint -> ../gv0wz6r2k2i2cgmrmdip0az1al52x5sj-cssnano-4.1.11/lib/node_modules/.bin/browserslist-lint
lrwxrwxrwx 1 grmpf users 79 Aug 9 15:10 cssesc -> ../gv0wz6r2k2i2cgmrmdip0az1al52x5sj-cssnano-4.1.11/lib/node_modules/.bin/cssesc
lrwxrwxrwx 1 grmpf users 80 Aug 9 15:10 esparse -> ../gv0wz6r2k2i2cgmrmdip0az1al52x5sj-cssnano-4.1.11/lib/node_modules/.bin/esparse
lrwxrwxrwx 1 grmpf users 83 Aug 9 15:10 esvalidate -> ../gv0wz6r2k2i2cgmrmdip0az1al52x5sj-cssnano-4.1.11/lib/node_modules/.bin/esvalidate
lrwxrwxrwx 1 grmpf users 80 Aug 9 15:10 js-yaml -> ../gv0wz6r2k2i2cgmrmdip0az1al52x5sj-cssnano-4.1.11/lib/node_modules/.bin/js-yaml
lrwxrwxrwx 1 grmpf users 79 Aug 9 15:10 mkdirp -> ../gv0wz6r2k2i2cgmrmdip0az1al52x5sj-cssnano-4.1.11/lib/node_modules/.bin/mkdirp
lrwxrwxrwx 1 grmpf users 77 Aug 9 15:10 svgo -> ../gv0wz6r2k2i2cgmrmdip0az1al52x5sj-cssnano-4.1.11/lib/node_modules/.bin/svgo The |
@DavHau {
inputs.dream2nix.url = "github:tinybeachthor/dream2nix/fix-nodejs-link-direct-bins";
outputs = inp: let
pkgs = inp.dream2nix.inputs.nixpkgs.legacyPackages.x86_64-linux;
package_json = builtins.toFile "package.json" ''
{
"name": "anything",
"devDependencies": {
"svgo": "^2.2.2",
"cssnano": "^4.1.10"
}
}
'';
in
inp.dream2nix.lib.makeFlakeOutputs {
systemsFromFile = ./nix_systems;
config.projectRoot = ./.;
source = pkgs.runCommand "src" {} ''
mkdir $out
cp ${package_json} $out/package.json
'';
};
} > ls -la node_modules/.bin
total 32
drwxr-xr-x 1 martin users 138 Aug 9 11:22 .
drwxr-xr-x 1 martin users 4590 Aug 9 11:22 ..
lrwxrwxrwx 1 martin users 22 Aug 9 11:22 browserslist -> ../browserslist/cli.js
lrwxrwxrwx 1 martin users 32 Aug 9 11:22 browserslist-lint -> ../update-browserslist-db/cli.js
lrwxrwxrwx 1 martin users 20 Aug 9 11:22 cssesc -> ../cssesc/bin/cssesc
lrwxrwxrwx 1 martin users 25 Aug 9 11:22 esparse -> ../esprima/bin/esparse.js
lrwxrwxrwx 1 martin users 28 Aug 9 11:22 esvalidate -> ../esprima/bin/esvalidate.js
lrwxrwxrwx 1 martin users 25 Aug 9 11:22 js-yaml -> ../js-yaml/bin/js-yaml.js
lrwxrwxrwx 1 martin users 20 Aug 9 11:22 mkdirp -> ../mkdirp/bin/cmd.js
lrwxrwxrwx 1 martin users 16 Aug 9 11:22 svgo -> ../svgo/bin/svgo I am not sure why adding a |
The name thing is because the discoverer gets a null name. I have a fix for it in my branch |
Fixes #221
At the end of the
src/subsystems/nodejs/builders/granular/install-deps.py
,read
package.json
,and link bins of direct dependencies to
node_modules/.bin
.Needs to pass the
src
(+ run unpack phase) todevShell
sopackage.json
is available.