FAQ

Frequently Asked Questions

What linters should I be using?

The best set of linters depends on your particular needs and which tech stack you are using (C/C++, Javascript, Rust, Python, etc). By default Trunk Check will detect your project type and select a recommended set of linters for that type, ESLint for a Javascript project or clang-tidy for C++ projects. There are plenty more linters you can use, however. You can see all possible (built in) linters with

trunk check list

and enable a new linter with

trunk check enable cool_new_linter

See more about our supported linters here.

Why aren't issues showing up anymore?

If you aren’t seeing any issues the likely cause is that your local repo is clean. By default Trunk Check only processes new changes to your codebase (read about hold-the-line). To scan older changes try running:

trunk check --samples=5 

to look at a sampling of each linter's issues for 5 random files

trunk check --all

to scan all files, whether they've changed or not. More on CLI options.

There are too many issues showing up

One reason for seeing too many issues is that you may have multiple linters configured which are all printing output. Try running just one linter at a time with the --filter=some_linter option.

Another reason may be that linters are running on files they should skip, such as generated code from other tools. These docs explain how to configure linters to ignore certain files.

Linters are usually configured to be very aggressive and flag many potential bugs and security risks. Sometimes you may want to tell a linter “Trust me, I know what I’m doing”. If that is the case you can configure a linter to ignore certain issues.

A final possible reason for excess issues is that one of your linters is misconfigured. For example, when using ESlint on a TypeScript project it will flag code that is perfectly fine for TypeScript, but incorrect for JavaScript. In this case make sure that your .eslintrc file is correctly set up to handle TypeScript. Also make sure the extends section lists the typescript defaults after the eslint:recommended ones, since ESLint uses last one wins priority.

More on the CLI options.

My linters are failing or not running as expected

When your linters aren’t working the way you expect, first check their configuration. Trunk’s list of supported linters provides some specific tips for certain linters. You can see the full default configuration of every linter in Trunk’s public plugin repo.

You can also try running trunk check --verbose to see what’s going on under the hood. If that still doesn’t work then please reach out to us on our community Slack with the output of trunk check --verbose.

What is the difference between a Linter and a Formatter?

A linter is a tool that looks for potential code errors such as security vulnerabilities, code spell, anti-patterns, and other things that might be a problem at runtime. Linters generally report warnings and errors but do not modify code. A formatter is a tool that reformats code to fit a particular style (indentation, sorting imports, semicolons, etc). Formatters always modify code. In general, even though your setup may use many different linters we recommend using only one formatter per filetype.

Some tools like ESLint can serve as both a linter and formatter for Javascript code. If Prettier is also enabled then code could be reformatted twice, creating conflicts. In this case we recommend using ESLint just for linting and use Prettier for code formatting. Further advice for ESLint with prettier.

Ruff and Black are another example of a linter/formatter pair that can collide with each other if not configured properly. If you enable Ruff but don’t already have a ruff config, Trunk Check will generate a ruff.toml file for you automatically. This ruff.toml is formatter friendly, meaning that it will silence formatting related warnings and allow Black to take care of them more quickly and easily. This is another example of tuning your linters with linter configs.

What is Hold-the-line (HTL)?

Hold The Line (HTL) is the principle that Trunk Check will only run on new changes in your codebase, rather than every file in the whole repo. This allows you to use Check to improve your codebase incrementally rather than having to address all of the issues at once. HTL also runs checks much faster than scanning the entire codebase would.

HTL works even within files! Check only processes changed lines in a file, not the entire file. More on how Hold the Line works.

If you specifically want to work on older files you can do that by running trunk check directly on that file

trunk check foo.file

or

trunk check --all

to run on all files. More on CLI options.

What does it mean when Trunk Check wants to format an image in my repo?

Sometimes Trunk Check says there is some Incorrect formatting in your images. Check usually enables a program called Oxipng which can optimize images to make them smaller (without losing any data). The error message just means that Oxipng wants to optimize those images. You can do that with trunk fmt or trunk fmt filename.png. You can also disable Oxipng with trunk check disable oxipng.

Why does Trunk take up so much disk space?

Trunk Check uses hermetically versioned tools, which means it downloads a separate copy of the tools and runtime for each tool version. Over time, as tools are upgraded, this can leave a lot of unnecessary files in the cache directory. Trunk is working on a way to automatically remove unneeded files from the cache. In the meantime you can safely clear your cache with

