Wstrzykiwanie zmiennych w czasie kompilacji w Go
Kontekst
Podczas pracy nad projektem firmowym poszukiwałem metody wstrzykiwania zmiennych w czasie kompilacji bez użycia .env.
Uważałem, że byłoby to niezwykle wygodne, ponieważ wymagałoby tylko jednego pliku zamiast .env lub wielu plików konfiguracyjnych.
Początkowo szukałem narzędzia CLI, takiego jak go:generate, które generowałoby pliki stałych na podstawie .env, ale nic takiego nie znalazłem.
Jednakże, jeśli miałbym modyfikować constants, nie było potrzeby kłopotliwego generowania, więc szukałem sposobu na wstrzykiwanie wartości w czasie kompilacji, podobnie jak makro include_bytes! w Rust.
Wstrzykiwanie zmiennych w czasie kompilacji
Sposób użycia jest prosty.
1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8 fmt.Println(Foo)
9}
Zakładając, że istnieje powyższy kod, można wstrzyknąć zmienne podczas budowania w następujący sposób:
1go build -ldflags="-X 'main.Foo=bar'"
Przekazanie argumentów za pomocą ldflag spowoduje wstrzyknięcie wartości bar do zmiennej Foo w czasie kompilacji podczas budowania. Jest to proste.
Jeśli w projekcie istnieje wiele pakietów lub zmiennych o tej samej nazwie, należy określić ścieżkę pakietu.
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
W takim przypadku można rozróżnić i wstrzyknąć w następujący sposób:
1go build -ldflags="-X 'github.com/myproject/config.Version=v1.0.0' -X 'github.com/myproject/internal/config.BuildTime=2025-05-27'"
Nawet jeśli w tym samym pakiecie znajduje się wiele zmiennych, wystarczy przekazać dodatkowe argumenty.
1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"
Cechy charakterystyczne są następujące:
- Zmienna nie musi być publiczna: Możliwe jest wstrzykiwanie zmiennych zaczynających się małą literą.
- Obsługuje tylko typ string: Inne typy nie są obsługiwane.