Go's Compile-Time Variable Injection
Baggrund
Mens jeg arbejdede på et virksomhedsprojekt, undersøgte jeg, om der var en metode til at injicere variabler under kompilering uden brug af .env-filer. Jeg antog, at dette ville være yderst praktisk, da det kun ville kræve en enkelt fil i stedet for .env eller flere konfigurationsfiler.
Til at starte med søgte jeg efter et go:generate CLI-værktøj, der kunne generere en konstant fil baseret på en .env-fil, men fandt ingen.
Men hvis det var tilfældet, ville det ikke være nødvendigt at generere den besværligt; man kunne blot ændre konstanterne direkte. I stedet fandt jeg en metode til at injicere værdier under kompilering, ligesom Rusts include_bytes! makro.
Injektion af kompileringstidsvariabler
Anvendelsen er ligetil.
1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8 fmt.Println(Foo)
9}
Hvis der er kode som ovenstående, kan den injiceres under build-processen som følger:
1go build -ldflags="-X 'main.Foo=bar'"
Ved at overføre argumenter via ldflag injiceres værdien bar i Foo-variablen under kompilering, når buildet udføres. Det er simpelt.
Hvis der er pakker eller variabler med samme navn flere steder i projektet, kan pakkevejen specificeres.
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
I sådanne tilfælde kan injektionen differentieres som følger:
1go build -ldflags="-X 'github.com/myproject/config.Version=v1.0.0' -X 'github.com/myproject/internal/config.BuildTime=2025-05-27'"
Hvis der er flere variabler i den samme pakke, skal man blot angive yderligere argumenter.
1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"
Karakteristika er som følger:
- Variabler behøver ikke at være offentlige: Variabler, der starter med små bogstaver, kan også injiceres.
- Understøtter kun string-typer: Andre typer understøttes ikke.