Home

blog @main - refs - log -
-
https://git.jolheiser.com/blog.git
My nonexistent blog
blog / articles / gomodsri.md
- raw
 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>