GoSuda

Injection de variables Compile-Time dans Go

By wHoIsDReAmer
views ...

Contexte

En travaillant sur un projet d'entreprise cette fois-ci, j'ai cherché s'il existait un moyen d'injecter des variables au moment de la compilation sans .env. J'ai pensé que cela serait très pratique car cela ne nécessiterait qu'un seul fichier, sans avoir besoin de .env ou de plusieurs fichiers de configuration.

Ce que j'ai d'abord cherché était quelque chose comme un go:generate CLI qui générerait des fichiers de constantes basés sur .env, mais il n'y en avait pas.

Mais si tel était le cas, il suffirait de modifier simplement les constants, et il n'était pas nécessaire de se donner la peine de générer ; j'ai trouvé une méthode pour injecter des valeurs au moment de la compilation, similaire à la macro include_bytes! en Rust.

Injection de variables au moment de la compilation

L'utilisation est simple.

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

En supposant qu'il existe un code comme celui ci-dessus, il peut être injecté lors du build comme suit.

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

Si vous passez des arguments avec ldflag, la valeur bar est injectée dans la variable Foo au moment de la compilation lors du build. C'est simple.

Si des packages ou des variables portant le même nom existent à plusieurs endroits dans le projet, il suffit de spécifier le chemin du package.

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

Dans de tels cas, il est possible d'injecter en différenciant comme suit :

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

Même s'il y a plusieurs variables dans le même package, il suffit de passer des arguments supplémentaires.

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

Les caractéristiques sont les suivantes :

  • La variable n'a pas besoin d'être public : Les variables commençant par une lettre minuscule peuvent également être injectées.
  • Seul le type string est pris en charge : Les autres types ne sont pas pris en charge.

Référence