Buf的目标是将API开发转向模式驱动的范式,从而为未来铺平道路,使API以服务所有者和客户可以依赖的方式定义。

与简单地暴露REST/JSON服务相比,使用IDL来定义API有很多好处,今天,Protobuf是业界最稳定、最广泛采用的IDL。但就目前的情况来看,使用Protobuf比使用JSON作为数据传输格式要困难得多。

Buf正在建立工具,使Protobuf对服务所有者和客户来说是可靠和友好的,同时保持它在技术上的明显优势。您的组织不需要重新发明轮子来高效地创建、维护和使用Protobuf API。我们将为您处理您的Protobuf管理策略,因此您可以专注于重要的事情。

本篇文章是讲述 buf 使用的第一篇文章,主要讲解使用 buf 定义 proto 文件的 lint 规则。统一的 lint 规则,可以让个人或团队定义的 API 保持一致。

lint

1 创建 buf.yaml 文件 使用 buf mod init 命令创建 buf.yaml 文件。

version: v1
breaking:
  use:
    - FILE
lint:
  use:
    - DEFAULT

使用默认 lint 规则。

2 运行 lint 命令

使用 buf lint 命令运行 lint。

buf lint 命令将进行一下操作:

  • buf.yaml根据您的配置发现所有 Protobuf 文件。
  • 将它们复制到内存中。
  • 编译它们
  • 根据配置的 lint 规则运行编译结果。

3 输出结果

这是我的一个实例文件输出的结果:

api\helloworld\v1\greeter.proto:5:8:google/api/annotations.proto: does not exist
third_party\google\api\annotations.proto:19:8:google/api/http.proto: does not exist
third_party\google\protobuf\descriptor.proto:57:1:duplicate symbol google.protobuf.FileDescriptorSet: already defined as message in "google/protobuf/des
criptor.proto"
third_party\google\protobuf\descriptor.proto:58:3:duplicate symbol google.protobuf.FileDescriptorSet.file: already defined as field in "google/protobuf/
descriptor.proto"
third_party\google\protobuf\descriptor.proto:62:1:duplicate symbol google.protobuf.FileDescriptorProto: already defined as message in "google/protobuf/d
escriptor.proto"
third_party\google\protobuf\descriptor.proto:63:3:duplicate symbol google.protobuf.FileDescriptorProto.name: already defined as field in "google/protobu
f/descriptor.proto"
third_party\google\protobuf\descriptor.proto:64:3:duplicate symbol google.protobuf.FileDescriptorProto.package: already defined as field in "google/prot
obuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:67:3:duplicate symbol google.protobuf.FileDescriptorProto.dependency: already defined as field in "google/p
rotobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:69:3:duplicate symbol google.protobuf.FileDescriptorProto.public_dependency: already defined as field in "g
oogle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:72:3:duplicate symbol google.protobuf.FileDescriptorProto.weak_dependency: already defined as field in "goo
gle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:75:3:duplicate symbol google.protobuf.FileDescriptorProto.message_type: already defined as field in "google
/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:76:3:duplicate symbol google.protobuf.FileDescriptorProto.enum_type: already defined as field in "google/pr
otobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:77:3:duplicate symbol google.protobuf.FileDescriptorProto.service: already defined as field in "google/prot
obuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:78:3:duplicate symbol google.protobuf.FileDescriptorProto.extension: already defined as field in "google/pr
otobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:80:3:duplicate symbol google.protobuf.FileDescriptorProto.options: already defined as field in "google/prot
obuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:86:3:duplicate symbol google.protobuf.FileDescriptorProto.source_code_info: already defined as field in "go
ogle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:90:3:duplicate symbol google.protobuf.FileDescriptorProto.syntax: already defined as field in "google/proto
buf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:94:1:duplicate symbol google.protobuf.DescriptorProto: already defined as message in "google/protobuf/descr
iptor.proto"
third_party\google\protobuf\descriptor.proto:95:3:duplicate symbol google.protobuf.DescriptorProto.name: already defined as field in "google/protobuf/de
scriptor.proto"
third_party\google\protobuf\descriptor.proto:97:3:duplicate symbol google.protobuf.DescriptorProto.field: already defined as field in "google/protobuf/d
escriptor.proto"
third_party\google\protobuf\descriptor.proto:98:3:duplicate symbol google.protobuf.DescriptorProto.extension: already defined as field in "google/protob
uf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:100:3:duplicate symbol google.protobuf.DescriptorProto.nested_type: already defined as field in "google/pro
tobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:101:3:duplicate symbol google.protobuf.DescriptorProto.enum_type: already defined as field in "google/proto
buf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:103:3:duplicate symbol google.protobuf.DescriptorProto.ExtensionRange: already defined as message in "googl
e/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:104:5:duplicate symbol google.protobuf.DescriptorProto.ExtensionRange.start: already defined as field in "g
oogle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:105:5:duplicate symbol google.protobuf.DescriptorProto.ExtensionRange.end: already defined as field in "goo
gle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:107:5:duplicate symbol google.protobuf.DescriptorProto.ExtensionRange.options: already defined as field in 
"google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:109:3:duplicate symbol google.protobuf.DescriptorProto.extension_range: already defined as field in "google
/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:111:3:duplicate symbol google.protobuf.DescriptorProto.oneof_decl: already defined as field in "google/prot
obuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:113:3:duplicate symbol google.protobuf.DescriptorProto.options: already defined as field in "google/protobu
f/descriptor.proto"
third_party\google\protobuf\descriptor.proto:118:3:duplicate symbol google.protobuf.DescriptorProto.ReservedRange: already defined as message in "google
/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:119:5:duplicate symbol google.protobuf.DescriptorProto.ReservedRange.start: already defined as field in "go
ogle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:120:5:duplicate symbol google.protobuf.DescriptorProto.ReservedRange.end: already defined as field in "goog
le/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:122:3:duplicate symbol google.protobuf.DescriptorProto.reserved_range: already defined as field in "google/
protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:125:3:duplicate symbol google.protobuf.DescriptorProto.reserved_name: already defined as field in "google/p
rotobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:128:1:duplicate symbol google.protobuf.ExtensionRangeOptions: already defined as message in "google/protobu
f/descriptor.proto"
third_party\google\protobuf\descriptor.proto:130:3:duplicate symbol google.protobuf.ExtensionRangeOptions.uninterpreted_option: already defined as field
 in "google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:138:1:duplicate symbol google.protobuf.FieldDescriptorProto: already defined as message in "google/protobuf
