lint

Runs the policy checks of the tree, each file read once, with a self-test before each check

lint

lint runs the policy checks of the tree: the rules that the code, the build files and the documents must follow, each with the spec section that owns it. It replaces the scripts of integration/lint/, one check at a time.

Usage

lint                               run every check
lint --check <id>[,<id>...]        run the named checks
lint --list [--markdown]           list the checks
lint --self-test                   run the self-test of every check, and nothing else
lint --check <id> --update         rewrite the baseline of a check that has one
lint --check <id> --write          write what a check writes: the evidence blocks of
                                   parity-citations, the leading whitespace of glsl-style
lint --root <folder>               check another checkout
lint --jobs <n>                    cap the worker threads (default: the processor count)
lint --timings                     print the time of each check
lint --strict                      fail on a check that is not judged
lint --with-tests [--kiln <program>] [--compile-db <file>]  after the checks, run the guard suites and the kiln check modes

Build and run it from the repository root:

qbs run -p lint -- --check cpp-policy

Without --root, lint checks the checkout that holds the working folder. It reads the files that git tracks, leaves out the trees that integration/lint/vendored-paths.txt lists, and reads each file once, on all processors, for every check that needs it.

What a run reports

Each check gets a block, then the run ends with a summary:

── cpp-policy
  note: 9410 non-vendored source file(s) scanned; ...
  ✓ clean

════════════════════════════════════════════
files read: 10708 of 10708 selected
passed: 1
   ✓ cpp-policy

A finding names its file and line. A note is good news, such as an allowlist entry that is no longer needed, and never fails the run.

Each check runs its self-test first. The self-test plants a violation and a clean case and checks that the matcher tells them apart. If the self-test fails, the check does not run and the run fails, because a matcher that stopped matching reports the same clean result as a clean tree.

A check that cannot judge, for example because an input file is missing, is listed as not judged. It does not count as passed. The run fails on it only with --strict.

The report goes to standard error. --list writes to standard output.

Exit codes

Code Meaning
0 Every check that ran passed
1 A finding, a failed self-test, an empty run, or, with --strict, a check that is not judged
2 A wrong command line, such as a check name that does not exist
4 No checkout, no vendored-paths.txt, or, with --with-tests, no kiln program in the build

--with-tests

After the checks, lint --with-tests runs the guard suites with kiln test --prebuilt default --profile gate. It does not build: run qbs build first.

Then it runs the four check modes of kiln, which hold kiln's description of the build to what qbs builds: kiln commands --check, kiln sources --check, kiln keys --check and kiln import-qbs --check. The first two read the compile database that qbs wrote, release/compile_commands.json unless --compile-db names another. A mode that lacks its input is listed as not judged.

By default it runs the kiln program of this checkout's build. A machine that runs one kiln broker for every checkout refuses a kiln of another build, so there name the machine's kiln with --kiln <program>. If the program does not exist, lint exits 4 and says so.

The build step

cpp-policy also runs in the build, as a step of the lint product. A violation of the exception and RTTI policy fails qbs build. The other checks run in the guard suites, so a known violation that someone recorded does not stop a build.

Checks

The table is the output of lint --list --markdown. A test compares the two, so this page cannot drift from the program.

ID Title Owner Scope
banned-identifiers A removed name stays removed: no code names an identifier of banned-identifiers.txt §SCP-D-2.7 tree
build-matrix The build-matrix YAML parses, carries its Qt and Windows output schema, and has every leaf §CF-13 tree
ccache-config ccache shares its entries between sibling checkouts on this host §BPC-0 machine
clear-colors A clear that can reach the screen uses placeholderColor(), not a QColor literal §WFD-C4 tree
core-tier A coreTier library's headers include Qt Core and nothing else from Qt §BSS-T-1 tree
cpp-policy Our code uses no exceptions and no RTTI, and a product that enables either records why §EXP-E2 tree
debuginfo-follows-install Each Application wrapper binds installDebugInformation to install §WFR-RC-6.3 tree
disabled-tests A suite is not switched off (excluded category, condition: false, extraCondition: false, requiresCapabilities) without the owner's approval §TL-T-1 test tree
facility-ctor An activity that looks up a facility declares the context constructor, and casts the result checked §AC-3 tree
glsl-style GLSL indents with tabs, aligns with spaces and holds no tab inside a line, in all three populations §RRF-C3 tree
header-statics A first-party header declares no mutable static variable at namespace scope §TSR-S-6 tree
headless-contradiction A suite in a built category does not declare headless: false §TSR-S-1 test tree
hivecluster-mkpath libhive makes folders inside a hive with FsUtil::mkpath(), not QDir::mkpath() §FU-6 tree
nice-compliance Every process the build spawns takes its priority from lowpriority.js §BPT-5 tree
no-shell Every tracked script is listed in exempt-scripts.txt with the reason it stays a script §SCP-D-12 tree
opal-family-registration Every OPAL task family is declared or called, and the hand-wired set grows only through its baseline §OTR-6 tree
parity-citations Every matrix <ID> citation names one row of one registered matrix, and each generated evidence block is current §CIE-C5 tree
pragma-once A first-party header uses an include guard, not #pragma once, and no two headers share one §APD-M17 tree
qdoc-file-local No QDoc block documents a helper in an anonymous namespace, or main() §APD-M26 tree
product-boundary A product compiles only its own files: no files: or prefix: reaches into another product §KN-K9 tree
real-platform-tests A suite that skips for want of Vulkan declares requiresRealPlatform: true §TSR-S-3 test tree
rhi-first-policy Backend-specific graphics code stays in librhi, and libconstruct guards float targets and SSBOs §RFC-4 tree
root-strays The project root holds only its fixed set of tracked entries §BSS-M-2 tree
script-env An exempt script uses the environment only where §NEV-A10 allows it, and says so §NEV-A10 tree
section-numbers A §-number in a markdown heading addresses one section per file §BSS-M-2 tree
service-level-names A ServiceLevel member list names its services with ->name(), never with a string literal §NCL-C1 tree
settings-write-paths An apply, push or fallback path never persists a setting §CIE-C4 tree
shared-members A suite with shared: true obeys the member rules of SharedTestProbe.qbs §TSR-B-6 test tree
shell-stubs A test stubs a program with a program, not a shell script, and names no /tmp/ §WFD-C5 test tree
shortcut-callbacks Every id a shortcut callback binds is registered somewhere in the tree §CFGU-8 tree
shutdown-rules A QFutureWatcher that libstore makes is parented to qApp §SL-RS-8 tree
signal-id-discipline A handler for an id-carrying signal uses the id, or says why it does not §UC-T5 tree
stream-discipline Shipped code writes to stdout only where the allowlist records it as data §SD-V-3 tree
test-condition A Test binds extraCondition, never a condition that replaces the template's §KN-F25 test tree
test-main Every suite enters through OC_TEST_MAIN*, never a raw QTEST_*_MAIN §TSR-S-2 test tree
tick-discipline SceneWorkerWidget ticks the worker through the gate, or says why not §IQD-3 tree
unique-connection-lambda No connect that names Qt::UniqueConnection carries a lambda §CIE-T4 tree

A tree check reads the source tree. A test tree check reads test/ only and also runs in the testTestHygiene suite. A machine check reads the configuration of this computer, so it runs from the command line only.

In this section
Topics
reference tools lint policy build
See also