Compile-Time Variable Injection v Go
Pozadie
Pri práci na firemnom projekte som tentoraz hľadal spôsob, ako v čase compile time vkladať variables bez použitia .env. Myslel som si, že by to bolo veľmi pohodlné, pretože by to vyžadovalo len jeden jediný súbor namiesto .env alebo viacerých config súborov.
Najprv som hľadal niečo ako go:generate CLI, ktoré by generovalo constants súbory na základe .env, ale nenašiel som nič.
Avšak, ak by to tak bolo, stačilo by jednoducho upraviť constants a nebolo by potrebné sa trápiť s gen; namiesto toho som našiel spôsob, ako v čase compile time vkladať hodnoty, podobne ako Rust include_bytes! macro.
Vkladanie variables v čase compile time
Použitie je jednoduché.
1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8 fmt.Println(Foo)
9}
Ak predpokladáme kód ako ten vyššie, počas build sa dá vložiť nasledovne:
1go build -ldflags="-X 'main.Foo=bar'"
Ak sa argumenty odovzdajú cez ldflag, hodnota bar sa vloží do Foo variable v čase compile time počas build. Je to jednoduché.
Ak má projekt na viacerých miestach package alebo variable s rovnakým názvom, stačí explicitne uviesť package cestu.
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 takomto prípade sa dá vložiť s rozlíšením nasledovne:
1go build -ldflags="-X 'github.com/myproject/config.Version=v1.0.0' -X 'github.com/myproject/internal/config.BuildTime=2025-05-27'"
Aj v prípade, že v rovnakom package je viacero variables, stačí jednoducho odovzdať dodatočné argumenty.
1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"
Charakteristiky sú nasledovné:
- Variable nemusí byť public: Je možné vkladať aj variables začínajúce malým písmenom.
- Podporuje iba string type: Iné typy nie sú podporované.