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.
wheels analyze
Section titled “wheels analyze”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.
Synopsis
Section titled “Synopsis”wheels analyze [target]Description
Section titled “Description”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.
Target argument
Section titled “Target argument”| Value | Scans |
|---|---|
all (default) | app/models/, app/controllers/, and app/views/ |
models | app/models/ only |
controllers | app/controllers/ only |
views | app/views/ only |
If you pass anything else, the command falls through to all.
None. wheels analyze takes a single positional target and no flags.
Example
Section titled “Example”wheels analyzeSample output (trimmed):
Analyzing code...
Code Analysis Results────────────────────────────────────Files: 29Lines: 1842Functions: 134Grade: 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.42sIf nothing is found, the command prints No issues found! in green instead of the three category lists.
wheels validate
Section titled “wheels validate”Run the shorter, error-focused pass: check model associations, controller conventions, route syntax, and view cfparam declarations, then report pass/fail.
Synopsis
Section titled “Synopsis”wheels validateDescription
Section titled “Description”wheels validate uses the same analysis service but calls its validate() method, which runs four targeted checks:
- Models — iterates
app/models/*.cfcand flags problems like mixed association argument styles or a missingextends="Model"in the active (uncommented) component declaration; a commented-outextends="Model"does not satisfy the check. - Controllers — iterates
app/controllers/*.cfclooking for convention violations (public filter functions, missingextends="Controller"in the active component declaration, etc.). - Routes — parses
config/routes.cfmfor syntax problems. - Views — walks
app/views/for.cfmfiles missingcfparamdeclarations.
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.
Example
Section titled “Example”wheels validateSample output when everything passes (warnings can still appear):
Validating...
Validation passed — no errors found (1 warnings) [WARNING] show.cfm — missing cfparam for 'post'Sample output with errors:
Validating...
Validation found 2 issue(s): [ERROR] Posts.cfc — hasMany mixes positional and named args [ERROR] routes.cfm — unclosed resources() blockwheels coverage
Section titled “wheels coverage”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.
Synopsis
Section titled “Synopsis”wheels coverage [--top=N] [--no-test-db]| Flag | Default | Description |
|---|---|---|
--top=N | 15 | How many files to list in the ranking. |
--no-test-db | off | Run against the main database instead of the isolated test database. |
Example
Section titled “Example”wheels coveragewheels 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.
Common workflows
Section titled “Common workflows”Pre-commit sanity check
Section titled “Pre-commit sanity check”wheels validatewheels analyzeRun 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
Section titled “Scope the analysis”wheels analyze modelswheels analyze controllerswheels analyze viewsNarrow 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.