Hi,
I’m new to nix and wondering how to properly use the buildGoModule function, specifically how does one generate the modSha256.
Thanks.
Hi,
I’m new to nix and wondering how to properly use the buildGoModule function, specifically how does one generate the modSha256.
Thanks.
Nix will generate the hash for you, and you have to trust it on first use. There is no way you can figure this out otherwise.
You give it a fake hash (like 0000000000000000000000000000000000000000000000000000
) for the first run, and use the value it gives you on a mismatch. This will look something like this:
hash mismatch in fixed-output derivation '/nix/store/q4cfnancqqvkc3v18r48zfq0vig6v6y9-pgmetrics-1.6.2-go-modules':
wanted: sha256:0000000000000000000000000000000000000000000000000000
got: sha256:0llbx2sgcx95ym2q4l3334rdj3nkgr9z5jyp8406cp3k1ixi7gdb
Then you simply replace the modSha256
with the actual hash.
If you update your Go dependencies again, you’ll encounter a new mismatch, in which case you can update the hash again.
Incidentally you can use lib.fakeSha256
(or stdenv.lib.fakeSha256
) if you don’t want to type out all of those zeroes.
Maybe we can ask msteen to add support for buildGoModule too: https://github.com/msteen/nix-prefetch
Thanks for the help guys. Unfortunately I’m also new to go modules, and I imagine this is a go module related problem. Getting
source root is source
patching sources
configuring
building
warning: pattern "all" matched no module dependencies
installing
cp: cannot stat '/private/var/folders/v1/g_sph9b951qcn0k1sq0d40gdc5xb6t/T/nix-build-docopts-v0.6.1+fix-go-modules.drv-0/go/pkg/mod/cache/download': No such file or directory
builder for '/nix/store/vdz3abswdhrjdvvmb6bdfalcsh9554z5-docopts-v0.6.1+fix-go-modules.drv' failed with exit code 1
with this derivation
with import <nixpkgs> { };
buildGoModule rec {
name = "docopt.go-${version}";
version = "0.6.2";
src = fetchFromGitHub {
owner = "docopt";
repo = "docopt.go";
sha256 = "0wwz48jl9fvl1iknvn9dqr4gfy1qs03gxaikrxxp9gry6773v3sj";
rev = "${version}";
};
modSha256 = stdenv.lib.fakeSha256;
}
Well, that repo doesn’t have any Go modules. Good news is that it doesn’t have any dependencies at all outside of the Go stdlib.
So… in theory you can build it with this derivation:
with import <nixpkgs> { };
buildGoPackage rec {
name = "docopt.go-${version}";
version = "0.6.2";
src = fetchFromGitHub {
owner = "docopt";
repo = "docopt.go";
sha256 = "0wwz48jl9fvl1iknvn9dqr4gfy1qs03gxaikrxxp9gry6773v3sj";
rev = "${version}";
};
goPackagePath = "github.com/docopt/docopt-go";
}
The bad news is, that this is really only a library that you can use for building applications, it doesn’t have any executables itself. So the derivation won’t help you much.
It would help to know what you actually want to do
The ultimate end goal is to setup up a nix derivation for a local bash script that uses doctops: GitHub - docopt/docopts: Shell interpreter for docopt, the command-line interface description language., which is the shell for docopt and has those executables.
I ended up using the python version of docopts and have a derivation like this, but the nix-build output cannot find docopts, even though it’s availabe in the nix-shell.
with import <nixpkgs> { };
let
docopts = stdenv.mkDerivation {
name = "docopts";
src = fetchFromGitHub {
owner = "doordash";
repo = "docopts";
rev = "4c8b652998a5ffda5068197f002b5ab5735761d6";
sha256 = "0h7ywn2bcyckh9pvgaiwp3n5jnfszsj9mrxpri7w647wjihh4i12";
};
installPhase = ''
mkdir -p $out/bin
cp docopts $out/bin/
chmod +x $out/bin/docopts
'';
};
in
stdenv.mkDerivation rec {
name = "data-deployer";
propagatedBuildInputs = [
docopts
pkgs.python37
pkgs.python37Packages.docopt
pkgs.yq
];
src = ./.;
installPhase = ''
mkdir -p $out/bin
cp -r ${src}/src/* $out/bin
chmod +x $out/bin/data-deployer
'';
}
``
So here’s what I did. First the default.nix
:
with import <nixpkgs> {};
buildGoPackage {
name = "docopts";
src = fetchFromGitHub {
owner = "docopt";
repo = "docopts";
rev = "dab1ec98c9b2c9f36abcde5b9780d041dfc11b0f";
sha256 = "06dyhcbh5s70i9fzwayr16c2fpyv7iw0qigjxz48pm3xrpkb4c5l";
};
goPackagePath = [ "github.com/docopt/docopts" ];
goDeps = ./deps.nix;
}
I made the ´deps.nix´ by cloning the docopts repo, then running go mod init; go build; vgo2nix
.
It looks like this:
# file generated from go.mod using vgo2nix (https://github.com/adisbladis/vgo2nix)
[
{
goPackagePath = "github.com/docopt/docopt-go";
fetch = {
type = "git";
url = "https://github.com/docopt/docopt-go";
rev = "ee0de3bc6815";
sha256 = "0hlra7rmi5pmd7d93rv56ahiy4qkgmq8a6mz0jpadvbi5qh8lq6j";
};
}
]
Once you run nix-build
, you’ll get a ./result-bin/bin/docopts
.
Hope that helps.
Thanks a lot! I’ve got some questions here about the choices made. I would’ve assumed that ./deps.nix
would be replaceable by the contents of ./deps.nix
, but I get a cannot coerce a list to a string
. So goDeps expects a path, which it thinks is a string, but goDeps = ./deps.nix;
doesn’t look like a string. Is there some sugar I’m missing here?
That’s an artifact of how import
works. Which is how the goDeps is loaded, it doesn’t check whether it’s a list first, it just tries to import it. And paths are basically strings, see Introduction for a bit more info.