Vstrekovanie premenných v čase kompilácie v Go
Pozadie
Počas práce na firemnom projekte som hľadal spôsob, ako vstreknúť premenné počas kompilácie bez použitia .env súboru.
Domnieval som sa, že by to bolo mimoriadne pohodlné, pretože by to vyžadovalo iba jeden súbor namiesto .env alebo viacerých konfiguračných súborov.
Spočiatku som hľadal CLI nástroje, ako napríklad go:generate, ktoré by generovali súbory konštánt na základe .env súborov, avšak žiadne som nenašiel.
Avšak, ak by to bolo tak, nebolo by potrebné robiť gen, stačilo by upraviť konštanty, a našiel som spôsob, ako vstreknúť hodnoty počas kompilácie, podobne ako makro include_bytes! v Rust.
Vstrekovanie premenných počas kompilácie
Použitie je jednoduché.
1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8 fmt.Println(Foo)
9}
Ak máme kód ako ten vyššie, môžeme ho vstreknúť počas fázy zostavovania nasledovne:
1go build -ldflags="-X 'main.Foo=bar'"
Odovzdaním argumentov prostredníctvom ldflag sa hodnota bar vstrekne do premennej Foo počas kompilácie. Je to jednoduché.
Ak existujú viaceré balíky alebo premenné s rovnakým názvom v projekte, je potrebné špecifikovať cestu k balíku.
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
V takýchto prípadoch je možné ich vstreknúť odlišne takto:
1go build -ldflags="-X 'github.com/myproject/config.Version=v1.0.0' -X 'github.com/myproject/internal/config.BuildTime=2025-05-27'"
Dokonca aj keď má rovnaký balík viacero premenných, stačí odovzdať ďalšie argumenty.
1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"
Charakteristiky sú nasledovné:
- Premenná nemusí byť public: Je možné vstreknúť aj premenné začínajúce malým písmenom.
- Podporuje iba typ string: Iné typy nie sú podporované.