Compile-Time Variable Injection van Go
Achtergrond
Tijdens werkzaamheden aan een bedrijfsproject heb ik onlangs onderzocht of er een methode bestaat om variabelen tijdens compile-tijd te injecteren zonder gebruik te maken van .env.
Ik veronderstelde dat dit zeer praktisch zou zijn, aangezien slechts één enkel bestand vereist is, in plaats van .env
of diverse config-bestanden.
Aanvankelijk zocht ik naar iets dergelijks als een go:generate
CLI die een constante bestand genereert op basis van .env
, maar dit bleek niet voorhanden te zijn.
Echter, indien dat het geval was, zou men eenvoudigweg constants kunnen aanpassen, en was er geen noodzaak voor het omslachtige proces van gen; bijgevolg vond ik een methode om waarden tijdens compile-tijd te injecteren, vergelijkbaar met de include_bytes!
macro in Rust.
Injectie van Variabelen tijdens Compile-tijd
Het gebruik is eenvoudig.
1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8 fmt.Println(Foo)
9}
Indien men code zoals hierboven heeft, kan deze tijdens de build als volgt worden geïnjecteerd.
1go build -ldflags="-X 'main.Foo=bar'"
Wanneer argumenten worden doorgegeven met ldflag, wordt de waarde bar
tijdens de compile-tijd bij de build in de variabele Foo
geïnjecteerd. Dit is eenvoudig.
Indien er binnen een project packages of variabelen met dezelfde naam op meerdere locaties aanwezig zijn, dient men het package path te specificeren.
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 dergelijke gevallen kan men als volgt injecteren door onderscheid te maken:
1go build -ldflags="-X 'github.com/myproject/config.Version=v1.0.0' -X 'github.com/myproject/internal/config.BuildTime=2025-05-27'"
Zelfs indien er meerdere variabelen in hetzelfde package aanwezig zijn, volstaat het om additionele 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:
- Variabele hoeft niet public te zijn: Variabelen die met een kleine letter beginnen, kunnen eveneens worden geïnjecteerd.
- Enkel string type ondersteund: Andere types worden niet ondersteund.