Skip to content

Command Line Tools

Code Quality

Two read-only diagnostics cluster here — wheels analyze (a long-form report with metrics, anti-patterns, and complexity hotspots) and wheels validate (a tighter, error-focused pass over models, controllers, routes, and views) — plus wheels coverage, which instruments the app, runs the suite, and ranks files by change risk.

You’ll use this for:

  • Catching Wheels anti-patterns (mixed argument styles, query-vs-array confusion, non-private filters) before they ship.
  • Spotting complex functions and code smells that have grown past sanity while you weren’t looking.
  • Running a quick validation sweep before a deploy to confirm models, controllers, routes, and views still parse clean.

Walk the project’s CFC and CFM files and print a code-health report: totals, a graded health score, and lists of anti-patterns, complex functions, and code smells.

"
wheels analyze [target]

wheels analyze delegates to the analysis service, which reads files under app/models/, app/controllers/, and app/views/ (or a single directory if you pass a target). Each file is scanned for Wheels-specific anti-patterns — the kind listed in the top-10 at the root of this project — plus cyclomatic-complexity outliers and generic code smells. The command prints counts, a letter grade (A–F) backed by a 0–100 health score, and the individual findings with file name, line number, and severity.

This command does not require a running server. It reads the project off disk and exits.

ValueScans
all (default)app/models/, app/controllers/, and app/views/
modelsapp/models/ only
controllersapp/controllers/ only
viewsapp/views/ only

If you pass anything else, the command falls through to all.

None. wheels analyze takes a single positional target and no flags.

Terminal window
wheels analyze

Sample output (trimmed):

sample output
Analyzing code...
Code Analysis Results
────────────────────────────────────
Files: 29
Lines: 1842
Functions: 134
Grade: B (82/100)
Anti-Patterns (2)
[ERROR] Posts.cfc:18 — hasMany mixes positional and named args
[WARNING] User.cfc:34 — filter 'authenticate' is public, should be private
Complex Functions (1)
Posts.cfc:create — complexity 14
Completed in 0.42s

If nothing is found, the command prints No issues found! in green instead of the three category lists.

Run the shorter, error-focused pass: check model associations, controller conventions, route syntax, and view cfparam declarations, then report pass/fail.

"
wheels validate

wheels validate uses the same analysis service but calls its validate() method, which runs four targeted checks:

  • Models — iterates app/models/*.cfc and flags problems like mixed association argument styles or a missing extends="Model" in the active (uncommented) component declaration; a commented-out extends="Model" does not satisfy the check.
  • Controllers — iterates app/controllers/*.cfc looking for convention violations (public filter functions, missing extends="Controller" in the active component declaration, etc.).
  • Routes — parses config/routes.cfm for syntax problems.
  • Views — walks app/views/ for .cfm files missing cfparam declarations.

The result is a valid flag (true if zero error-severity issues exist), a total count, and a per-issue list with file, severity, and message.

None. wheels validate takes no arguments and no flags.

Terminal window
wheels validate

Sample output when everything passes (warnings can still appear):

sample output — passing
Validating...
Validation passed — no errors found (1 warnings)
[WARNING] show.cfm — missing cfparam for 'post'

Sample output with errors:

sample output — errors
Validating...
Validation found 2 issue(s):
[ERROR] Posts.cfc — hasMany mixes positional and named args
[ERROR] routes.cfm — unclosed resources() block

Ranks your app’s files by change risk — the CRAP score (cyclomatic complexity × test coverage) — so you can see which files are hardest to change safely. Unlike analyze’s static complexity, coverage adds the tested half: it instruments app/ with function-level counters, runs the app test suite against a running server, and reports a ranked list. The instrumentation is reverted automatically afterward.

"
wheels coverage [--top=N] [--no-test-db]
FlagDefaultDescription
--top=N15How many files to list in the ranking.
--no-test-dboffRun against the main database instead of the isolated test database.
Terminal window
wheels coverage

wheels coverage needs a running server (it instruments app/, then runs the suite against it) — start one with wheels start first.

Pairs with the debug bar’s Code Complexity panel: complexity is static and always visible; wheels coverage adds the test-coverage half of the CRAP score on demand. Files at the top of the ranking are the ones to touch with tests in hand.

run both checks in sequence
wheels validate
wheels analyze

Run validate first and read its output for any ✗ errors or ⚠ warnings. Then run analyze for a broader look at health scores and anti-patterns. wheels validate exits non-zero when it finds error-severity issues, so you can gate CI on it. wheels analyze always exits 0 — its findings live in the output only.

scope the analysis to one directory
wheels analyze models
wheels analyze controllers
wheels analyze views

Narrow to one directory while you’re iterating on it. Useful when you’re refactoring models and don’t want controller noise in the report — or vice versa.