mail

Nouveau avec Go 1.16, la directive //go:embed permet d'embarquer des fichiers dans vos artefacts Go. Modèles pour les emails, sites web, scripts être ajoutés plus facilement que jamais.

TL;DR: //go:embed est une directive qui remplit une variable ou un type dédié qui implémente l'interface io/fs.FS à partir d'un ensemble de fichiers et répertoires. Nouvelle fonctionnalité de Go 1.16, elle est très utile pour distribuer vos artéfacts Go qui incluent du contenu tel que des modèles, des scripts ou des pages web. Il supprime le besoin d'utiliser des bibliothèques tierces. Parce qu'il est inclus dans la toolchain, //go:embed ne nécessite pas d'utiliser aucune autre commande quand vous faites un build.

Le TL;DR: dit tout. Vous trouverez 2 exemples simples ci-dessous.

Un exemple simple

La manière la plus simple d'utiliser embed consiste à ajouter la directive au dessus d'une variable string ou []byte comme dans l'exemple ci-dessous. Pour que cela fonctionne, vous devrez :

  • ajouter //go:embed suivi du chemin du fichier à charger au dessus de la déclaration de la variable
  • référencer la bibliothèque dans les imports à l'aide de _ "embed"
  • disposer d'un fichier, ici nommé index.txt qui contient, par exemple, Hello World!

Il s'agit d'un exemple très simple d'un tel programme:

package main

import (
	_ "embed"
	"fmt"
)

//go:embed index.txt
var helloworld string

func main() {
	fmt.Printf("%s", helloworld)
}

L'exécution de ce programme ressemble à ce qui suit:

go run main.go
Hello World!

Un exemple plus avancé

Si vous avez plusieurs fichiers de ressources ou que vous avez besoin de manipuler le contenu comme vous manipuleriez des fichiers ou des répertoires, Go 1.16 offre une interface nommée FS dans io/fs. Cette interface permet de gérer les contenus embarqués comme s'il s'agissait de fichiers sur un système de fichier en lecture seule.

Pour utiliser embed dans ce contexte, vous devrez créer une variable de type embed.FS. Pour que cela fonctionne, vous devrez également:

  • ajouter //go:embed suivi du chemin du fichier à charger au dessus de la déclaration de la variable
  • référencer la bibliothèque dans les imports à l'aide de "embed"
  • disposer d'un fichier, ici nommé index.txt, qui contient, par exemple, Hello World!

Ci-dessous un programme qui utilise une variable de type embed.FS :

package main

import (
	"embed"
	"fmt"
)

//go:embed index.txt
var fs embed.FS

func main() {
	data, _ := fs.ReadFile("index.txt")
	fmt.Printf("%s", string(data))
}

L'exécution de ce programme ressemble à ce qui suit:

go run main.go
Hello World!

Pour continuer

En fait, il n'y a pas vraiment plus à dire. L'interface est simple et elle offre une solution élégante pour remplacer les nombreux outils tels que go-bindata, gobuffalo/packr, markbates/pkger ou mjibson/esc qui permettaient d'adresser ce besoin. Le principal bénéfice réside dans le fait que vous n'aurez plus à utiliser un Makefile ni go generate pour générer le contenu de votre programme.

Bibliographie

Pour en savoir plus à propos de "embed", regardez les URLs ci-après :