ThriftCheck is a linter for Thrift IDL
files. It provides a general Thrift linting framework, a set of checks, and a
command line tool (thriftcheck
).
You can download the latest prebuilt release or build the project
yourself using the Go compiler toolchain (e.g. go install
).
thriftcheck
is a configuration-driven tool for linting Thrift IDL files from
the command line:
usage: thriftcheck [options] [path ...]
-I, --include value
include path (can be specified multiple times)
-c, --config string
configuration file path (default ".thriftcheck.toml")
--errors-only
only report errors (not warnings)
-h, --help
show command help
-l, --list
list all available checks with their status and exit
--stdin-filename string
filename used when piping from stdin (default "stdin")
-v, --verbose
enable verbose (debugging) output
--version
print the version and exit
You can pass a list of filenames or directory paths. Directories will be
expanded recursively to include all nested .thrift
files.
You also can lint from standard input by passing -
as the sole filename.
Use --stdin-name
to customize the filename used in output messages.
$ thriftlint --stdin-name filename.thrift - < filename.thrift
Messages are reported to standard output using a familiar parseable format:
file.thrift:1:1: error: "py" namespace must match "^idl\\." (namespace.pattern)
file.thrift:3:1: error: unable to find include path for "bar.thrift" (include.path)
If you only want errors (and not warnings) to be reported, you can use the
--errors-only
command line option.
thriftcheck
's exit code indicates whether it reported any warnings (1)
or errors (2). Otherwise, exit code 0 is returned.
Many checks are configurable via the configuration file. This file is named
.thriftcheck.toml
and is loaded from the current directory by default, but
you can use the --config
command line option to use a different file. If you
prefer, you can use a JSON- or YAML-formatted file instead by using a .json
or .yaml
file extension, respectively. The examples shown below use the
default TOML syntax.
example.toml
is an example configuration file that you
can use as a starting point.
The full list of available checks can printed using the --list
command line
option. By default, all checks are enabled.
You can enable or disable checks using the configuration file's top-level
enabled
and disabled
lists. The list of disabled
checks is subtracted
from the full list first, and then the resulting list is filtered by the list
of enabled
checks. Either list can be empty (the default).
This check reports an error if a referenced constant or enum value cannot be found in either the current scope or in an included file (using dot notation).
This check warns or errors if an enumeration's element size grows beyond a limit.
[enum.size]
warning = 500
error = 1000
This check warns if a field is missing a documentation comment.
This check reports an error if a field's ID is missing (using the legacy implicit/auto-assigning syntax).
This check reports an error if a field's ID is explicitly negative.
This check reports an error if a field's ID is explicitly zero, which is
generally unsupported by the Apache Thrift compiler. This is distinct from
the field.id.negative
check given the existence of the --allow-neg-keys
Apache Thrift compiler option.
This check warns if a field isn't declared as "optional", which is considered a best practice.
This check warns if a field isn't explicitly declared as "required" or "optional".
This check ensures that each include
'd file can be located in the set of
given include paths.
Relative paths are resolved relative to the current working directory. The
list of includes
specified in the configuration file is used by default,
but if any paths are specified on the command line using the -I
option,
they will be used instead.
includes = [
'shared',
]
This check restricts some files from being imported by other files using a
map of patterns: the key is a file name pattern that matches the including
filename and the value is a regular expression that matches the included
filename. When both match, the include
is flagged as "restricted" and an
error is reported.
[checks.include]
[[checks.include.restricted]]
"*" = "(huge|massive).thrift"
This check warns when an integer constant exceeds the 32-bit number range. Some languages (e.g. JavaScript) don't support 64-bit integers.
This check ensures that only primitive types are used for map<>
keys.
This checks allows you to extend the default list of reserved keywords with additional disallowed names.
[checks.names]
reserved = [
"template",
]
This check ensures that a namespace's name matches a regular expression pattern. The pattern can be configured one a per-language basis.
[[namespace.patterns]]
py = "^idl\\."
This check ensures that only primitive types are used for set<>
values.
You can also implement your own checks using the thriftcheck
package's public
interfaces. Checks are functions which receive a *thriftheck.C
followed by a
variable number of ast.Node
-compliant argument types.
check := thriftcheck.NewCheck("enum.name", func(c *thriftcheck.C, e *ast.Enum, ei *ast.EnumItem) {
for _, r := range ei.Name {
if !unicode.IsUpper(r) && unicode.IsLetter(r) {
c.Errorf(f, "item name %q (in %q) can only contain uppercase letters", ei.Name, e.Name)
return
}
}
})
You can pass any list of checks to thriftcheck.NewLinter
. You will probably
want to build a custom version of the thriftcheck
tool that is aware of your
additional checks.
You can disable one or more checks on a per-node basis using nolint
directives. nolint
directives apply to the current node and all of its
descendents. The directives's value can be empty, in which case linting is
entirely disabled, or it can be set to a comma-separated list of checks to
disable.
nolint
directives can be written as Thrift annotations:
enum State {
STOPPED = 1
RUNNING = 2
PASSED = 3
FAILED = 4
} (nolint = "enum.size")
... and as @nolint
lines in documentation blocks:
/**
* States
*
* @nolint(enum.size)
*/
enum State {
STOPPED = 1
RUNNING = 2
PASSED = 3
FAILED = 4
}
The annotation syntax is preferred, but the documentation block syntax is
useful for those few cases where the target node doesn't support Thrift
annotations (such as const
declarations).
- Vim, using ALE
pre-commit support is provided. Simply add the
following to your .pre-commit-config.yaml
configuration file:
- repo: https://github.com/pinterest/thriftcheck
rev: 1.0.0 # git revision or tag
hooks:
- id: thriftcheck
name: thriftcheck
For information on development and making code contributions, see
CONTRIBUTING.md
.
This software is released under the terms of the Apache 2.0 License.