Skip to content

chore(scripts): add dead-code detector - #45

Closed
nexxeln wants to merge 1 commit into
devfrom
nxl/dead-code-detector
Closed

nexxeln wants to merge 1 commit into
devfrom
nxl/dead-code-detector

Conversation

@nexxeln

@nexxeln nexxeln commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Why

rustc does not flag an unused pub item in a library crate. allow(dead_code) also hides items that nothing calls. So a clean cargo clippy run says little about dead code in crates/core or in crates/cli/tests/support. scripts/dead-code.mjs closes both gaps and runs the JS and dependency checks in the same pass. You can rerun it before any cleanup.

On current dev, it finds no dead code. This PR adds only the detector and deletes nothing.

Scope

  • scripts/dead-code.mjs. Run node scripts/dead-code.mjs --linux.
  • Rust. The script copies the tree to a temp directory, strips allow(dead_code), and narrows every pub item in crates/core/src to pub(crate). If another crate uses an item, the narrowed build fails, and the script restores that item to pub and builds again. When the build passes, rustc flags the exported items that only core itself could use. Clippy runs with -W dead_code -W unreachable_pub. --linux repeats the build in a rust:latest container, because macOS builds skip cfg(target_os = "linux") code.
  • Other checks: cargo machete, unused [workspace.dependencies] entries, knip on plugins/opencode and npm/rift-snapshot, tsc --noUnusedLocals --noUnusedParameters on the plugin, scripts/ files that nothing invokes, uncalled shell functions, and #[no_mangle] FFI symbols that nothing outside crates/ffi names.
  • Each candidate then gets an rg --word-regexp search across the repo, so string, dynamic, and cross-language references show up. The verdict is dead when nothing references the item, test-only when only tests do, and review otherwise.

Tradeoffs

  • The script uses Node, like the other files in scripts/. It needs cargo-machete, rg, and bun on PATH, plus Docker for --linux.
  • CI does not run the script. The Linux pass needs Docker, and the report still needs a human to read the review rows.

Verification

Detector output on dev at 5afb72b (node scripts/dead-code.mjs --linux, with the 15 unreachable_pub rows for crates/cli/tests/support collapsed):

## dead (0)

## test-only (1)
crates/core/src/lib.rs:420 rust: dead_code: remove_all [narrowed; host/rift,linux/rift]
    ref crates/core/src/tests.rs:796:    let removed = manager.remove_all(&source).unwrap();
    ref crates/core/src/tests.rs:832:        manager.remove_all(&source),
    ref crates/core/src/tests.rs:849:    assert_eq!(manager.remove_all(&first).unwrap(), vec![second]);

## review (2)
crates/core/src/lib.rs:213 rust: dead_code: create [narrowed; host/rift,linux/rift]
crates/core/src/strategy/mod.rs:45 rust: dead_code: Converted [plain; host/rift]

## visibility (15)
  • Manager::remove_all and Manager::create are wrappers that pass default options. Only crates/core/src/tests.rs and linux_filesystem_tests.rs call them. The create refs in the full output are npm JS names and shell commands. This PR leaves both wrappers in place because feat(core): add guarded lifecycle plans and recovery #44 edits crates/core/src/lib.rs.
  • The macOS build never constructs StrategyInit::Converted. strategy/btrfs.rs constructs it on Linux, so the variant is live.
  • To test the detector, I added seven pieces of dead code in a scratch worktree: a private fn, an unused exported Manager method, an unused test-support fn, an unused TS export, an unused workspace dependency, an uncalled shell function, and an enum variant. The script reported the first six as dead. The enum variant broke exhaustive matches, so that test case was invalid.
  • cargo +nightly udeps --workspace --all-targets --locked agrees with machete: "All deps seem to have been used".
  • On this branch, cargo test --workspace --locked, bun test (5 pass), and bun run typecheck pass. I built rift-cli and ran init, create, list, and remove against a temp database.

scripts/dead-code.mjs reports dead-code candidates from rustc, cargo-machete, knip, tsc and a repo-wide word search. It narrows every pub item in crates/core to pub(crate) in a scratch copy so rustc can flag exported items that no other crate uses. Run it with --linux to add a pass in a rust:latest container for Linux-only code.
@nexxeln nexxeln closed this Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant