Compile-Time Variable Injection a Go-ban
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.