GoSuda

Injection de Variables au Compile-Time en Go

By wHoIsDReAmer
views ...

Contexte

En travaillant sur un projet d'entreprise, j'ai cherché un moyen d'injecter des variables au moment de la compilation sans utiliser de fichier .env. J'ai pensé que ce serait très pratique, car cela permettrait de n'avoir qu'un seul fichier au lieu d'un .env ou de plusieurs fichiers de configuration.

Au départ, j'ai cherché une CLI go:generate capable de créer un fichier de constantes à partir d'un .env, mais je n'en ai pas trouvé.

Cependant, dans ce cas, il ne serait pas nécessaire de générer des fichiers de constantes, il suffirait de modifier les constantes directement. J'ai donc cherché un moyen d'injecter des valeurs au moment de la compilation, à l'instar de 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}

Si nous avons le code ci-dessus, nous pouvons injecter des valeurs lors de la construction comme suit :

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

En passant des arguments via ldflag, la valeur bar est injectée dans la variable Foo au moment de la compilation lors de la construction. C'est simple.

Si des packages ou des variables portant le même nom se trouvent à 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 ce cas, on peut les distinguer et les injecter 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 si plusieurs variables se trouvent dans le même package, il suffit de transmettre 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 :

  • Les variables n'ont pas besoin d'être publiques : les variables commençant par une lettre minuscule peuvent également être injectées.
  • Supporte uniquement le type string : les autres types ne sont pas supportés.

Références