trunk cache clean --all

then run trunk install again in your repos.

How can I expand the number of tools I use with Trunk?

Trunk supports over 100 different linters, checkers, and other tools; and we are always adding more! Some tools are easier to configure than others, and we enable many of them out-of-the-box. You can read more about specific linter setup here. Trunk is intended to be the one-stop-shop for running all of your linters.

To see a list of currently available linters run

trunk check list

Upgrading Trunk

Trunk automatically keeps your tools up to date. To check for recent updates you can run trunk upgrade to get the latest tools and fixes. You can read more about how this works here.

When upgrading from Trunk CLI versions 1.14.2 or older, you will have to rerun trunk upgradein order to get all available fixes.

Runtime & Download Versioning

Some of the tools that Trunk installs use direct downloads and others use runtime installs. For example, most Javascript tools run using the NodeJS runtime. Runtimes themselves are provided through Trunk as versioned direct downloads.

You can use a different version of a runtime by changing its version in the enabled section of your .trunk/trunk.yaml file in the runtimes section.

runtimes:
  enabled:
    - node@18.12.1
    - python@3.10.8

If you want to pin the version of a runtime that a particular tool uses, you can do that with an ! after the version number in your trunk.yaml.

lint:
  enabled:
    - pylint@2.17.5!

More on pinning versions

However, some versions are not supported in Trunk check by default. If you need to specify an unsupported version, for example to use a particular python version that has been deprecated, you would need to override the downloads section as necessary. Check out the definition for python downloads here. In general we advise against using unsupported runtimes.

More on how runtimes work

How do I Make a Linter Work with a Different Filetype?

Every linter defines a set of file types that it wants to work with in a section of the YAML called files. To change this you need to override the files section of that linter’s definition. More linter application file types.

Suppose you are using the foo-linter which normally runs on foo files. The config might look like this:

lint:
  files:
    - name: foo
      extensions: [foo]
  definitions:
    - name: foo-linter
      files: [foo]
      commands:
        - name: lint
          output: pass_fail
          run: echo “foo”
          success_codes: [0, 1]

To add support for bar files add this to your trunk.yaml file. The first part defines the bar file type, and the second says that foo-linter uses both foo and bar files.

lint:
  files:
    - name: bar
      extensions: [bar]
...
      
  definitions:
    - name: foo-linter
        files:
          - foo
          - bar

How can I disable trunk on commit for just me, but keep it on for the rest of my team?

If you prefer to never run Trunk on commit and push you can disable it just for you. Edit or create the .trunk/user.yaml file and change the actions.disabled section to look like this:

version: 0.1
actions:
  disabled:
    - trunk-check-pre-push
    - trunk-fmt-pre-commit
  

This will disable the checks for just the current user. The .trunk/user.yaml file is specifically gitignored but will be loaded locally if present.

What should I do if a linter process seems to take longer than expected during a Trunk check?

There are two main strategies to address this issue: configuring timeouts and ignoring certain files.

Timeout Configuration

Each linter integrated with Trunk Check has a default timeout of 10 minutes to prevent processes from running indefinitely. If a linter exceeds this timeframe, Trunk Check will automatically terminate the process and notify you of the timeout.

To adjust the timeout duration for a specific linter, you can modify its run_timeout setting in your configuration. For example:

lint:
    definitions:
    - name: clang-tidy
      run_timeout: 5m

Timeouts can be specified using s for seconds, m for minutes, or h for hours, allowing you to tailor the behavior to your project's needs. More on linter timeouts.

Ignoring Files

Certain files, particularly those that are auto-generated, may not require linting and can significantly extend the duration of checks. To exclude these from being checked, use the ignore key in your configuration:

lint:
  ignore:
    - linters: [ALL]
      paths:
        # Ignore generated files
        - src/generated/**
        # Except for files ending in .foo
        - !src/generated/**/*.foo # Test data
        - test/test_data

This approach lets you specify which linters to ignore for particular paths, optimizing the check process and focusing on relevant files. More details on ignoring files.

trunk init says "Trunk can only init if it's run at the root of a git repo"

Trunk requires that you run trunk init from the root of a git repository. Trunk is git-aware, and relies on git to understand which files are modified, gitignored, and more.

If you see this message, it means that you are not in the root directory of a git repository. If you are in a git worktree, Trunk does support worktrees. Your worktree may be in a broken state, try running git worktree repair and then trunk init again.

Last updated