Skip to content

01 — Audit & re-scaffold: modular skeleton + the CLDK CLI contract #10

Description

@rahlk

Part of #9. Phase 0 — foundations.

Learning goals

Packages/crates/modules and visibility (TRPL Managing Growing Projects with Packages, Crates, and
Modules
), error handling design (Result, ?, a crate-level error enum with thiserror
TRPL Error Handling), clap derive, workspace layout, tracing for logs.

Task

Turn the flat scaffold into the modular package every CLDK analyzer shares (mirror
codeanalyzer-python's shape in Rust idiom — one module per phase, seams first):

src/
main.rs thin: parse CLI -> options -> core::analyze -> emit
cli.rs clap derive, the FULL CLDK flag contract
core.rs ORCHESTRATOR ONLY — delegates every phase, inlines nothing
options.rs AnalysisOptions
config.rs extensions, skip-dirs, cache subdir name
schema/ the entities/ types, evolved in issue 02
syntactic_analysis/ symbol-table builder (issues 04–05)
semantic_analysis/ call graph (06) + mir/ stub subdir (the level-2 seam, empty)
analysis/ pluggable pass layer: AnalysisPass trait + registry (empty but wired)
frameworks/ entrypoint-finder trait (empty but wired)
utils/ logging, progress — no analysis logic

CLI: align to the CLDK contract — -i/--input, -o/--output (stdout JSON when omitted),
-f/--format json|msgpack, --emit json|neo4j|schema, -a 1|2 (3 arrives in issue 16),
-t/--target-files, --skip-tests/--include-tests, --eager/--lazy, -c/--cache-dir,
-j/--jobs, -v (count). Remove the -f/--project-root-path flag (field project_root_pom) — a fossil copied from codeanalyzer-java, where it points at the root pom.xml/build.gradle for classpath materialization. Rust needs none of it: cargo metadata from -i finds the workspace-root Cargo.toml itself, and -f is needed for --format. (--build-cmd/--no-build/--no-clean-dependencies are the same Java inheritance — drop them too; revisit --manifest-path only if a real workspace edge case demands it.) Decide the binary
name (canrs fits the canpy/cants/canclang convention) and record it + the tooling table in the
README under Architecture & Tooling.

Teacher's notes

  • The empty-but-wired seams are the deliverable, not ceremony: the TS analyzer shipped without
    them and could not host extensions without a rewrite (references/analyzer-architecture.md).
  • core::analyze() should read as a table of contents. If a match arm grows analysis logic, it's
    in the wrong file.
  • An AnalysisPass trait with requires()/provides() is your first real trait design. Keep it
    object-safe (Box<dyn AnalysisPass>) — you'll learn why that constraint exists.

Gate

  • cargo build && cargo test && cargo clippy -- -D warnings green.
  • canrs --help shows the contract; --format msgpack exits non-zero with a clear message
    (never a silent fallback).
  • Every skeleton module exists and core compiles against the (still-stub) phase functions.

Metadata

Metadata

Assignees

Labels

learning-ladderThe escalating-complexity curriculum issues

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions