1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
+++
title = "gomodsri"
summary = "Using tailscale/nardump to generate a go module SRI without building first"
date = 2024-03-10
category = "Nix"
+++
### The problem
When building a Go module with `nix`, generally you would use `buildGoModule`. One thing it shares with other builders in the nix ecosystem is a `vendorHash` property (or similar name).
Although there _have_ been various workarounds, there's usually no getting around some variation of building, noting the "expected" new hash, and replacing the old hash with the correct one before building works for real.
### The solution
Now, I am admittedly borrowing this idea from [tailscale](https://tailscale.com). I simply wrapped it in a (nu)shell command for easier generic usage.
The original idea combines the [nardump](https://github.com/tailscale/tailscale/tree/ad33e47270509345469af795aed65177df88904e/cmd/nardump) command with the [vendoring](https://pkg.go.dev/cmd/go#hdr-Make_vendored_copy_of_dependencies) ability of Go modules to predict the `vendorHash`. Put together, it can look something like the following:
- [update-flake.sh](https://github.com/tailscale/tailscale/blob/ad33e47270509345469af795aed65177df88904e/update-flake.sh#L9-L10)
```sh
# [...] setting up a tempdir
go mod vendor -o "$OUT"
go run tailscale.com/cmd/nardump --sri "$OUT" >go.mod.sri
# [...] cleanup
```
- [flake.nix](https://github.com/tailscale/tailscale/blob/ad33e47270509345469af795aed65177df88904e/flake.nix#L69)
```nix
pkgs.buildGoModule {
# ...
vendorHash = pkgs.lib.fileContents ./go.mod.sri;
# ...
}
```
---
I've modified it to use across other projects as the following nushell function:
```nu
def gomodsri [] {
let tmp = (mktemp -d)
go mod vendor -o $tmp
let sri = (go run tailscale.com/cmd/nardump@latest --sri $tmp)
$sri | save -f go.mod.sri
rm -rf $tmp
echo 'nixpkgs.lib.fileContents ./go.mod.sri'
}
```
<small>The echo at the end is because I always forget the invocation otherwise...</small>
|