Run lint checks

More information

To run all configured lint checks:

$ buf check lint

This command should have exit code 0 and no output.

Behind the scenes, this command:

  • Discovers all Protobuf files per your configuration.
  • Copies all Protobuf file content into memory.
  • Compiles all Protobuf files.
  • Runs the compilation result against the configured lint checkers.

Let's examine the lint section of the buf.yaml file we have set up:

version: v1beta1
lint:
# This is not the lint configuration we recommend!
# This just just what googleapis passes.
# We recommend having the single value "DEFAULT" in "use" with no values in "except".
# See https://docs.buf.build/lint-usage
use:
- BASIC
- FILE_LOWER_SNAKE_CASE
except:
- ENUM_NO_ALLOW_ALIAS
- IMPORT_NO_PUBLIC
- PACKAGE_DIRECTORY_MATCH
- PACKAGE_SAME_DIRECTORY
- PACKAGE_AFFINITY
breaking:
use:
- WIRE_JSON

This instructs Buf to use the BASIC lint category, as well as the FILE_LOWER_SNAKE_CASE lint checker, but not use the checkers ENUM_NO_ALLOW_ALIAS, IMPORT_NO_PUBLIC, PACKAGE_DIRECTORY_MATCH, or PACKAGE_SAME_DIRECTORY (all of which are in the BASIC lint category), and not use any checkers in the lint category PACKAGE_AFFINITY (all of which are also in the BASIC lint category). We will examine the available lint checkers later.

Let's comment out two of the exceptions:

version: v1beta1
lint:
use:
- BASIC
- FILE_LOWER_SNAKE_CASE
except:
#- ENUM_NO_ALLOW_ALIAS
#- IMPORT_NO_PUBLIC
- PACKAGE_DIRECTORY_MATCH
- PACKAGE_SAME_DIRECTORY
- PACKAGE_AFFINITY
breaking:
use:
- WIRE_JSON

Then re-run linting:

$ buf check lint
google/appengine/v1/app_yaml.proto:53:5:Enum option "allow_alias" on enum "ErrorCode" must be false.
google/appengine/v1/app_yaml.proto:264:3:Enum option "allow_alias" on enum "SecurityLevel" must be false.
google/cloud/policytroubleshooter/v1/checker.proto:20:1:Import "google/cloud/policytroubleshooter/v1/explanations.proto" must not be public.
google/cloud/recommendationengine/v1beta1/catalog.proto:132:5:Enum option "allow_alias" on enum "StockState" must be false.
google/cloud/securitycenter/v1/securitycenter_service.proto:19:1:Import "google/cloud/securitycenter/v1/run_asset_discovery_response.proto" must not be public.
google/cloud/securitycenter/v1p1beta1/securitycenter_service.proto:20:1:Import "google/cloud/securitycenter/v1p1beta1/run_asset_discovery_response.proto" must not be public.
google/cloud/websecurityscanner/v1beta/scan_config_error.proto:35:5:Enum option "allow_alias" on enum "Code" must be false.
google/storage/v1/storage.proto:1902:5:Enum option "allow_alias" on enum "Values" must be false.

We can also output this as JSON:

$ buf check lint --error-format=json
{"path":"google/appengine/v1/app_yaml.proto","start_line":53,"start_column":5,"end_line":53,"end_column":31,"type":"ENUM_NO_ALLOW_ALIAS","message":"Enum option \"allow_alias\" on enum \"ErrorCode\" must be false."}
{"path":"google/appengine/v1/app_yaml.proto","start_line":264,"start_column":3,"end_line":264,"end_column":29,"type":"ENUM_NO_ALLOW_ALIAS","message":"Enum option \"allow_alias\" on enum \"SecurityLevel\" must be false."}
{"path":"google/cloud/policytroubleshooter/v1/checker.proto","start_line":20,"start_column":1,"end_line":20,"end_column":73,"type":"IMPORT_NO_PUBLIC","message":"Import \"google/cloud/policytroubleshooter/v1/explanations.proto\" must not be public."}
{"path":"google/cloud/recommendationengine/v1beta1/catalog.proto","start_line":132,"start_column":5,"end_line":132,"end_column":31,"type":"ENUM_NO_ALLOW_ALIAS","message":"Enum option \"allow_alias\" on enum \"StockState\" must be false."}
{"path":"google/cloud/securitycenter/v1/securitycenter_service.proto","start_line":19,"start_column":1,"end_line":19,"end_column":83,"type":"IMPORT_NO_PUBLIC","message":"Import \"google/cloud/securitycenter/v1/run_asset_discovery_response.proto\" must not be public."}
{"path":"google/cloud/securitycenter/v1p1beta1/securitycenter_service.proto","start_line":20,"start_column":1,"end_line":20,"end_column":90,"type":"IMPORT_NO_PUBLIC","message":"Import \"google/cloud/securitycenter/v1p1beta1/run_asset_discovery_response.proto\" must not be public."}
{"path":"google/cloud/websecurityscanner/v1beta/scan_config_error.proto","start_line":35,"start_column":5,"end_line":35,"end_column":31,"type":"ENUM_NO_ALLOW_ALIAS","message":"Enum option \"allow_alias\" on enum \"Code\" must be false."}
{"path":"google/storage/v1/storage.proto","start_line":1902,"start_column":5,"end_line":1902,"end_column":31,"type":"ENUM_NO_ALLOW_ALIAS","message":"Enum option \"allow_alias\" on enum \"Values\" must be false."}

