GoSuda

Injekce proměnných v čase kompilace v Go

By wHoIsDReAmer
views ...

Pozadí

Při práci na firemním projektu jsem hledal způsob, jak vkládat proměnné v době kompilace bez použití souboru .env. Předpokládal jsem, že by to bylo velmi pohodlné, protože by stačil jediný soubor namísto souboru .env nebo více konfiguračních souborů.

Zpočátku jsem hledal CLI nástroj podobný go:generate, který by generoval soubor s konstantami na základě .env, ale nenašel jsem žádný.

Nicméně, pokud by tomu tak bylo, nebylo by nutné generovat soubor, ale stačilo by upravit konstanty. Místo toho jsem objevil způsob, jak vkládat hodnoty v době kompilace, podobně jako makro include_bytes! v Rustu.

Vkládání proměnných v době kompilace

Použití je jednoduché.

1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8    fmt.Println(Foo)
9}

Pokud máme kód jako výše, můžeme během sestavování vložit proměnnou následovně:

1go build -ldflags="-X 'main.Foo=bar'"

Předáním argumentu přes ldflag se hodnota bar vloží do proměnné Foo v době kompilace během sestavování. Je to jednoduché.

Pokud má projekt více balíčků nebo proměnných se stejným názvem, stačí specifikovat 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 takovém případě je možné provést vkládání s rozlišením následovně:

1go build -ldflags="-X 'github.com/myproject/config.Version=v1.0.0' -X 'github.com/myproject/internal/config.BuildTime=2025-05-27'"

I v případě, že existuje více proměnných ve stejném balíčku, stačí předat další argumenty.

1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"

Charakteristiky jsou následující:

  • Proměnná nemusí být public: Lze vkládat i proměnné začínající malým písmenem.
  • Podporuje pouze typ string: Jiné typy nejsou podporovány.

Odkazy