GoSuda

Injectarea Variabilelor la Compile-Time în Go

By wHoIsDReAmer
views ...

Context

Cu ocazia lucrului la un proiect al companiei, am căutat o modalitate de a injecta variabile la momentul compilării fără a utiliza .env. Am considerat că acest lucru ar fi extrem de convenabil, deoarece ar necesita un singur fișier, eliminând necesitatea fișierelor .env sau a multiplelor fișiere de configurare.

Inițial, am căutat un instrument similar cu un CLI go:generate care să genereze un fișier de constante pe baza fișierului .env, dar nu am găsit unul.

Însă, în acest caz, aș fi putut pur și simplu să modific constantele direct, fără a fi necesară generarea lor laborioasă, așa că am căutat o modalitate de a injecta valori la momentul compilării, similară cu macro-ul include_bytes! din Rust.

Injectarea Variabilelor la Momentul Compilării

Modul de utilizare este simplu.

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

Presupunând că aveți cod similar cu cel de mai sus, puteți efectua injectarea în timpul construirii (build) astfel:

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

Prin transmiterea argumentelor cu ldflag, valoarea bar este injectată în variabila Foo la momentul compilării în timpul procesului de construire. Este simplu.

Dacă în proiect există pachete sau variabile cu același nume în multiple locații, este suficient să specificați calea pachetului.

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

În astfel de cazuri, le puteți injecta distinct astfel:

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

Chiar dacă există multiple variabile în același pachet, este suficient să transmiteți argumente suplimentare.

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

Caracteristicile sunt următoarele:

  • Variabila nu trebuie să fie publică: Pot fi injectate și variabile care încep cu literă mică.
  • Suportă doar tipul string: Alte tipuri nu sunt suportate.

Referințe