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`. Like other builders in the nix ecosystem, it uses a `vendorHash` property (or similar name).
Although there _have_ been various workarounds, the process typically involves building, noting the "expected" new hash, and replacing the old hash with the correct one before the build succeeds.
### The solution
My solution is inspired by [tailscale](https://tailscale.com), which I've adapted into a (nu)shell command for easier generic usage.
The original idea starts with the [nardump](https://github.com/tailscale/tailscale/tree/ad33e47270509345469af795aed65177df88904e/cmd/nardump) command. This is combined 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>
|