Smells Code Analyzer (Rust)
Rust implementation of the original smells-code-analyzer CLI.
The binary reproduces the TypeScript version’s behaviour: it loads the same JSON
configuration, filters candidate files, walks TypeScript syntax trees via
tree-sitter, calls the configured language server for reference counts, and
prints the familiar emoji-styled report.
Features
- Compatible CLI:
sca --config-file <path> [--threshold <n>] - JSON config schema shared with the Node.js tool
- File discovery and content filtering using
globset/ignore - Tree-sitter based structural matching with nested node targets
- Minimal LSP client (JSON-RPC) for
initialize,didOpen,references,shutdown - ASCII/non-ASCII sanitisation pipeline equivalent to the original implementation
- Threshold enforcement with non-zero exit code on smell overflow
Getting Started
You can override the maximum number of allowed “dead” entities:
To analyse a specific set of files listed in changed-files.txt (newline separated paths), use:
Paths may be absolute or relative to the list file; entries outside the analysed directory or missing on disk are skipped.
Snapshot Modes
Generate a JSON snapshot of all detected errors (without emoji):
Compare current analysis against a previous snapshot and fail with exit code if new errors are found:
The --compare-snapshot flag will print all new errors and exit with an error if any new issues are detected.
Both snapshot flags work with --files-from to scope the analysis to a specific file list.
Important: Snapshots store file paths relative to analyzeDirectory from your config. This ensures snapshots are portable between different environments (e.g., local development vs CI), where absolute paths may differ.
Note
The language server referenced in the config (e.g.node .../typescript-language-server) must be accessible on the host machine before running the binary.
Project Layout
src/
main.rs # CLI entry + orchestration
config.rs # JSON config loading, validation, encoding helpers
model.rs # Shared data structures
sanitize.rs # Source pre-processing
analyzer/
mod.rs # Analyzer facade + aggregation helpers
files.rs # File discovery utilities
tree.rs # Tree-sitter traversal and node extraction
lsp.rs # Async JSON-RPC LSP client
report.rs # Emoji-styled report rendering
Logging is powered by tracing. Set RUST_LOG=debug for verbose diagnostics,
including raw LSP stderr output.
Testing & Tooling
cargo fmtensures Rustfmt compliance (already applied).cargo testruns unit coverage (sanitizeandreportmodules today).cargo checkvalidates the build graph (requires access to crates.io).
Publishing
- Update
Cargo.tomlmetadata (version,description,repository,readme,keywords, etc.).
The manifest already contains sensible defaults; bump the version before each release. - Ensure the crate builds cleanly and the README renders:
cargo fmt && cargo check && cargo test && cargo doc --no-deps. - Create a tagged release in git (e.g.
git tag -a vX.Y.Z -m "sca-rust vX.Y.Z"). - Dry-run the publish to crates.io:
- Publish for real once the dry-run succeeds:
- (Optional) Build release binaries for GitHub Releases:
Consider using# tar/zip target/release/sca for each target triple you cross-compilecrossor GitHub Actions to produce multi-platform artefacts.
Next Steps
- Expand unit coverage for config parsing and tree traversal.
- Add integration tests against a TypeScript fixture to snapshot reports.
- Evaluate caching with pooled tree-sitter parsers for large codebases.