GoSuda

Go's Compile-Time Variable Injection

By wHoIsDReAmer
views ...

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.

Reference