nestinglint

command
v1.20.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 26, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Command nestinglint enforces the project's shallow-nesting rule (CODING_STYLE.md: "Keep Indentation Shallow" / "avoids 'arrow code,' where indentation grows with each condition checked"). It flags any function whose control-structure nesting exceeds a threshold, so that "arrow code" is caught mechanically rather than only in review.

What counts as a level

A function body is depth 0. Entering the body of any block-introducing control structure adds one level:

  • if / else / else-if (the else-if chain stays at ONE level — see below)
  • for / range
  • switch / type switch (case bodies live one level below the switch)
  • select (comm-clause bodies one level below the select)
  • an explicit nested block { }

The reported depth is the deepest such level reached in the function.

else-if is flat

gofmt renders `if a { } else if b { } else { }` as a flat chain at a single indentation level, even though the AST nests each `else if` inside the previous `IfStmt.Else`. This linter mirrors gofmt: an else-if continuation is measured at the SAME level as the `if` it continues, not one deeper. A ten-arm else-if ladder is depth 1, not depth 10.

Function literals are independent scopes

Each closure (a `func(...) { ... }` literal) is measured as its own function, with its body starting fresh at depth 0. The depth walker only descends into statement bodies, never into expressions, so a literal's interior is never counted against its enclosing function; the top-level ast.Inspect visits the literal separately. This keeps the metric per-function and avoids charging a deeply-placed callback for the nesting of its call site.

Depth is a positional/structural property that the gocritic/ruleguard DSL cannot express, so this lives as a standalone go/ast pass, mirroring tools/cmd/singlelinefunclint and tools/cmd/typeswitchlint.

It exits non-zero when any violation is found, so it can gate `make lint`.

Usage:

go run ./tools/cmd/nestinglint [-max N] [dir...]

If no directories are given, it scans the current directory recursively. Test files (_test.go) are skipped, consistent with the other standalone linters and the ruleguard rules that exempt tests from production-only conventions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL