Build and .toml Details

Most deep analysis tools build the project as part of operating. Lift can detect the build system and a build target to identify the code and decide which analyzer should be applied. Alternatively, direct configuration of Lift is possible by writing and committing a .lift.toml file or to your repository. .lift/config.toml is also recognized as a valid configuration file. Explicit configuration is not usually required unless custom compilation steps must be taken, such as using non-standard build targets or installing external library dependencies. This page describes the supported build systems and configuration options available to influence build, analysis and general Lift operation on a per-repository basis.

In-Repo Options (the  .lift.toml)

By default Lift will attempt to run all its analysts on a repository and generate reports from all analyses that succeed. The configuration file can be used to enable or disable analysis passes, specify the build system and filter types of bugs reported. The file .lift.toml controls Lift's behavior using the fields:

setup                   = <path to setup script>
build                   = ENV=<env> <build option> [target]
importantRules          = <exclusive list of issues to report back to user>
ignoreRules             = <list of issues never to report to the user>
ignoreFiles             = <gitignore format string of files to ignore>
tools                   = <limits the tools run against this project to this list>
disableTools            = <list of tools to not run on the project>
customTools             = <list of user-provided tools conforming to a tool API>
allow                   = <list of users whose pull requests can trigger analysis>
jdkVersion              = <jdk version>
summaryComments         = <true or false (defaults to false)>
  • setup: A script that can perform pre-build configuration, such as installing tools (e.g. apt install dependency) or libraries. The path should be either absolute or relative to the root of the repository.

  • build: The name of a build tool (overrides auto detection). Valid build tools include "make", "gradlew", "maven", "autogen", "configure", "cmake", "compdb" and "gradle".

    • "autogen" implies ./ ; ./configure ; make a la typical autotools workflow
    • "configure" similarly starts one step later
    • "gradlew" without an explicit target will try the  assemble  target
    • "compdb" requires a compile_commands.json file is present in the repository and its paths are all relative to the project's root
    • You may set environment variables from the build line: build = "CC=gcc GXX=g++ CXX=g++ make"
  • importantRules: An allow list of issues considered important enough to report. If defined, only bugs of types that are in this list will ever be reported to the user. The values here match the bold faced header, aka issue "type", seen on the reports. Rules here will have precedence over ignoreRules; the rule will be reported even if it's ignored by default.

  • ignoreRules: The opposite of important, a deny list of issues that should never be reported. Any issue in the ignore list is never reported to the user, even if it is marked important. For example, you can ignore ESLint's no-empty message by specifying ignoreRules = [ "no-empty" ]. Unless otherwise defined, the default for each tool is:

    • Bandit: [ "B101", "B301", "B302", "B308", "B310", "B311", "B403", "B404", "B605", "B608" ]

    • ErrorProne: [ "missingoverride",  "StringSplitter", "UnusedVariable", "SameNameButDifferent", "EqualsGetClass", "CanIgnoreReturnValueSuggester", "InlineMeSuggester", "UnnecessaryParenthesis" ]

    • ESLint: [ "none" ]

    • Pyre: [ "unbound name",  "call error", "incompatible attribute type", "unsupported operand", "inconsistent override" ]

    • Semgrep: [ "opt.semgrep.regex_dos" ]

  • ignoreFiles: A gitignore formatted specification of files from which results should be ignored. You may wish to use Toml's multiline string to specify multiple files or directories to be ignored. As an alternative, you may place a gitignore formatted file in the path  .lift/ignoreFiles  relative to the root of your repository. Unless otherwise defined, the defaults are **/test/** and **/*.min.js. For Lift's Software Composition Analysis (SCA) tool, the default ignore files are **/test/** and **/target/**. If you want SCA to scan these files, simply pass ignoreFiles="" to make SCA scan your entire repository.

  • tools: List of analysis tools to apply to the repository. Without this field, all tools included with Lift will be applied.

  • disableTools: A deny list of analyis tools to not be applied to the repository. For example, specifying disableTools = [ "errorprone" ] will run all the default tools except for errorprone.

  • customTools: List of custom tools to run. This can run any manner of tool. For a basic example that can serve as a starting point for your own tool see the Custom Tools Section.

  • allow: List of user names whose pull requests will cause analysis and result in comments being posted. The default behavior is to run Lift on all pull requests regardless of author.

  • jdkVersion: A text field indicating the version of java. Options are "8", "11" or "17". This defaults to 17.

  • summaryComments: A boolean field indicating whether or not to post a comment with a summary. When true, Lift will post a comment that looks similar to "Complete (6 min, 6/7 checks) no new bugs found".

An actual configuration might look like:

setup     = ".lift/"
build     = "gradlew assemble"

# We only care about NULL_DEREFERENCE (from Infer)
# and no-extra-boolean-cast (from ESLint)
importantRules = ["NULL_DEREFERENCE", "no-extra-boolean-cast"]

# Ignore results from test and build directories
ignoreFiles = """

# Only run infer and eslint (do not run errorprone, hlint, findsecbugs)
tools = [ "infer", "eslint" ]

# Only analyze and post responses to PRs from developers with these usernames
allow = [ "jill", "dave", "shawn" ]

The file and all fields are optional. By default, Lift will attempt to infer appropriate values for any setting that isn't specified in the file.

Build System Support

Lift analyses look for build system files on the repository root and through all the subdirectories. A build system is necessary for Lift to learn which files are appropriate to analyze, which dependencies (libraries and class paths) to leverage, and which compilation flags are appropriate. The supported build systems include:

  • gradlew:
    • Description: Lift will use the gradle wrapper
    • Condition: When a  gradlew  file is found
    • Command line equivalent: ./gradlew assemble
  • gradle:
    • Description: Lift will use the Gradle build system
    • Condition: When a  build.gradle  file is found.
    • Command line equivalent: gradle assemble
  • CompDB:
    • Description: Lift will read compile commands from a JSON file
    • Condition: When a compile_commands.json  file exists
    • Command line equivalent: Sequentially invoking the commands with arguments and files specified in the JSON file
  • mvnw:
    • Description: Lift will use the maven wrapper
    • Condition: When a mvnw file is found
    • Command line equivalent: ./mvnw compile -B
  • Maven:
    • Description: Lift will use Maven
    • Condition: When a  pom.xml  file is found
    • Command line equivalent:  mvn compile -B
  • Make:
    • Description: Lift will use  make
    • Condition: When a {M,m}akefile  file is found
  • Autotools:
    • Description: Lift will invoke the common GNU AutoTools of and configure to try and produce a Makefile
    • Condition: Used when  or configure  files are found
    • Command line equivalent: ./ || ./configure && make
  • Compilation database:
    • Description: Lift will use the individual compilation commands and arguments specified by a compilation database
    • Condition: Used when compile_commands.json  is found


Lift supports nested subprojects and projects not at the root level. This lets you easily build Lift into your monolithic repos and lets you specify entirely different build systems for different parts of your code. To set this up, each subproject needs its own Lift configuration file in the root directory of that subproject. This configuration file should use the same format as before, and in it you can configure specific tools and build systems to use for your subproject.

The top-level .lift.toml file can still optionally exist and can be used to build a top-level project. Additionally, this top-level configuration file is the only place you should put an allow list. Because the allowlist is global the allow field is only read from the top-level configuration file.

The directory structure might look something like this:




Lift will then automatically run on both Project A and Project B.

APIs for Custom Tools

Lift supports arbitrary tools for users to extend and customize the types of comments made on pull requests. The customizations can either be a file path or HTTPS URL to a script followed by arguments. Here are some example configurations and links to the supported APIs so you can add your own checks.

Example Extended Checks - Fixing the FIXME

Let's say you have a repository that you wish to keep clean of crufty code comments such as TODO,  XXX, and  FIXME. Add to the .lift.toml  file:

customTools =  [""]

There is no magic in the URL - you can download that script, change it, re-host it on your own domain, and have Lift run checks of your own design. The check-common-comments  script will grep through your source code and report any instance of the offending strings.

In many cases the script might be project-specific and can be hosted in the repository. In this case you might place the file .lift/  in your repository and have a tools line of:

customTools = [ ".lift/" ]

Example Extended Checks - ShellCheck and PMD

Let's look at two more examples. The first is a Java analysis tool PMD and the second is a shell script checker ShellCheck.

The PMD script is parameterized by the rule set so we'll pass in an argument. Our ShellCheck support script hard codes some simple assumptions and does not consider arguments. We further disable the built-in tools, yielding a .lift.toml  file of:

tools = [ ]
customTools = [ " rulesets/java/quickstart.xml"
              , ""

The hosted example scripts use binaries of pmd and shellcheck that are already on the image - the scripts just run the tool then translate the resulting JSON. If your preferred tool isn't installed consider specifying a installation script in the setup  configuration field to adjust the environment first.

Extended Tooling with Custom or Community-provided Tools

The above configuration shows how to invoke an existing tool. These tools all must conform to one of Lift's APIs. Please refer to our tool API for information necessary to build a tool. Details of some of the above and further examples can be found in the Custom Tooling Examples page.