นี่คือ GO SDK สำหรับเฟรมเวิร์ก bufplugin ปัจจุบัน bufplugin-go
มีแพ็คเกจตรวจสอบการตรวจสอบและแพ็คเกจตรวจสอบเพื่อให้ง่ายต่อผู้แต่ง และ ทดสอบปลั๊กอินที่กำหนดเองและการเปลี่ยนแปลงปลั๊กอิน มันห่อหุ้ม bufplugin
API ด้วย pluginrpc-go ในอินเทอร์เฟซและแนวคิดที่ใช้งานง่ายที่จัดระเบียบรอบ API Protoreflect มาตรฐานที่ให้อำนาจส่วนใหญ่ของระบบนิเวศ Protobuf GO bufplugin-go
ยังเป็นกรอบที่ทีม BUF ใช้ในการเขียนกฎผ้าสำลีในตัวและการเปลี่ยนแปลงกฎการเปลี่ยนแปลงภายใน BUF CLI-เราได้ตรวจสอบให้แน่ใจว่า bufplugin-go
มีพลังมากพอที่จะเป็นตัวแทนของกฎผ้าสำลีที่ซับซ้อนที่สุด ในขณะที่ทำให้มันง่ายที่สุดเท่าที่จะเป็นไปได้สำหรับคุณที่จะใช้ หากคุณต้องการเขียนปลั๊กอินผ้าสำลีหรือการเปลี่ยนแปลงวันนี้คุณควรใช้ bufplugin-go
ปลั๊กอินเป็นเพียงไบนารีในระบบของคุณที่ใช้ bufplugin API เมื่อคุณติดตั้งปลั๊กอินเพียงเพิ่มการอ้างอิงและกฎภายใน buf.yaml
ของคุณ ตัวอย่างเช่นหากคุณติดตั้งปลั๊กอินตัวอย่าง buf-plugin-timestamp-suffix บน $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
การกำหนดค่าทั้งหมดใช้งานได้ตามที่คุณคาดหวัง: คุณสามารถกำหนดค่า 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)
ในกรณีนี้ตัวอย่างมีค่าหนึ่งพันคำและเราขอแนะนำให้คุณอ่านตัวอย่างในการตรวจสอบ/ภายใน/ตัวอย่าง/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
และไฟล์ทดสอบ main_test.go
ที่ใช้แพ็คเกจ checktest
เพื่อทดสอบพฤติกรรมปลั๊กอิน แพ็คเกจ 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 กำลังอยู่ในช่วงเบต้าและอาจเปลี่ยนแปลงได้เมื่อเราทำงานกับผู้ใช้ก่อน เราตั้งใจจะจัดส่ง V1.0 ที่มั่นคงภายในสิ้นปี 2567 อย่างไรก็ตามเราเชื่อว่า API อยู่ใกล้กับรูปร่างสุดท้าย
เสนอภายใต้ใบอนุญาต Apache 2