Inyección de variables en tiempo de compilación en Go
Antecedentes
Mientras trabajaba en un proyecto de la empresa, busqué un método para inyectar variables en tiempo de compilación sin utilizar .env.
Pensé que esto sería extremadamente conveniente, ya que solo se necesitaría un único archivo en lugar de .env o múltiples archivos de configuración.
Inicialmente, busqué una interfaz de línea de comandos go:generate que generara archivos constantes a partir de .env, pero no encontré ninguna.
Sin embargo, si ese fuera el caso, no habría necesidad de pasar por la molestia de generar un archivo; simplemente se podrían modificar las constantes. En su lugar, encontré un método para inyectar valores en tiempo de compilación, similar a la macro include_bytes! en Rust.
Inyección de variables en tiempo de compilación
El uso es sencillo.
1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8 fmt.Println(Foo)
9}
Si existe un código como el anterior, se puede inyectar de la siguiente manera durante la compilación:
1go build -ldflags="-X 'main.Foo=bar'"
Al pasar argumentos con ldflag, el valor bar se inyecta en la variable Foo en tiempo de compilación durante el proceso de construcción. Es simple.
Si existen paquetes o variables con el mismo nombre en diferentes ubicaciones del proyecto, se debe especificar la ruta del paquete.
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
En tales casos, se puede inyectar de la siguiente manera:
1go build -ldflags="-X 'github.com/myproject/config.Version=v1.0.0' -X 'github.com/myproject/internal/config.BuildTime=2025-05-27'"
Incluso si hay varias variables en el mismo paquete, simplemente se pueden pasar argumentos adicionales.
1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"
Las características son las siguientes:
- La variable no necesita ser pública: Las variables que comienzan con minúscula también pueden ser inyectadas.
- Solo admite el tipo string: Otros tipos no son compatibles.