If you'd like to skip ahead in the documentation, you can also lint directly from GitHub:

$ buf check lint "https://github.com/googleapis/googleapis/archive/${GOOGLEAPIS_COMMIT}.tar.gz#strip_components=1" --config buf.yaml
google/appengine/v1/app_yaml.proto:53:5:Enum option "allow_alias" on enum "ErrorCode" must be false.
google/appengine/v1/app_yaml.proto:264:3:Enum option "allow_alias" on enum "SecurityLevel" must be false.
google/cloud/policytroubleshooter/v1/checker.proto:20:1:Import "google/cloud/policytroubleshooter/v1/explanations.proto" must not be public.
google/cloud/recommendationengine/v1beta1/catalog.proto:132:5:Enum option "allow_alias" on enum "StockState" must be false.
google/cloud/securitycenter/v1/securitycenter_service.proto:19:1:Import "google/cloud/securitycenter/v1/run_asset_discovery_response.proto" must not be public.
google/cloud/securitycenter/v1p1beta1/securitycenter_service.proto:20:1:Import "google/cloud/securitycenter/v1p1beta1/run_asset_discovery_response.proto" must not be public.
google/cloud/websecurityscanner/v1beta/scan_config_error.proto:35:5:Enum option "allow_alias" on enum "Code" must be false.
google/storage/v1/storage.proto:1902:5:Enum option "allow_alias" on enum "Values" must be false.

We can also output errors in a format you can then copy into your buf.yaml file. This allows you to ignore all existing lint errors and correct them over time:

$ buf check lint --error-format=config-ignore-yaml
lint:
ignore_only:
ENUM_NO_ALLOW_ALIAS:
- google/appengine/v1/app_yaml.proto
- google/cloud/recommendationengine/v1beta1/catalog.proto
- google/cloud/websecurityscanner/v1beta/scan_config_error.proto
- google/storage/v1/storage.proto
IMPORT_NO_PUBLIC:
- google/cloud/policytroubleshooter/v1/checker.proto
- google/cloud/securitycenter/v1/securitycenter_service.proto
- google/cloud/securitycenter/v1p1beta1/securitycenter_service.proto

If we then copy this into our buf.yaml:

version: v1beta1
lint:
use:
- BASIC
- FILE_LOWER_SNAKE_CASE
except:
#- ENUM_NO_ALLOW_ALIAS
#- IMPORT_NO_PUBLIC
- PACKAGE_AFFINITY
- PACKAGE_DIRECTORY_MATCH
- PACKAGE_SAME_DIRECTORY
ignore_only:
ENUM_NO_ALLOW_ALIAS:
- google/appengine/v1/app_yaml.proto
- google/cloud/recommendationengine/v1beta1/catalog.proto
- google/cloud/websecurityscanner/v1beta/scan_config_error.proto
- google/storage/v1/storage.proto
IMPORT_NO_PUBLIC:
- google/cloud/policytroubleshooter/v1/checker.proto
- google/cloud/securitycenter/v1/securitycenter_service.proto
- google/cloud/securitycenter/v1p1beta1/securitycenter_service.proto
breaking:
use:
- WIRE_JSON

We can re-run linting and there will be no output:

$ buf check lint

Once done, change the config file back to it's original state before continuing the tour:

version: v1beta1
lint:
use:
- BASIC
- FILE_LOWER_SNAKE_CASE
except:
- ENUM_NO_ALLOW_ALIAS
- IMPORT_NO_PUBLIC
- PACKAGE_DIRECTORY_MATCH
- PACKAGE_SAME_DIRECTORY
- PACKAGE_AFFINITY
breaking:
use:
- WIRE_JSON