{"id":15074353,"url":"https://github.com/bufbuild/bufplugin-go","last_synced_at":"2025-04-10T18:44:29.119Z","repository":{"id":255551599,"uuid":"852386611","full_name":"bufbuild/bufplugin-go","owner":"bufbuild","description":"The Go library for plugins to the Buf platform.","archived":false,"fork":false,"pushed_at":"2025-01-31T20:54:41.000Z","size":155,"stargazers_count":22,"open_issues_count":1,"forks_count":0,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-04-01T16:57:15.404Z","etag":null,"topics":["grpc","protobuf","protocol-buffers"],"latest_commit_sha":null,"homepage":"https://buf.build/go/bufplugin","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bufbuild.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-04T18:05:23.000Z","updated_at":"2025-03-30T00:53:02.000Z","dependencies_parsed_at":"2024-10-24T04:37:35.509Z","dependency_job_id":"d1ef9b05-d0bd-4edc-bfcd-d11bd72d08d5","html_url":"https://github.com/bufbuild/bufplugin-go","commit_stats":{"total_commits":6,"total_committers":2,"mean_commits":3.0,"dds":"0.16666666666666663","last_synced_commit":"17e55c964da68aab7275600d7f07f7fb524ba2ca"},"previous_names":["bufbuild/bufplugin-go"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bufbuild%2Fbufplugin-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bufbuild%2Fbufplugin-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bufbuild%2Fbufplugin-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bufbuild%2Fbufplugin-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bufbuild","download_url":"https://codeload.github.com/bufbuild/bufplugin-go/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248271921,"owners_count":21075800,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["grpc","protobuf","protocol-buffers"],"created_at":"2024-09-25T03:32:29.294Z","updated_at":"2025-04-10T18:44:29.100Z","avatar_url":"https://github.com/bufbuild.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bufplugin-go\n\n[![Build](https://github.com/bufbuild/bufplugin-go/actions/workflows/ci.yaml/badge.svg?branch=main)](https://github.com/bufbuild/bufplugin-go/actions/workflows/ci.yaml)\n[![Report Card](https://goreportcard.com/badge/buf.build/go/bufplugin)](https://goreportcard.com/report/buf.build/go/bufplugin)\n[![GoDoc](https://pkg.go.dev/badge/buf.build/go/bufplugin.svg)](https://pkg.go.dev/buf.build/go/bufplugin)\n[![Slack](https://img.shields.io/badge/slack-buf-%23e01563)](https://buf.build/links/slack)\n\nThis is the Go SDK for the [Bufplugin](https://github.com/bufbuild/bufplugin) framework.\n`bufplugin-go` currently provides the [check](https://pkg.go.dev/buf.build/go/bufplugin/check),\n[checkutil](https://pkg.go.dev/buf.build/go/bufplugin/check/checkutil), and\n[checktest](https://pkg.go.dev/buf.build/go/bufplugin/check/checktest) packages to make it simple to\nauthor _and_ test custom lint and breaking change plugins. It wraps the `bufplugin` API with\n[pluginrpc-go](https://github.com/pluginrpc/pluginrpc-go) in easy-to-use interfaces and concepts\nthat organize around the standard\n[protoreflect](https://pkg.go.dev/google.golang.org/protobuf@v1.34.2/reflect/protoreflect) API that\npowers most of the Go Protobuf ecosystem. `bufplugin-go` is also the framework that the Buf team\nuses to author all of the builtin lint and breaking change rules within the\n[Buf CLI](https://github.com/bufbuild/buf) - we've made sure that `bufplugin-go` is powerful enough\nto represent the most complex lint and breaking change rules while keeping it as simple as possible\nfor you to use. If you want to author a lint or breaking change plugin today, you should use\n`bufplugin-go`.\n\n## Use\n\nA plugin is just a binary on your system that implements the\n[Bufplugin API](https://buf.build/bufbuild/bufplugin). Once you've installed a plugin, simply add a\nreference to it and its rules within your `buf.yaml`. For example, if you've installed the\n[buf-plugin-timestamp-suffix](check/internal/example/cmd/buf-plugin-timestamp-suffix) example plugin\non your `$PATH`:\n\n```yaml\nversion: v2\nlint:\n  use:\n    - TIMESTAMP_SUFFIX\nplugins:\n  - plugin: buf-plugin-timestamp-suffix\n    options:\n      timestamp_suffix: _time # set to the suffix you'd like to enforce\n```\n\nAll [configuration](https://buf.build/docs/configuration/v2/buf-yaml) works as you'd expect: you can\ncontinue to configure `use`, `except`, `ignore`, `ignore_only` and use `// buf:lint:ignore` comment\nignores, just as you would for the builtin rules.\n\nPlugins can be named whatever you'd like them to be, however we'd recommend following the convention\nof prefixing your binary names with `buf-plugin-` for clarity.\n\nGiven the following file:\n\n```protobuf\n# foo.proto\nsyntax = \"proto3\";\n\npackage foo;\n\nimport \"google/protobuf/timestamp.proto\";\n\nmessage Foo {\n  google.protobuf.Timestamp start = 1;\n  google.protobuf.Timestamp end_time = 2;\n}\n```\n\nThe following error will be returned from `buf lint`:\n\n```\nfoo.proto:8:3:Fields of type google.protobuf.Timestamp must end in \"_time\" but field name was \"start\". (buf-plugin-timestamp-suffix)\n```\n\n## Examples\n\nIn this case, examples are worth a thousand words, and we recommend you read the examples in\n[check/internal/example/cmd](check/internal/example/cmd) to get started:\n\n- [buf-plugin-timestamp-suffix](check/internal/example/cmd/buf-plugin-timestamp-suffix): A simple\n  plugin that implements a single lint rule, `TIMESTAMP_SUFFIX`, that checks that all\n  `google.protobuf.Timestamp` fields have a consistent suffix for their field name. This suffix is\n  configurable via plugin options.\n- [buf-plugin-field-lower-snake-case](check/internal/example/cmd/buf-plugin-field-lower-snake-case):\n  A simple plugin that implements a single lint rule, `PLUGIN_FIELD_LOWER_SNAKE_CASE`, that checks\n  that all field names are `lower_snake_case`.\n- [buf-plugin-field-option-safe-for-ml](check/internal/example/cmd/buf-plugin-field-option-safe-for-ml):\n  Likely the most interesting of the examples. A plugin that implements a lint rule\n  `FIELD_OPTION_SAFE_FOR_ML_SET` and a breaking change rule `FIELD_OPTION_SAFE_FOR_ML_STAYS_TRUE`,\n  both belonging to the `FIELD_OPTION_SAFE_FOR_ML` category. This enforces properties around an\n  example custom option `acme.option.v1.safe_for_ml`, meant to denote whether or not a field is safe\n  to use in ML models. An organization may want to say that all fields must be explicitly marked as\n  safe or unsafe across all of their schemas, and no field changes from safe to unsafe. This plugin\n  would enforce this organization-side. The example shows off implementing multiple rules,\n  categorizing them, and taking custom option values into account.\n- [buf-plugin-syntax-specified](check/internal/example/cmd/buf-plugin-syntax-specified): A simple\n  plugin that implements a single lint rule, `PLUGIN_SYNTAX_SPECIFIED`, that checks that all files\n  have an explicit `syntax` declaration. This demonstrates using additional metadata present in the\n  `bufplugin` API beyond what a `FileDescriptorProto` provides.\n\nAll of these examples have a `main.go` plugin implementation, and a `main_test.go` test file that\nuses the `checktest` package to test the plugin behavior. The `checktest` package uses\n[protocompile](https://github.com/bufbuild/protocompile) to compile test `.proto` files on the fly,\nrun them against your rules, and compare the resulting annotations against an expectation.\n\nHere's a short example of a plugin implementation - this is all it takes:\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\n\t\"buf.build/go/bufplugin/check\"\n\t\"buf.build/go/bufplugin/check/checkutil\"\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n)\n\nfunc main() {\n\tcheck.Main(\n\t\t\u0026check.Spec{\n\t\t\tRules: []*check.RuleSpec{\n\t\t\t\t{\n\t\t\t\t\tID:      \"PLUGIN_FIELD_LOWER_SNAKE_CASE\",\n\t\t\t\t\tDefault: true,\n\t\t\t\t\tPurpose: \"Checks that all field names are lower_snake_case.\",\n\t\t\t\t\tType:    check.RuleTypeLint,\n\t\t\t\t\tHandler: checkutil.NewFieldRuleHandler(checkFieldLowerSnakeCase, checkutil.WithoutImports()),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t)\n}\n\nfunc checkFieldLowerSnakeCase(\n\t_ context.Context,\n\tresponseWriter check.ResponseWriter,\n\t_ check.Request,\n\tfieldDescriptor protoreflect.FieldDescriptor,\n) error {\n\tfieldName := string(fieldDescriptor.Name())\n\tfieldNameToLowerSnakeCase := toLowerSnakeCase(fieldName)\n\tif fieldName != fieldNameToLowerSnakeCase {\n\t\tresponseWriter.AddAnnotation(\n\t\t\tcheck.WithMessagef(\n\t\t\t\t\"Field name %q should be lower_snake_case, such as %q.\",\n\t\t\t\tfieldName,\n\t\t\t\tfieldNameToLowerSnakeCase,\n\t\t\t),\n\t\t\tcheck.WithDescriptor(fieldDescriptor),\n\t\t)\n\t}\n\treturn nil\n}\n\nfunc toLowerSnakeCase(fieldName string) string {\n\t// The actual logic for toLowerSnakeCase would go here.\n\treturn \"TODO\"\n}\n```\n\n## Status: Beta\n\nBufplugin is currently in beta, and may change as we work with early adopters. We're intending to\nship a stable v1.0 by the end of 2024. However, we believe the API is near its final shape.\n\n## Legal\n\nOffered under the [Apache 2 license](https://github.com/bufbuild/bufplugin-go/blob/main/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbufbuild%2Fbufplugin-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbufbuild%2Fbufplugin-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbufbuild%2Fbufplugin-go/lists"}