Skip to content

Linting – Tutorial

Buf offers linting for Protobuf files via the buf lint command in the Buf CLI. In this tutorial, we'll explore how to use linting to maintain code quality and consistency in your projects. Read the overview to learn about editor integration and see usage examples.

Prerequisites

We recommend completing the Buf CLI tour to get an overview of the Buf CLI first.

  • Install the Buf CLI
  • Clone the buf-tour repo:
    $ git clone git@github.com:bufbuild/buf-tour.git
    

1. Inspect the workspace

Modules represent a collection of files that are configured, built, and versioned as a logical unit when performing Buf operations. Workspaces are collections of modules and are configured by the buf.yaml configuration file, which should generally be put above the directories that contain the modules within it. The example code provides a workspace and module to work with, so start there. From the directory you cloned into, go to the tutorial code:

$ cd buf-tour/start/tutorial-lint

Your module has the directory structure shown below, and is defined by the buf.yaml file at the root. This workspace is your input for the buf lint commands in the rest of the tutorial.

tutorial-lint
├── buf.yaml
└── proto
    └── acme
        └── weather
            └── v1
                └── weather.proto

The example buf.yaml file contains all of its required fields. The lint field controls your lint settings. It's set to our recommended default of STANDARD, which includes every rule we feel is important for modern Protobuf development.

proto/buf.yaml
version: v2
modules:
  - path: proto
    name: buf.build/tutorials/lint
lint:
  use:
    - STANDARD
breaking:
  use:
    - FILE

For more information about specific fields, see the buf.yaml reference.

2. Run lint

Run buf lint on your workspace—it lints the proto directory since that's defined as the module path:

~/.../buf-tour/start/tutorial-lint/
$ buf lint

proto/acme/weather/v1/weather.proto:3:1:Files with package "weather" must be within a directory "weather" relative to root but were in directory "proto/acme/weather/v1".
proto/acme/weather/v1/weather.proto:3:1:Package name "weather" should be suffixed with a correctly formed version, such as "weather.v1".
proto/acme/weather/v1/weather.proto:6:3:Enum value name "SUNNY" should be prefixed with "CONDITION_".
proto/acme/weather/v1/weather.proto:6:3:Enum zero value name "SUNNY" should be suffixed with "_UNSPECIFIED".
proto/acme/weather/v1/weather.proto:7:3:Enum value name "RAINY" should be prefixed with "CONDITION_".
proto/acme/weather/v1/weather.proto:21:19:RPC request type "Location" should be named "GetWeatherRequest" or "WeatherServiceGetWeatherRequest".

3. Fix lint errors

Now that you know what needs to be fixed, you can go through your .proto files and fix them. Let's start with the package name—it should match the directory structure under which the schema lives (relative to the module root), so change the package declaration:

~/.../buf-tour/start/tutorial-lint/proto/acme/weather/v1/weather.proto
syntax = "proto3";

- package weather;
+ package acme.weather.v1;

If you run buf lint again, the first two errors about the package no longer appear. You can work through the rest of the errors in a similar way—the messages provide specific suggestions to help you fix them.

Note

The changes the linter recommends are breaking changes for this package, which illustrates why it's best (if possible) to start linting when you first create your Protobuf files.

However, it's not always possible, so we also provide a way to temporarily ignore rules when you first bring your .proto files into Buf—see step 5 below.

4. Customize lint configuration

We generally recommend that you use the STANDARD category for linting—it represents what we consider to be best practice for Protobuf development. However, if your organization's style has other requirements, you can choose a different category or add and remove individual rules from your configuration.

For example, if your org generally agrees with STANDARD rules but doesn't want to check for a suffix on service names, you can selectively ignore that rule in the configuration like this:

buf.yaml
version: v2
lint:
  use:
    - STANDARD
  except:
    - SERVICE_SUFFIX

You can also add individual rules to the more minimal categories if they better match your style. For example, to add only the SERVICE_SUFFIX rule to the BASIC category, you can use this configuration:

buf.yaml
version: v2
lint:
  use:
    - BASIC
    - SERVICE_SUFFIX

5. Temporarily ignore lint errors

There may be times when you want to ignore errors temporarily, such as adding buf lint to an existing project (where fixing lint errors would introduce breaking changes). We've provided a flag to make it simple to ignore them in this case. Once you've fixed everything you want to fix, run this command to get a set of lint settings that you can copy and paste into your buf.yaml file to ignore the remaining errors:

~/.../buf-tour/start/tutorial-lint
$ buf lint --error-format=config-ignore-yaml

version: v2
lint:
  ignore_only:
    ENUM_VALUE_PREFIX:
      - acme/weather/v1/weather.proto
    ENUM_ZERO_VALUE_SUFFIX:
      - acme/weather/v1/weather.proto
    RPC_REQUEST_STANDARD_NAME:
      - acme/weather/v1/weather.proto