I'm packaging a node script with an external dependency (GraphicsMagick), and when attempting to override the derivation generated from node2nix I get the error:
wrapProgram: command not found
The following text goes into detail of what I've tried to solve this error.
Reproducing the problem from scratch
I've created a minimal git repository that reproduces this problem if you'd just like to take a look there. Else, the steps to reproduce the problem are below.
Initial Shell Session:
In an empty directory, run:
npm init -y
npm install --save gm
curl https://i.imgur.com/addSfQi.jpg > image.png
(npm version: 5.6.0 & node version v8.9.4)
Create index.js
#!/usr/bin/env node
const path = require("path"); // node.js builtin
const gm = require("gm"); // GraphicsMagick module
const imagePath = path.join(__dirname, "image.png");
// Flip image horizontally and write to disk
gm(imagePath)
.flop()
.write(imagePath, error => {
console.log("error:", error);
});
Add a "bin" section to package.json:
"bin": "index.js"
Generate *.nix files with node2nix
node2nix -8 -l package-lock.json
Create override.nix
{ pkgs ? import <nixpkgs> {}
, system ? builtins.currentSystem
}:
let
nodePackages = import ./default.nix {
inherit pkgs system;
};
in
nodePackages // {
package = nodePackages.package.override (oldAttrs: {
postInstall = ''
wrapProgram "$out/bin/test-nodejs-gm-nixpkg" --prefix PATH : "${pkgs.graphicsmagick}/bin"
'';
});
}
Build nix package
nix-build override.nix -A package
The above fails with:
/nix/store/*/setup: line 95: wrapProgram: command not found
Helpful Resources
node2nix git repository - includes some basic examples.
example override in nixpkgs - example of how nixpkgs uses wrapProgram in postInstall with files generated by node2nix.
wrapProgram is contained within the makeWrapper package.
nativeBuildInputs = oldAttrs.nativeBuildInputs or [] ++ [ pkgs.makeWrapper ];
As mentioned by #ppb in the comments.
Related
I'm trying to write a derivation for a Go project that uses a Makefile to build its frontend with Yarn. As Yarn downloads files, I'm using a fixed derivation hash for networking.
However, Yarn attempts to write to its global package cache in /usr/local or /homeless-shelter, even though neither path exists.
To work around this issue, I tried to use makeWrapper to pass the --global-folder /tmp argument, but while the derivation runs it doesn't seem to be using it, as even --help is ignored.
How can I correctly wrap Yarn, or what other tool can I use to fix this?
cd frontend && yarn install --frozen-lockfile
yarn install v1.22.19
warning Skipping preferred cache folder "/homeless-shelter/.cache/yarn" because it is not writable.
warning Selected the next writable cache folder in the list, will be "/build/.yarn-cache-1000".
[1/4] Resolving packages...
[2/4] Fetching packages...
warning Cannot find a suitable global folder. Tried these: "/usr/local, /homeless-shelter/.yarn"
warning Cannot find a suitable global folder. Tried these: "/usr/local, /homeless-shelter/.yarn"
warning Cannot find a suitable global folder. Tried these: "/usr/local, /homeless-shelter/.yarn"
warning Cannot find a suitable global folder. Tried these: "/usr/local, /homeless-shelter/.yarn"
warning Cannot find a suitable global folder. Tried these: "/usr/local, /homeless-shelter/.yarn"
warning Cannot find a suitable global folder. Tried these: "/usr/local, /homeless-shelter/.yarn"
Done in 24.32s.
Error: ENOENT: no such file or directory, open '/homeless-shelter/.yarnrc'
make: *** [Makefile:218: frontend] Error 1
My config:
{ pkgs ? (
let
inherit (builtins) fetchTree fromJSON readFile;
inherit ((fromJSON (readFile ./flake.lock)).nodes) nixpkgs;
in
import (fetchTree nixpkgs.locked) {
overlays = [];
}
)
}:
with pkgs;
stdenv.mkDerivation rec {
pname = "someapp";
version = "v1.0";
src = fetchFromGitHub {
owner = "someowner";
repo = "someapp";
rev = "ffffffffffffffffffffffffffffffff";
sha256 = "sha256-fffffffffffffffffffffffffffffffff";
};
wrappedYarn = yarn.overrideAttrs (oldAttrs: {
buildInputs = oldAttrs.buildInputs or [] ++ [ makeBinaryWrapper ];
postInstall = oldAttrs.postInstall or "" + ''
wrapProgram $out/bin/yarn \
/*--append-flags "--global-folder /tmp/yarn --global-link /tmp/yarn2"*/
--append-flags "--help"
'';
});
buildInputs = [ go git wrappedYarn gcc gnumake ];
outputHashMode = "flat";
outputHashAlgo = "sha256";
outputHash = lib.fakeHash;
meta = with lib; {
description = "SomeApp";
homepage = "https://github.com/someowner/someapp";
platforms = platforms.linux;
};
}
This is the sequel of this question.
I've a bash list of command that generated a file nix directory when these commands are executed.
mkdir nix
rm -fr node_module
node2nix -16 --development --input package.json --lock package-lock.json --node-env ./nix/node-env.nix --composition ./nix/default.nix --output ./nix/node-package.nix
I have flake.nix file that use nix to create an envirnoment.
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
#npm_pack = import (./nix );
npm_pack = import ./nix { inherit pkgs ;};
in with pkgs;{
#devShell = mkShell { buildInputs = [ npm_pack.package ];};
devShell = npm_pack.shell;
});
}
It is executed with this command:
nix develop --extra-experimental-features nix-command --extra-experimental-features flakes --ignore-environment
Is there a way to modify the flake.nix file to create the nix directory and then do the work it has to do with nix directory.
I know that I could ONE create bash file (see the in answer why I don't like it)
In order to create the flake.nix I thinking about using something like a sheelhook in the beginning.I need too to be sure that node and node2nix are installed. Therefore I need those line
node2nix.url ="github:svanderburg/node2nix"; # in the input
nodejs = pkgs.nodejs-16_x; #in the output
running this script works
#/nix/store/4xw8n979xpivdc46a9ndcvyhwgif00hz-bash-5.1-p16/bin/bash
#nix-shell -p node2nix nodejs stdenv --pure
npm init -y
npm install node-gyp-build
mkdir nix;
rm -fr node_modules ;
node2nix -16 --development --input package.json --lock package-lock.json --node-env ./nix/node-env.nix --composition ./nix/default.nix --output ./nix/node-package.nix
nix develop --extra-experimental-features nix-command --extra-experimental-features flakes --ignore-environment
but it doesn't work if somebody has not the bash in the directory than my bash.
Therefore I prefer a solution consisting of implementing a big flake.nix because I'm sure it works if nix is installed
and it need to files : the flake.nix and the script.sh
with derivation
let
pkgs = import <nixpkgs> {};
in
with pkgs;
stdenv.mkDerivation {
name = "asdfasdf";
version = "0.1";
src = /home/srghma/opt/foxitsoftware/foxitreader/FoxitReader; # this is executeable file
dontUnpack = true; # not fu**** working
installPhase = ''
echo "not even executed"
'';
}
I have an error
nix-build tmp.nix
these derivations will be built:
/nix/store/x75gi70i1i57y8d3k4hhx0r3z5kjn6h6-asdfasdf.drv
building '/nix/store/x75gi70i1i57y8d3k4hhx0r3z5kjn6h6-asdfasdf.drv'...
unpacking sources
unpacking source archive /nix/store/3hnf69pky6mqaxv4jxly9fyywqpq6iml-FoxitReader
do not know how to unpack source archive /nix/store/3hnf69pky6mqaxv4jxly9fyywqpq6iml-FoxitReader
builder for '/nix/store/x75gi70i1i57y8d3k4hhx0r3z5kjn6h6-asdfasdf.drv' failed with exit code 1
error: build of '/nix/store/x75gi70i1i57y8d3k4hhx0r3z5kjn6h6-asdfasdf.drv' failed
why dontUnpack not working?
Update: created bug issue at nixpkgs https://github.com/NixOS/nixpkgs/issues/65434
Try this:
let
pkgs = import <nixpkgs> {};
in
with pkgs;
stdenv.mkDerivation {
name = "asdfasdf";
version = "0.1";
# Renamed to imply that 'src' functionality is not being used.
executable = /home/srghma/opt/foxitsoftware/foxitreader/FoxitReader; # this is executeable file
phases = [ "installPhase" ]; # Removes all phases except installPhase
installPhase = ''
mkdir -p $out/bin
cp ${executable} $out/bin
'';
}
#FRidh wrote
Many of the dont attributes were not yet implemented in the
current and past stable releases. So, if you intend to use it with the
current stable or older stables, use instead unpackPhase = ":".
I'm trying to get the latest version of ghcid installed.
I've installed ghcid via adding haskellPackages.ghcid in my nix config like so:
{ config, pkgs, ... }:
let
unstable = import <unstable> {};
in
{
environment.systemPackages = with pkgs; [
haskellPackages.ghcid
];
}
I thought possibly it would be available as a specific package but I can't seem to find anything:
nix-env -v -qaP haskellPackages.ghcid
And
nix-env -v -qaP ghcid
Return ...matches no derivations
Surprisingly simple:
unstable.haskellPackages.ghcid
I've just started using the Nix package manager on OSX and I'm attempting to create my first package for the pass binary (https://www.passwordstore.org) - which is not available in the Nixpkgs repository.
I'm attempting to specify a runtime dependency (getopt), however this doesn't appear to be available when the binary is used.
This is my packages's default.nix:
{ pkgs ? import <nixpkgs> {} }:
with pkgs;
let
version = "1.7.1";
in {
pass = stdenv.mkDerivation rec {
name = "pass-${version}";
src = fetchurl {
url = "https://git.zx2c4.com/password-store/snapshot/password-store-1.7.1.tar.xz";
sha256 = "0scqkpll2q8jhzcgcsh9kqz0gwdpvynivqjmmbzax2irjfaiklpn";
};
buildInputs = [ stdenv makeWrapper];
installPhase = ''
make install PREFIX=$out/artifact
makeWrapper $out/artifact/bin/pass $out/bin/pass \
--set PATH ${stdenv.lib.makeBinPath [ getopt ]}
'';
meta = {
homepage = "https://www.passwordstore.org";
description = "The standard unix password manager";
license = stdenv.lib.licenses.gpl2Plus;
};
};
}
I can successfully build this package (nix-build --show-trace) and install it (nix-env -i ./result).
Listing the runtime dependencies for my package shows getopt listed:
nix-store -qR $(which pass)
...
/nix/store/c5swmygzc0kmvpq6cfkvwm2yz1k57kqy-getopt-1.1.4
However when I come to use the binary (pass init my-key) I get the following error:
/nix/store/...-pass-1.7.1/artifact/bin/pass: line 302:
/usr/local/bin/getopt: No such file or directory
Can anyone advise what I'm doing wrong?
Thanks
It looks like getopt gets a special treatment. The darwin.sh script looks for it using brew and port and falls back to /usr/local. That's why the (correct) wrapper has no effect.
So the solution seems to be, to make it look for getopt in PATH, which is provided by the wrapper script. You can probably make it as simple as GETOPT=getopt (which is similar to openbsd.sh)
For patching source code, see the NixPkgs documentation
After running nix-build, you should run cat result/bin/pass to look at your wrapper script and make sure it looks OK. It should be a shell script that sets the PATH to include getopt and then calls result/artifact/bin/pass.
Then try running the wrapper script. Note that the wrapper should be in result/bin, not result/artifact/bin.