Compile-Time Variable Injection von Go
Hintergrund
Beim Arbeiten an einem Unternehmensprojekt habe ich diesmal nach einer Möglichkeit gesucht, Variablen zur Kompilierzeit ohne .env
zu injizieren.
Ich dachte, dies wäre sehr praktisch, da man nur eine einzige Datei anstelle von .env
oder mehreren Konfigurationsdateien benötigt.
Zuerst habe ich nach etwas wie einem go:generate
CLI gesucht, das eine Konstanten-Datei basierend auf .env
generiert, aber es gab nichts.
Aber wenn das der Fall ist, könnte man einfach die constants modifizieren, ohne die umständliche Generierung durchzuführen, und ich fand eine Methode, Werte zur Kompilierzeit zu injizieren, ähnlich dem include_bytes!
Makro in Rust.
Injektion von Kompilierzeitvariablen
Die Verwendung ist einfach.
1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8 fmt.Println(Foo)
9}
Wenn Code wie der oben genannte vorhanden ist, kann er beim Build wie folgt injiziert werden.
1go build -ldflags="-X 'main.Foo=bar'"
Wenn Argumente mit ldflag übergeben werden, wird der Wert bar
zur Kompilierzeit während des Builds in die Variable Foo
injiziert. Das ist einfach.
Wenn es in einem Projekt Pakete oder Variablen mit demselben Namen an mehreren Stellen gibt, müssen Sie den Paketpfad angeben.
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
In einem solchen Fall kann wie folgt getrennt injiziert werden:
1go build -ldflags="-X 'github.com/myproject/config.Version=v1.0.0' -X 'github.com/myproject/internal/config.BuildTime=2025-05-27'"
Auch wenn es mehrere Variablen im selben Paket gibt, müssen nur zusätzliche Argumente übergeben werden.
1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"
Die Merkmale sind wie folgt:
- Die Variable muss nicht public sein: Variablen, die mit einem Kleinbuchstaben beginnen, können ebenfalls injiziert werden.
- Es wird nur der string-Typ unterstützt: Andere Typen werden nicht unterstützt.