/descriptor.proto"
third_party\google\protobuf\descriptor.proto:139:3:duplicate symbol google.protobuf.FieldDescriptorProto.Type: already defined as enum in "google/protob
uf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:142:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_DOUBLE: already defined as enum value in "
google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:143:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_FLOAT: already defined as enum value in "g
oogle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:146:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_INT64: already defined as enum value in "g
oogle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:147:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_UINT64: already defined as enum value in "
google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:150:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_INT32: already defined as enum value in "g
oogle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:151:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_FIXED64: already defined as enum value in 
"google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:152:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_FIXED32: already defined as enum value in 
"google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:153:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_BOOL: already defined as enum value in "go
ogle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:154:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_STRING: already defined as enum value in "
google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:159:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_GROUP: already defined as enum value in "g
oogle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:160:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_MESSAGE: already defined as enum value in 
"google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:163:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_BYTES: already defined as enum value in "g
oogle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:164:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_UINT32: already defined as enum value in "
google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:165:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_ENUM: already defined as enum value in "go
ogle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:166:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_SFIXED32: already defined as enum value in
 "google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:167:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_SFIXED64: already defined as enum value in
 "google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:168:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_SINT32: already defined as enum value in "
google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:169:5:duplicate symbol google.protobuf.FieldDescriptorProto.TYPE_SINT64: already defined as enum value in "
google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:172:3:duplicate symbol google.protobuf.FieldDescriptorProto.Label: already defined as enum in "google/proto
buf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:174:5:duplicate symbol google.protobuf.FieldDescriptorProto.LABEL_OPTIONAL: already defined as enum value i
n "google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:175:5:duplicate symbol google.protobuf.FieldDescriptorProto.LABEL_REQUIRED: already defined as enum value i
n "google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:176:5:duplicate symbol google.protobuf.FieldDescriptorProto.LABEL_REPEATED: already defined as enum value i
n "google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:179:3:duplicate symbol google.protobuf.FieldDescriptorProto.name: already defined as field in "google/proto
buf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:180:3:duplicate symbol google.protobuf.FieldDescriptorProto.number: already defined as field in "google/pro
tobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:181:3:duplicate symbol google.protobuf.FieldDescriptorProto.label: already defined as field in "google/prot
obuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:185:3:duplicate symbol google.protobuf.FieldDescriptorProto.type: already defined as field in "google/proto
buf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:192:3:duplicate symbol google.protobuf.FieldDescriptorProto.type_name: already defined as field in "google/
protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:196:3:duplicate symbol google.protobuf.FieldDescriptorProto.extendee: already defined as field in "google/p
rotobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:203:3:duplicate symbol google.protobuf.FieldDescriptorProto.default_value: already defined as field in "goo
gle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:207:3:duplicate symbol google.protobuf.FieldDescriptorProto.oneof_index: already defined as field in "googl
e/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:213:3:duplicate symbol google.protobuf.FieldDescriptorProto.json_name: already defined as field in "google/
protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:215:3:duplicate symbol google.protobuf.FieldDescriptorProto.options: already defined as field in "google/pr
otobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:238:3:duplicate symbol google.protobuf.FieldDescriptorProto.proto3_optional: already defined as field in "g
oogle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:242:1:duplicate symbol google.protobuf.OneofDescriptorProto: already defined as message in "google/protobuf
/descriptor.proto"
third_party\google\protobuf\descriptor.proto:243:3:duplicate symbol google.protobuf.OneofDescriptorProto.name: already defined as field in "google/proto
buf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:244:3:duplicate symbol google.protobuf.OneofDescriptorProto.options: already defined as field in "google/pr
otobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:248:1:duplicate symbol google.protobuf.EnumDescriptorProto: already defined as message in "google/protobuf/
descriptor.proto"
third_party\google\protobuf\descriptor.proto:249:3:duplicate symbol google.protobuf.EnumDescriptorProto.name: already defined as field in "google/protob
uf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:251:3:duplicate symbol google.protobuf.EnumDescriptorProto.value: already defined as field in "google/proto
buf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:253:3:duplicate symbol google.protobuf.EnumDescriptorProto.options: already defined as field in "google/pro
tobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:261:3:duplicate symbol google.protobuf.EnumDescriptorProto.EnumReservedRange: already defined as message in
 "google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:262:5:duplicate symbol google.protobuf.EnumDescriptorProto.EnumReservedRange.start: already defined as fiel
