Ceci est le SDK Go pour le framework Bufplugin. bufplugin-go
fournit actuellement les packages Check, CheckUtil et CheckTest pour rendre les plugins simples à auteur et à tester des peluches et de la rupture personnalisées. Il enveloppe l'API bufplugin
avec Pluginrpc-Go dans des interfaces et des concepts faciles à utiliser qui s'organisent autour de l'API Protoreflect standard qui alimente la plupart de l'écosystème GO Protobuf. bufplugin-go
est également le cadre que l'équipe BUF utilise pour autoriser toutes les règles de la peluche et de rupture intégrées au sein de la CLI BUF - nous nous sommes assurés que bufplugin-go
est suffisamment puissant pour représenter les règles de peluche la plus complexes et les règles de changement de rupture tout en le gardant aussi simple que possible pour vous. Si vous souhaitez rédiger un plugin de peluche ou de changement aujourd'hui, vous devez utiliser bufplugin-go
.
Un plugin est juste un binaire sur votre système qui implémente l'API Bufplugin. Une fois que vous avez installé un plugin, ajoutez simplement une référence et ses règles dans votre buf.yaml
. Par exemple, si vous avez installé le plugin Buf-Plugin-Timestamp-Suffix Exemple sur votre $PATH
:
version : v2
lint :
use :
- TIMESTAMP_SUFFIX
plugins :
- plugin : buf-plugin-timestamp-suffix
options :
timestamp_suffix : _time # set to the suffix you'd like to enforce
Toute la configuration fonctionne comme vous vous en doutez: vous pouvez continuer à configurer use
, except
ignore
, ignore_only
et utiliser // buf:lint:ignore
le commentaire ignore, tout comme vous le feriez pour les règles intégrées.
Les plugins peuvent être nommés ce que vous souhaitez qu'ils soient, mais nous recommandons de suivre la convention de préfixation de vos noms binaires avec buf-plugin-
pour plus de clarté.
Compte tenu du fichier suivant:
# foo.proto
syntax = "proto3" ;
package foo ;
import "google/protobuf/timestamp.proto" ;
message Foo {
google.protobuf.Timestamp start = 1 ;
google.protobuf.Timestamp end_time = 2 ;
}
L'erreur suivante sera renvoyée de buf lint
:
foo.proto:8:3:Fields of type google.protobuf.Timestamp must end in "_time" but field name was "start". (buf-plugin-timestamp-suffix)
Dans ce cas, des exemples valent mille mots, et nous vous recommandons de lire les exemples en chèque / interne / exemple / cmd pour commencer:
TIMESTAMP_SUFFIX
, qui vérifie que tous les champs google.protobuf.Timestamp
ont un suffixe cohérent pour leur nom de champ. Ce suffixe est configurable via des options de plugin.PLUGIN_FIELD_LOWER_SNAKE_CASE
, qui vérifie que tous les noms de champ sont lower_snake_case
.FIELD_OPTION_SAFE_FOR_ML_SET
et une règle de changement de changement FIELD_OPTION_SAFE_FOR_ML_STAYS_TRUE
, tous deux appartenant à la catégorie FIELD_OPTION_SAFE_FOR_ML
. Cela applique des propriétés autour d'un exemple d'option personnalisée acme.option.v1.safe_for_ml
, destinée à indiquer si un champ est sûr ou non dans les modèles ML. Une organisation peut vouloir dire que tous les domaines doivent être explicitement marqués comme sûrs ou dangereux dans tous leurs schémas, et aucun changement de champ, de la sécurité à dangereux. Ce plugin appliquerait cette organisation côté organisation. L'exemple montre la mise en œuvre de plusieurs règles, les catégoriser et la prise en compte des valeurs d'options personnalisées.PLUGIN_SYNTAX_SPECIFIED
, qui vérifie que tous les fichiers ont une déclaration syntax
explicite. Cela démontre l'utilisation de métadonnées supplémentaires présentes dans l'API bufplugin
au-delà de ce qu'un FileDescriptorProto
fournit. Tous ces exemples ont une implémentation du plugin main.go
et un fichier de test main_test.go
qui utilise le package checktest
pour tester le comportement du plugin. Le package checktest
utilise le protocompile pour compiler les fichiers de test .proto
à la volée, les exécuter contre vos règles et comparer les annotations qui en résultent avec une attente.
Voici un court exemple d'implémentation de plugin - c'est tout ce qu'il faut:
package main
import (
"context"
"buf.build/go/bufplugin/check"
"buf.build/go/bufplugin/check/checkutil"
"google.golang.org/protobuf/reflect/protoreflect"
)
func main () {
check . Main (
& check. Spec {
Rules : [] * check. RuleSpec {
{
ID : "PLUGIN_FIELD_LOWER_SNAKE_CASE" ,
Default : true ,
Purpose : "Checks that all field names are lower_snake_case." ,
Type : check . RuleTypeLint ,
Handler : checkutil . NewFieldRuleHandler ( checkFieldLowerSnakeCase , checkutil . WithoutImports ()),
},
},
},
)
}
func checkFieldLowerSnakeCase (
_ context. Context ,
responseWriter check. ResponseWriter ,
_ check. Request ,
fieldDescriptor protoreflect. FieldDescriptor ,
) error {
fieldName := string ( fieldDescriptor . Name ())
fieldNameToLowerSnakeCase := toLowerSnakeCase ( fieldName )
if fieldName != fieldNameToLowerSnakeCase {
responseWriter . AddAnnotation (
check . WithMessagef (
"Field name %q should be lower_snake_case, such as %q." ,
fieldName ,
fieldNameToLowerSnakeCase ,
),
check . WithDescriptor ( fieldDescriptor ),
)
}
return nil
}
func toLowerSnakeCase ( fieldName string ) string {
// The actual logic for toLowerSnakeCase would go here.
return "TODO"
}
Bufplugin est actuellement en version bêta et peut changer lorsque nous travaillons avec les premiers adoptants. Nous avons l'intention d'expédier un V1.0 stable d'ici la fin de 2024. Cependant, nous pensons que l'API est près de sa forme finale.
Offert sous la licence Apache 2.