Compile-Time Variabelinjeksjon i Go
Bakgrunn
I forbindelse med et selskapsprosjekt undersøkte jeg nylig om det var mulig å injisere variabler ved kompileringstidspunktet uten å benytte .env-filer.
Jeg antok at dette ville være svært praktisk, ettersom det kun ville kreve én enkelt fil, i stedet for .env-filer eller flere konfigurasjonsfiler.
Først søkte jeg etter en go:generate CLI som kunne generere konstante filer basert på .env, men fant ingen slik løsning.
Imidlertid, hvis det var tilfelle, ville det ikke være nødvendig å generere dem på en tungvint måte; man kunne bare modifisere konstantene direkte, og jeg fant en metode for å injisere verdier ved kompileringstidspunktet, i likhet med include_bytes!-makroen i Rust.
Variabelinjeksjon ved kompileringstidspunktet
Bruken er enkel.
1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8 fmt.Println(Foo)
9}
Hvis det finnes kode som den ovenfor, kan den injiseres under bygging som følger:
1go build -ldflags="-X 'main.Foo=bar'"
Ved å sende argumenter med ldflag, injiseres verdien bar inn i variabelen Foo ved kompileringstidspunktet under bygging. Dette er enkelt.
Hvis det finnes pakker eller variabler med samme navn flere steder i prosjektet, spesifiseres pakkebanen.
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 slike tilfeller kan injeksjonen differensieres 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 om det finnes flere variabler i samme pakke, er det bare å sende inn tilleggsargumenter.
1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"
Egenskapene er som følger:
- Variabelen trenger ikke å være public: Variabler som starter med små bokstaver kan også injiseres.
- Støtter kun string-type: Andre typer støttes ikke.