d in "google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:263:5:duplicate symbol google.protobuf.EnumDescriptorProto.EnumReservedRange.end: already defined as field 
in "google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:269:3:duplicate symbol google.protobuf.EnumDescriptorProto.reserved_range: already defined as field in "goo
gle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:273:3:duplicate symbol google.protobuf.EnumDescriptorProto.reserved_name: already defined as field in "goog
le/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:277:1:duplicate symbol google.protobuf.EnumValueDescriptorProto: already defined as message in "google/prot
obuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:278:3:duplicate symbol google.protobuf.EnumValueDescriptorProto.name: already defined as field in "google/p
rotobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:279:3:duplicate symbol google.protobuf.EnumValueDescriptorProto.number: already defined as field in "google
/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:281:3:duplicate symbol google.protobuf.EnumValueDescriptorProto.options: already defined as field in "googl
e/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:285:1:duplicate symbol google.protobuf.ServiceDescriptorProto: already defined as message in "google/protob
uf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:286:3:duplicate symbol google.protobuf.ServiceDescriptorProto.name: already defined as field in "google/pro
tobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:287:3:duplicate symbol google.protobuf.ServiceDescriptorProto.method: already defined as field in "google/p
rotobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:289:3:duplicate symbol google.protobuf.ServiceDescriptorProto.options: already defined as field in "google/
protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:293:1:duplicate symbol google.protobuf.MethodDescriptorProto: already defined as message in "google/protobu
f/descriptor.proto"
third_party\google\protobuf\descriptor.proto:294:3:duplicate symbol google.protobuf.MethodDescriptorProto.name: already defined as field in "google/prot
obuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:298:3:duplicate symbol google.protobuf.MethodDescriptorProto.input_type: already defined as field in "googl
e/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:299:3:duplicate symbol google.protobuf.MethodDescriptorProto.output_type: already defined as field in "goog
le/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:301:3:duplicate symbol google.protobuf.MethodDescriptorProto.options: already defined as field in "google/p
rotobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:304:3:duplicate symbol google.protobuf.MethodDescriptorProto.client_streaming: already defined as field in 
"google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:306:3:duplicate symbol google.protobuf.MethodDescriptorProto.server_streaming: already defined as field in 
"google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:342:1:duplicate symbol google.protobuf.FileOptions: already defined as message in "google/protobuf/descript
or.proto"
third_party\google\protobuf\descriptor.proto:348:3:duplicate symbol google.protobuf.FileOptions.java_package: already defined as field in "google/protob
uf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:356:3:duplicate symbol google.protobuf.FileOptions.java_outer_classname: already defined as field in "googl
e/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:364:3:duplicate symbol google.protobuf.FileOptions.java_multiple_files: already defined as field in "google
/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:367:3:duplicate symbol google.protobuf.FileOptions.java_generate_equals_and_hash: already defined as field 
in "google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:375:3:duplicate symbol google.protobuf.FileOptions.java_string_check_utf8: already defined as field in "goo
gle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:379:3:duplicate symbol google.protobuf.FileOptions.OptimizeMode: already defined as enum in "google/protobu
f/descriptor.proto"
third_party\google\protobuf\descriptor.proto:380:5:duplicate symbol google.protobuf.FileOptions.SPEED: already defined as enum value in "google/protobuf
/descriptor.proto"
third_party\google\protobuf\descriptor.proto:382:5:duplicate symbol google.protobuf.FileOptions.CODE_SIZE: already defined as enum value in "google/prot
obuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:383:5:duplicate symbol google.protobuf.FileOptions.LITE_RUNTIME: already defined as enum value in "google/p
rotobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:385:3:duplicate symbol google.protobuf.FileOptions.optimize_for: already defined as field in "google/protob
uf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:392:3:duplicate symbol google.protobuf.FileOptions.go_package: already defined as field in "google/protobuf
/descriptor.proto"
third_party\google\protobuf\descriptor.proto:407:3:duplicate symbol google.protobuf.FileOptions.cc_generic_services: already defined as field in "google
/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:408:3:duplicate symbol google.protobuf.FileOptions.java_generic_services: already defined as field in "goog
le/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:409:3:duplicate symbol google.protobuf.FileOptions.py_generic_services: already defined as field in "google
/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:410:3:duplicate symbol google.protobuf.FileOptions.php_generic_services: already defined as field in "googl
e/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:416:3:duplicate symbol google.protobuf.FileOptions.deprecated: already defined as field in "google/protobuf
/descriptor.proto"
third_party\google\protobuf\descriptor.proto:420:3:duplicate symbol google.protobuf.FileOptions.cc_enable_arenas: already defined as field in "google/pr
otobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:425:3:duplicate symbol google.protobuf.FileOptions.objc_class_prefix: already defined as field in "google/p
rotobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:428:3:duplicate symbol google.protobuf.FileOptions.csharp_namespace: already defined as field in "google/pr
otobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:434:3:duplicate symbol google.protobuf.FileOptions.swift_prefix: already defined as field in "google/protob
uf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:438:3:duplicate symbol google.protobuf.FileOptions.php_class_prefix: already defined as field in "google/pr
otobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:443:3:duplicate symbol google.protobuf.FileOptions.php_namespace: already defined as field in "google/proto
buf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:448:3:duplicate symbol google.protobuf.FileOptions.php_metadata_namespace: already defined as field in "goo
gle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:453:3:duplicate symbol google.protobuf.FileOptions.ruby_package: already defined as field in "google/protob
uf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:458:3:duplicate symbol google.protobuf.FileOptions.uninterpreted_option: already defined as field in "googl
e/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:467:1:duplicate symbol google.protobuf.MessageOptions: already defined as message in "google/protobuf/descr
iptor.proto"
third_party\google\protobuf\descriptor.proto:486:3:duplicate symbol google.protobuf.MessageOptions.message_set_wire_format: already defined as field in 
"google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:491:3:duplicate symbol google.protobuf.MessageOptions.no_standard_descriptor_accessor: already defined as f
ield in "google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:497:3:duplicate symbol google.protobuf.MessageOptions.deprecated: already defined as field in "google/proto
buf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:522:3:duplicate symbol google.protobuf.MessageOptions.map_entry: already defined as field in "google/protob
uf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:529:3:duplicate symbol google.protobuf.MessageOptions.uninterpreted_option: already defined as field in "go
ogle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:535:1:duplicate symbol google.protobuf.FieldOptions: already defined as message in "google/protobuf/descrip
tor.proto"
third_party\google\protobuf\descriptor.proto:540:3:duplicate symbol google.protobuf.FieldOptions.ctype: already defined as field in "google/protobuf/des
criptor.proto"
third_party\google\protobuf\descriptor.proto:541:3:duplicate symbol google.protobuf.FieldOptions.CType: already defined as enum in "google/protobuf/desc
riptor.proto"
third_party\google\protobuf\descriptor.proto:543:5:duplicate symbol google.protobuf.FieldOptions.STRING: already defined as enum value in "google/protob
uf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:545:5:duplicate symbol google.protobuf.FieldOptions.CORD: already defined as enum value in "google/protobuf
/descriptor.proto"
third_party\google\protobuf\descriptor.proto:547:5:duplicate symbol google.protobuf.FieldOptions.STRING_PIECE: already defined as enum value in "google/
protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:554:3:duplicate symbol google.protobuf.FieldOptions.packed: already defined as field in "google/protobuf/de
scriptor.proto"
third_party\google\protobuf\descriptor.proto:567:3:duplicate symbol google.protobuf.FieldOptions.jstype: already defined as field in "google/protobuf/de
scriptor.proto"
third_party\google\protobuf\descriptor.proto:568:3:duplicate symbol google.protobuf.FieldOptions.JSType: already defined as enum in "google/protobuf/des
criptor.proto"
third_party\google\protobuf\descriptor.proto:570:5:duplicate symbol google.protobuf.FieldOptions.JS_NORMAL: already defined as enum value in "google/pro
tobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:573:5:duplicate symbol google.protobuf.FieldOptions.JS_STRING: already defined as enum value in "google/pro
tobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:576:5:duplicate symbol google.protobuf.FieldOptions.JS_NUMBER: already defined as enum value in "google/pro
tobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:607:3:duplicate symbol google.protobuf.FieldOptions.lazy: already defined as field in "google/protobuf/desc
riptor.proto"
third_party\google\protobuf\descriptor.proto:613:3:duplicate symbol google.protobuf.FieldOptions.deprecated: already defined as field in "google/protobu
f/descriptor.proto"
third_party\google\protobuf\descriptor.proto:616:3:duplicate symbol google.protobuf.FieldOptions.weak: already defined as field in "google/protobuf/desc
riptor.proto"
third_party\google\protobuf\descriptor.proto:620:3:duplicate symbol google.protobuf.FieldOptions.uninterpreted_option: already defined as field in "goog
le/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:628:1:duplicate symbol google.protobuf.OneofOptions: already defined as message in "google/protobuf/descrip
tor.proto"
third_party\google\protobuf\descriptor.proto:630:3:duplicate symbol google.protobuf.OneofOptions.uninterpreted_option: already defined as field in "goog
le/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:636:1:duplicate symbol google.protobuf.EnumOptions: already defined as message in "google/protobuf/descript
or.proto"
third_party\google\protobuf\descriptor.proto:640:3:duplicate symbol google.protobuf.EnumOptions.allow_alias: already defined as field in "google/protobu
f/descriptor.proto"
third_party\google\protobuf\descriptor.proto:646:3:duplicate symbol google.protobuf.EnumOptions.deprecated: already defined as field in "google/protobuf
/descriptor.proto"
third_party\google\protobuf\descriptor.proto:651:3:duplicate symbol google.protobuf.EnumOptions.uninterpreted_option: already defined as field in "googl
e/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:657:1:duplicate symbol google.protobuf.EnumValueOptions: already defined as message in "google/protobuf/des
criptor.proto"
third_party\google\protobuf\descriptor.proto:662:3:duplicate symbol google.protobuf.EnumValueOptions.deprecated: already defined as field in "google/pro
tobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:665:3:duplicate symbol google.protobuf.EnumValueOptions.uninterpreted_option: already defined as field in "
google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:671:1:duplicate symbol google.protobuf.ServiceOptions: already defined as message in "google/protobuf/descr
iptor.proto"
third_party\google\protobuf\descriptor.proto:682:3:duplicate symbol google.protobuf.ServiceOptions.deprecated: already defined as field in "google/proto
buf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:685:3:duplicate symbol google.protobuf.ServiceOptions.uninterpreted_option: already defined as field in "go
ogle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:691:1:duplicate symbol google.protobuf.MethodOptions: already defined as message in "google/protobuf/descri
ptor.proto"
third_party\google\protobuf\descriptor.proto:702:3:duplicate symbol google.protobuf.MethodOptions.deprecated: already defined as field in "google/protob
uf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:707:3:duplicate symbol google.protobuf.MethodOptions.IdempotencyLevel: already defined as enum in "google/p
rotobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:708:5:duplicate symbol google.protobuf.MethodOptions.IDEMPOTENCY_UNKNOWN: already defined as enum value in 
"google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:709:5:duplicate symbol google.protobuf.MethodOptions.NO_SIDE_EFFECTS: already defined as enum value in "goo
gle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:710:5:duplicate symbol google.protobuf.MethodOptions.IDEMPOTENT: already defined as enum value in "google/p
rotobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:712:3:duplicate symbol google.protobuf.MethodOptions.idempotency_level: already defined as field in "google
/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:716:3:duplicate symbol google.protobuf.MethodOptions.uninterpreted_option: already defined as field in "goo
gle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:729:1:duplicate symbol google.protobuf.UninterpretedOption: already defined as message in "google/protobuf/
descriptor.proto"
third_party\google\protobuf\descriptor.proto:735:3:duplicate symbol google.protobuf.UninterpretedOption.NamePart: already defined as message in "google/
protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:736:5:duplicate symbol google.protobuf.UninterpretedOption.NamePart.name_part: already defined as field in 
"google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:737:5:duplicate symbol google.protobuf.UninterpretedOption.NamePart.is_extension: already defined as field 
in "google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:739:3:duplicate symbol google.protobuf.UninterpretedOption.name: already defined as field in "google/protob
uf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:743:3:duplicate symbol google.protobuf.UninterpretedOption.identifier_value: already defined as field in "g
oogle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:744:3:duplicate symbol google.protobuf.UninterpretedOption.positive_int_value: already defined as field in 
"google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:745:3:duplicate symbol google.protobuf.UninterpretedOption.negative_int_value: already defined as field in 
"google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:746:3:duplicate symbol google.protobuf.UninterpretedOption.double_value: already defined as field in "googl
e/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:747:3:duplicate symbol google.protobuf.UninterpretedOption.string_value: already defined as field in "googl
e/protobuf/descriptor.proto"
n "google/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:904:5:duplicate symbol google.protobuf.GeneratedCodeInfo.Annotation.begin: already defined as field in "goo
gle/protobuf/descriptor.proto"
third_party\google\protobuf\descriptor.proto:909:5:duplicate symbol google.protobuf.GeneratedCodeInfo.Annotation.end: already defined as field in "googl
e/protobuf/descriptor.proto"

提示的错误会以如下形式展示: {文件} :{行} :{列} :{错误消息}

Docker 映像

Buf 提供了一个 Docker 映像,bufbuild/buf它使您能够将buf其用作 Docker 工作流程的一部分

docker run \
  --volume "$(pwd):/workspace" \
  --workdir /workspace \
  bufbuild/buf lint

小结

本篇是 buf 介绍的第一篇,简单介绍了 buf lint的使用,后面会介绍如何自定义规则和 buf 的其他用法。