Compile-Time Variable Injection i Go
Baggrund
I forbindelse med arbejdet på et virksomhedsprojekt for nylig undersøgte jeg, om der var en metode til at injicere variabler ved kompileringstid uden brug af .env. Jeg antog, at dette ville være yderst bekvemt, da det kun ville kræve en enkelt fil uden behov for .env eller flere konfigurationsfiler.
Til at starte med søgte jeg efter noget i stil med en go:generate
CLI, der kunne generere en konstantfil baseret på .env, men fandt intet.
Men i så fald kunne man blot modificere constants direkte uden besværet med generering, og jeg fandt en metode til at injicere værdier ved kompileringstid, ligesom Rusts include_bytes!
makro.
Variabelindføjelse ved kompileringstid
Anvendelsen er simpel.
1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8 fmt.Println(Foo)
9}
Hvis man antager, at der findes kode som ovenstående, kan værdier injiceres under build som følger.
1go build -ldflags="-X 'main.Foo=bar'"
Ved at overføre argumenter via ldflag injiceres værdien bar
i variablen Foo
ved kompileringstid under build. Dette er simpelt.
Hvis der findes pakker eller variabler med samme navn flere steder i projektet, kan man angive pakkevejen eksplicit.
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 værdier injiceres adskilt 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'"
Selv hvis der er flere variabler i samme pakke, kan yderligere argumenter blot overføres.
1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"
Karakteristikaene er som følger:
- Variablen behøver ikke at være public: Variabler, der starter med et lille bogstav, kan også injiceres.
- Kun string-typen understøttes: Andre typer understøttes ikke.