GoSuda

Compile-Time Variable Injection a Go-ban

By wHoIsDReAmer
views ...

Háttér

Mostanában egy céges projekten dolgozva megvizsgáltam, létezik-e módszer változók fordítási időben történő injektálására .env használata nélkül. Úgy véltem, ez rendkívül kényelmes lenne, mivel elegendő csupán egyetlen fájl, .env vagy többféle konfigurációs fájl nélkül.

Elsőként olyasmit kerestem, mint egy go:generate CLI, amely .env alapján állít elő konstans fájlt, de ilyet nem találtam.

Azonban ha ez a helyzet, elegendő lenne csupán a konstansokat módosítani, nem volt szükség a generálással járó fáradságra, így olyan módszert kerestem, amely lehetővé teszi értékek fordítási időben történő injektálásá, hasonlóan a Rust include_bytes! makrójához.

Változók injektálása fordítási időben

A használat egyszerű.

1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8    fmt.Println(Foo)
9}

Feltételezve, hogy a fentihez hasonló kód áll rendelkezésre, az buildelés során a következőképpen injektálható.

1go build -ldflags="-X 'main.Foo=bar'"

Amennyiben argumentumokat adunk át ldflag-gel, a bar érték injektálásra kerül a Foo változóba a buildelés során, fordítási időben. Egyszerű.

Amennyiben a projektben azonos nevű csomagok vagy változók több helyen is előfordulnak, elegendő meghatározni a csomag útvonalát.

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

Ilyen esetekben a következőképpen injektálható, megkülönböztetve:

1go build -ldflags="-X 'github.com/myproject/config.Version=v1.0.0' -X 'github.com/myproject/internal/config.BuildTime=2025-05-27'"

Még abban az esetben is, ha ugyanabban a csomagban több változó található, elegendő csupán további argumentumokat átadni.

1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"

A jellemzők a következők:

  • A változónak nem kell public-nak lennie: Kisbetűvel kezdődő változók is injektálhatók.
  • Csak string típus támogatott: Más típusok nem támogatottak.

Referencia