這是Bufplugin框架的GO SDK。 bufplugin-go
當前提供檢查,Checkutil和CheckTest軟件包,以使其對作者進行簡單,並測試自定義棉絨和破壞更改插件。它將bufplugin
API與插件一起包裝在易於使用的接口和概念中,這些接口和概念圍繞標準的ProtoReflect API組織,從而為大多數GO ProtoBuf生態系統提供動力。 bufplugin-go
也是BUF團隊在BUF CLI內使用所有內置的棉絨和破壞變更規則的框架 - 我們確保bufplugin-go
足夠強大,足以代表最複雜的絨毛和打破變化規則同時使其盡可能簡單地使用。如果您今天想撰寫棉絨或打破更改插件,則應使用bufplugin-go
。
插件只是系統上實現Bufplugin API的二進製文件。安裝插件後,只需在buf.yaml
中對其及其規則添加參考。例如,如果您已經在$PATH
上安裝了Buf-Plugin-timestamp-Suffix-Suffix示例插件:
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
所有配置都按照您的期望工作:您可以繼續配置use
, except
, ignore
, ignore_only
,使用// buf:lint:ignore
評論忽略,就像您對內置規則一樣。
可以將插件命名為您想要的任何東西,但是,我們建議按照將您的二進制名稱與buf-plugin-
為了清楚起見。
給定以下文件:
# foo.proto
syntax = "proto3" ;
package foo ;
import "google/protobuf/timestamp.proto" ;
message Foo {
google.protobuf.Timestamp start = 1 ;
google.protobuf.Timestamp end_time = 2 ;
}
以下錯誤將從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)
在這種情況下,示例值得一千個單詞,我們建議您閱讀check/internal/example/cmd中的示例以開始:
TIMESTAMP_SUFFIX
,該插件檢查所有google.protobuf.Timestamp
字段是否具有一致的字段名稱後綴。該後綴可通過插件選項配置。PLUGIN_FIELD_LOWER_SNAKE_CASE
,檢查所有字段名稱均為lower_snake_case
。FIELD_OPTION_SAFE_FOR_ML_SET
的插件和破壞更改規則FIELD_OPTION_SAFE_FOR_ML_STAYS_TRUE
,均屬於FIELD_OPTION_SAFE_FOR_ML
類別。這將圍繞一個示例定制選項acme.option.v1.safe_for_ml
強制實施屬性,旨在表示字段是否安全地用於ML模型。一個組織可能想說的是,必須在其所有模式中明確標記所有領域是安全的或不安全的,並且沒有從安全到不安全的領域變化。該插件將執行此組織側。該示例展示了實施多個規則,對它們進行分類並考慮自定義選項值。PLUGIN_SYNTAX_SPECIFIED
,該插件檢查所有文件是否均具有顯式syntax
聲明。這證明了使用bufplugin
API中存在的其他元數據超出了FileDescriptorProto
所提供的內容。所有這些示例都有一個main.go
插件實現,以及使用checktest
軟件包測試插件行為的main_test.go
測試文件。 checktest
軟件包使用protoCompile來編譯測試.proto
啟用文件,違反您的規則,並將結果註釋與期望進行比較。
這是插件實現的一個簡短示例 - 這就是全部所需的:
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目前正在Beta中,並且隨著我們與早期採用者合作時可能會發生變化。我們打算在2024年底之前運送穩定的V1.0。但是,我們認為API接近其最終形狀。
根據Apache 2許可提供。