Commands
A command is the fundamental unit of linters. It defines specifically what binary and arguments are used to run the linter. A linter can have multiple commands in case it has multiple behaviors (ex: lint and format), but it must have at least one.
How Code Qualit Runs Linters
The run
property is the command to actually run a linter. This command can use variables provided by the runtime such as ${plugin}
and ${target}
.
For example: this is the run
field for black, one of our Python linters. The run
field is set to black -q ${target}
.
This command template contains all the information Trunk needs to execute black
in a way where Trunk will be able to understand blacks
's output.
Input Target
The target
field specifies what paths this linter will run on given an input file. It may be a string literal such as .
, which will run the linter on the whole repository. It also supports various substitutions:
${file}
The input file.
${parent}
The folder containing the file.
${parent_with(<name>)}
Walks up toward the repository root looking for the first folder containing <name>
. If <name>
is not found, do not run any linter.
${root_or_parent_with(<name>)}
Walks up toward the repository root looking for the first folder containing <name>
. If <name>
is not found, evaluate to the repository root.
If target
is not specified it will default to ${file}
.
This target may be referenced in the run
field as ${target}
, as in the example above for black, or this simple example.
or via stdin
, by specifying stdin: true
:
Note: Linters that take their input via
stdin
may still want to know the file's path so that they can, say, generate diagnostics with the file's path. In these cases you can still use${target}
inrun
.
Exit codes
Linters often use different exit codes to categorize the outcome. For instance, markdownlint
uses 0
to indicate that no issues were found, 1
to indicate that the tool ran successfully but issues were found, and 2
, 3
, and 4
for tool execution failures.
Trunk supports specifying either success_codes
or error_codes
for a linter:
if
success_codes
are specified, Trunk expects a successful linter invocation (which may or may not find issues) to return one of the specifiedsuccess_codes
;if
error_codes
are specified, Trunk expects a successful linter invocation to return any exit code which is not one of the specifiederror_codes
.
markdownlint
, for example, has success_codes: [0, 1]
in its configuration.
Note: A linter command should set either success codes or error codes, but not both**.**
Working directory
run_from
determines what directory a linter command is run from.
<path>
(.
by default)
Explicit path to run from
${parent}
Parent of the target file; e.g. would be foo/bar
for foo/bar/hello.txt
${root_or_parent_with(<file>)}
Nearest parent directory containing the specified file
${root_or_parent_with_dir(<dir>)}
Nearest parent directory containing the specified directory
${root_or_parent_with_regex(<regex>)}
Nearest parent directory containing a file or directory matching specified regex
${root_or_parent_with_direct_config}
Nearest parent directory containing a file from direct_configs
${root_or_parent_with_any_config}
Nearest parent directory containing a file from affects_cache
or direct_configs
${target_directory}
Run the linter from the same directory as the target file, and change the target to be .
${compile_command}
Run from the directory where compile_commands.json
is located
Template Variables
Note that some of the fields in this command template contain ${}
tokens: these tokens are why command
is a template and are replaced at execution time with the value of that variable within the context of the lint action being executed.
${workspace}
Path to the root of the repository
${target}
Path to the file to check, relative to ${workspace}
${linter}
Path to the directory the linter was downloaded to
${runtime}
Path to the directory the runtime (e.g. node
) was downloaded to
${upstream-ref}
Upstream git commit that is being used to calculate new/existing/fixed issues
${plugin}
Path to the root of the plugin's repository
Limiting concurrency
If you would like to limit the number of times trunk will invoke a linter concurrently, then you can use the maximum_concurrency
option. For example, setting maximum_concurrency: 1
will limit Trunk from running more than one instance of the linter simultaneously.
Environment variables
Trunk by default runs linters without environment variables from the parent shell; however, most linters need at least some such variables to be set, so Trunk allows specifying them using environment
; for example, the environment
for ktlint
looks like this:
Most environment
entries are maps with name
and value
keys; these become name=value
environment variables. For PATH
, we allow specifying list
, in which case we concatenate the entries with :
.
We use the same template syntax for environment
as we do for command
.
Output Types and Parsing
The output of a command should be in one of the supported output types like SARIF or something that can be parsed with a regex. See See Output Types for more details. If the standard output types do not meet your needs, you can also create a custom parser.
Full Reference
The linter command definitions are defined in lint.definitions.commands
. A single linter can have multiple commands if it is used in different ways.
Note:. If you define the executable to run here (the command definition), then you should not define it also in the linter definition. Defining it here as a command is preferred.
allow_empty_files
allow_empty_files
allow_empty_files
: optional boolean. Skip linting empty files for this linter. Trunk will assume there are no linters if the file is empty.
batch
batch
batch
: optional boolean. Combine multiple files into the same execution. If true, the ${target}
template substitution in the run
field may expand into multiple files.
cache_ttl
cache_ttl
cache_ttl
, duration string. If this linter is not idempotent, this is how long cached results are kept before they expire. Defaults to 24hrs. See Output Caching for more details.
cache_results
cache_results
cache_results
: optional boolean. Indicates if this linter wants to cache results. See Caching for more details.
disable_upstream
disable_upstream
disable_upstream
: optional boolean, Whether this linter supports comparing against the upstream version of this file.
error_codes
error_codes
error_codes
: List of exit codes this linter will return when it hit an internal failure and couldn't generate results. A linter should set either success codes or error codes, but not both. See also success_codes
.
enabled
enabled
enabled
: optional boolean. Whether the command is enabled to run when the linter is run. Allows some commands of a linter to be run by default without others.
files
files
files
is a list of file types listed in the lint.files
section that this linter applies to.
Example: prettier full source
fix_prompt
fix_prompt
fix_prompt
, optional string. e.g. 'Incorrect formatting' or 'Unoptimized image'. This string is used when prompting the user to use the linter interactively.
fix_verb
fix_verb
fix_verb
: optional string. This string is used when prompting the user to use the linter interactively. Example: optimize
, autoformat
, or compress
.
formatter
formatter
formatter
: optional boolean. Whether this command is a formatter and should be included in trunk fmt
.
in_place
in_place
in_place
: optional boolean. Indicates that this formatter will rewrite the file in place. Only applies to formatters.
idempotent
idempotent
idempotent
: optional boolean. Indicates whether a linter is idempotent with config and source code inputs. For example, semgrep
fetches rules from the Internet, so it is not idempotent . If set, will only cache results a duration of cache_ttl
. See Output Caching for more details.
is_security
is_security
is_security
: optional boolean. Whether findings from this command should be considered "security" or not. Allows this linter to be run with --scope==security
. See Command Line Options
maximum_file_size
maximum_file_size
maximum_file_size
: optional number. The maximum file size in bytes for input files to the linter. If not specified, the lint.default_max_file_size will be used.
max_concurrency
max_concurrency
max_concurrency
: optional integer, The maximum number of processes that Trunk Code Quality will run concurrently for this linter. See Limiting Concurrency
name
name
name
: string. A unique name for this command (some tools expose multiple commands, format, lint, analyze, etc.).
no_issues_codes
no_issues_codes
no_issues_codes
: List of exit codes that Trunk will use to assume there were no issues without parsing the output.
output
output
output
: string. which type of output this linter produces. See Output Types.
parser
parser
parser
: The definition of a parser that will transform the output of the linter into SARIF. Not needed if linter is already output SARIF. See Output Types
parse_regex
parse_regex
parse_regex
: string. A regular expression used to support regex parsing. See Regex output type
platforms
platforms
platforms
: A list of platforms this linter supports. (ex: windows
, macos
, linux
). Linters using managed runtimes (node, python, etc.) can generally run cross-platform and do not need the platforms
property set. For tools which are platform specific or which have different configuration for each platform, this property can be used to distinguish between them. When multiple command definitions have the same name, Trunk Check will pick the first one that matches the platforms
setting.
For example, the detekt
plugin has different exit codes for Windows than MacOS or Linux, and has two command definitions with different success_codes
fields. Full Source.
prepare_run
prepare_run
prepare_run
: An extra command to run before running a linter.
read_output_from
read_output_from
read_output_from
: Tell parser where to expect output from for reading. Should be one of stdout
, stderr
, and tmp_file
. See Output Sources
run
run
run
: The command to run a linter. This command can use variables provided at runtime such as $plugin}
and $target}
. Full list of variables. See Run for more details.
dart
format
command: full source
run_from
run_from
run_from
: What current working directory to run the linter from. See Working Directory for more details.
run_when
run_when
run_when
: When this command should be run. One of cli
, lsp
, monitor
, or ci
.
std_in
std_in
std_in
: optional boolean. Should the command be fed the file on standard input?
success_codes
success_codes
success_codes:
List of exit codes that indicates linter ran successfully. This is unrelated to whether or not there were issues reported by the linter.
Note: a linter should set either success codes or error codes, but not both. See also error_codes
.
target
target
target
, optional string, What target does this run on. By default, the target is the modified source code file, ${file}
. Some linters operate on a whole repo or directory. See Input Target for more details.
Examples:
nancy uses .
as the target. full source
tflint uses ${parent}
as the target. full source
Clippy uses ${parent_with(Cargo.toml)}
as the target. full source
version
version
version
: optional string, Version constraint. When a linter has multiple commands with the same name, Trunk Code Quality will select the first command that matches the version constraint. This is useful for when multiple incompatible versions of a tool need to be supported.
Example: the ruff
linter changed a command line argument from --format
to --output-format
in version v0.1.0
. To handle both versions, the linter defines two commands with different version attributes. The first is for version >=0.1.0
. If the first is not matched (because the install version of run is less that 0.1.0) then Trunk Code Quality will move on to the next command until it finds a match. Full source.
Last updated