Go-compileertijdvariabelen injecteren: gebruik van go build -ldflags -X

Achtergrond
Tijdens een bedrijfsproject ben ik op zoek gegaan naar een manier om variabelen tijdens de compilatie te injecteren zonder gebruik te maken van een .env-bestand.
Ik dacht dat dit erg handig zou zijn, omdat je dan alleen een enkel bestand nodig hebt in plaats van een .env-bestand of meerdere configuratiebestanden.
Allereerst heb ik gezocht naar een go:generate CLI-tool die een constantenbestand genereert op basis van een .env-bestand, maar die heb ik niet gevonden.
Als dat het geval is, dan kan ik de constants gewoon zelf aanpassen, en hoef ik niet de moeite te nemen om een generatiestap uit te voeren. Vervolgens vond ik in Rust de include_bytes!-macro, waarmee waarden tijdens de compilatie kunnen worden geïnjecteerd.
Compilatietijd-variabelen injecteren
Het gebruik is eenvoudig.
1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8 fmt.Println(Foo)
9}
Stel dat je bovenstaande code hebt, dan kun je tijdens het bouwen het volgende injecteren.
1go build -ldflags="-X 'main.Foo=bar'"
Door het argument via de ldflag door te geven, wordt de waarde bar tijdens de compilatie in de variabele Foo geïnjecteerd. Het is eenvoudig.
Als er in het project meerdere pakketten of variabelen met dezelfde naam bestaan, dan kun je het pakketpad opgeven.
1// github.com/myproject/config/config.go
2package config
3
4var Version string
5
6// github.com/myproject/internal/config/config.go
7package config
8
9var BuildTime string
In dit geval kun je als volgt onderscheid maken bij het injecteren:
1go build -ldflags="-X 'github.com/myproject/config.Version=v1.0.0' -X 'github.com/myproject/internal/config.BuildTime=2025-05-27'"
Ook wanneer er meerdere variabelen in hetzelfde pakket staan, volstaat het om extra argumenten door te geven.
1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"
De kenmerken zijn als volgt:
- De variabele hoeft niet publiek te zijn: ook variabelen die met een kleine letter beginnen, kunnen worden geïnjecteerd.
- Alleen het string-type wordt ondersteund: andere typen worden niet ondersteund.