Skip to content

Linting

Gubarz edited this page May 19, 2026 · 1 revision

Linting

cheatmd --lint validates your cheats without opening the picker. It checks DSL syntax, references, and structural integrity.

Usage

cheatmd --lint              # Lint current directory
cheatmd --lint ~/cheats     # Lint specific path
cheatmd --lint --strict     # Treat warnings as errors (non-zero exit)

Output format

Findings are printed in GCC style for easy integration with editors and CI:

file.md:12:1: error: import "common" does not resolve to any exported module
file.md:25:1: warning: duplicate cheat name "list pods" (also at other.md:8:1)

What it checks

Errors

Check Example
Invalid DSL syntax Malformed var, if, chain lines
Unresolved imports import foo when no export foo exists
Duplicate exports Two blocks both export docker_container
Undeclared command variables $host in command but no var host

Warnings

Check Example
Duplicate cheat names Two cheats with ## list pods (across any files)
Empty headings A ## with no text
Missing chain steps Chain has step 1 and 3 but no 2
Duplicate chain steps Two cheats both chain release 2
Cheat with no code block A heading + metadata but no fenced command

Language-aware variable detection

The linter uses the code fence language hint to avoid false positives on language-native variables.

Shell (sh, bash, zsh)

These are not flagged as undeclared:

  • Built-in variables: $HOME, $USER, $PATH, $PWD, $SHELL, $?, $!, $$, $#, $@, $*, $0-$9, $OPTARG, $OPTIND, etc.
  • Loop variables: for x in ... declares $x
  • Assignments: x=value declares $x
  • read x, local x, declare x, export x=value - all declare $x
  • Single-quoted strings are not scanned
  • Variables inside $(...) subshells are not scanned

PowerShell

These are not flagged:

  • Automatic variables: $_, $true, $false, $null, $PSItem, $PSScriptRoot, $env:PATH, etc.
  • Provider namespaces: $env:, $Env: prefixes
  • Assignments: $x = value declares $x
  • foreach ($x in ...), param($x), function parameters
  • Method chains: $obj.Property is treated as accessing $obj

Angle bracket syntax

When var_syntax includes angle, <name> references are strict - there are no language-built-in angle-bracket variables. Every <name> must be declared.

Strict mode

By default, only errors cause a non-zero exit code. With --strict, warnings also fail:

cheatmd --lint --strict ~/cheats || echo "Lint failed"

Useful in CI pipelines.

Bypass checks

To suppress a specific lint check, add a literal var to the cheat that exactly matches the text you want to suppress:

## My Cheat

```sh title:"My Cheat"
echo $status
```
<!-- cheat
var status := $status
-->

When CheatMD returns this cheat it will literally return echo $status as a result.

See also

Clone this wiki locally