Skip to content

dylint: ban raw .fbuild path literals outside fbuild-paths; ratchet to zero #1349

Description

@zackees

Problem

fbuild-paths declares itself the single source of truth for all .fbuild paths (crates/fbuild-paths/src/lib.rs:3), but the .fbuild / .fbuild/build path segments are hardcoded as raw string literals in 69 files across the workspace — including production code:

  • fbuild-cli/src/cli/{ide,debug,symbols_cmd,ide_debug,clang_tools,args,dispatch,lib_select}.rs
  • fbuild-build-engine/src/{linker.rs,build_info.rs,symbol_analyzer,framework_libs.rs}
  • fbuild-daemon/src/{handlers/libraries.rs,handlers/emulator,models.rs}
  • fbuild-deploy/src/{lpc.rs,wlink.rs,wchisp.rs,probe_rs.rs,lpc_debugger_reflash.rs}
  • fbuild-core/src/{response_file.rs,path.rs,lib.rs}
  • plus ~25 test files hand-rolling fixture layouts like dir.join(".fbuild/build/uno/release/...")

Raw literals drift from the real layout rules (env-segment auto-collapse, FBUILD_BUILD_DIR override, PIO .build/pio layouts — see agents/docs/path-conventions.md) and silently break compile_cwd_from_output / BuildLayout consumers when the layout evolves.

Proposal

  1. New dylint lint dylints/ban_raw_fbuild_path (pattern after the existing dylints/ban_raw_subprocess crate): flag string literals containing .fbuild outside crates/fbuild-paths/src/** (the sanctioned definition site).
  2. Export canonical primitives from fbuild-paths: FBUILD_DIR_NAME / BUILD_DIR_NAME consts plus the existing project_fbuild_dir() / BuildLayout::resolve() so call sites have a mechanical replacement.
  3. Ratchet: land the lint with a baseline allowlist of the current 69 files; each file must be sanitized (route through BuildLayout / the new consts) and removed from the allowlist; the allowlist may only shrink. CI fails on any new raw-literal site.
  4. Test fixtures should build layouts via fbuild_paths::BuildLayout::new(project, env, profile).resolve() instead of hand-rolled join(".fbuild/build/...") chains.

Acceptance

  • dylints/ban_raw_fbuild_path lint crate exists, wired into the dylint CI gate alongside ban_raw_subprocess
  • Baseline allowlist checked in; count recorded in this issue
  • Allowlist reaches zero (or only fbuild-paths definition sites remain)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions