From 6ca8a1e16df29a959d14ebd1dffd0d6299cd82b3 Mon Sep 17 00:00:00 2001 From: zackees Date: Sun, 23 Aug 2026 17:49:36 -0700 Subject: [PATCH 1/2] =?UTF-8?q?chore(build):=20finish=20the=20`.fbuild`=20?= =?UTF-8?q?ratchet=20=E2=80=94=20baseline=20reaches=20zero?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seventh and final ratchet batch for FastLED/fbuild#1349. Allowlist 15 -> 3, and all three that remain are sanctioned definition sites. `fbuild-build`'s twelve files — `compile_many` plus eleven integration suites — assembled `/.fbuild/build//` by hand. They now build it from `FBUILD_DIR_NAME` / `BUILD_DIR_NAME`. Deliberately a literal substitution rather than a switch to `BuildLayout::resolve()`, which would be the more principled fixture. These are `#[ignore]`d toolchain-downloading suites that cannot run on this machine, and `resolve()` also honours `FBUILD_BUILD_DIR` and collapses the `` segment. Changing what the fixtures compute, in tests I cannot execute, is not a trade worth making for elegance. The literal is gone either way; moving them onto the real resolver is a separate change that should be made by someone who can run them. ## The baseline is closed 48 files spelled `.fbuild` by hand when the lint landed. All 48 now route through `fbuild_paths`. What remains: crates/fbuild-paths/src/lib.rs the source of truth crates/fbuild-core/src/path.rs where the const is declared, because fbuild-paths depends on fbuild-core and not the reverse crates/fbuild-cli/src/cli/args.rs clap stringifies `///` help into literals attributed to the `#[derive]`, so no expression edit can clear it Each carries its rationale inline. The baseline section is kept rather than deleted so the next person to reach for it can see it was closed on purpose. Lint crate 0.1.6 -> 0.1.7. Co-Authored-By: Claude Opus 5 (1M context) --- crates/fbuild-build/src/compile_many.rs | 12 +++- crates/fbuild-build/tests/avr_build.rs | 60 +++++++++++++++---- .../fbuild-build/tests/clangd_check_parity.rs | 6 +- .../tests/compile_many_stage2_perf.rs | 11 ++-- .../tests/compile_many_two_stage.rs | 2 +- .../tests/eh_frame_strip_esp32.rs | 18 +++++- crates/fbuild-build/tests/esp32_build.rs | 48 ++++++++++++--- .../fbuild-build/tests/nxplpc_build_flags.rs | 6 +- .../tests/nxplpc_core_compile_commands.rs | 14 +++-- crates/fbuild-build/tests/stm32_acceptance.rs | 6 +- .../fbuild-build/tests/teensy30_acceptance.rs | 6 +- crates/fbuild-build/tests/teensy_build.rs | 24 ++++++-- dylints/ban_raw_fbuild_path/Cargo.toml | 2 +- dylints/ban_raw_fbuild_path/src/allowlist.txt | 32 ++++------ 14 files changed, 187 insertions(+), 60 deletions(-) diff --git a/crates/fbuild-build/src/compile_many.rs b/crates/fbuild-build/src/compile_many.rs index 2bfe39d7d..cddb0a4e8 100644 --- a/crates/fbuild-build/src/compile_many.rs +++ b/crates/fbuild-build/src/compile_many.rs @@ -840,9 +840,17 @@ mod tests { // here that doesn't also update the orchestrators will silently // break the stage-1→stage-2 core/ handoff in FastLED/fbuild#335. let p = project_build_dir(Path::new("/tmp/sketch"), "uno", BuildProfile::Release); - assert!(p.ends_with("sketch/.fbuild/build/uno/release")); + assert!(p.ends_with(format!( + "sketch/{}/{}/uno/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + ))); let q = project_build_dir(Path::new("/tmp/sketch"), "esp32s3", BuildProfile::Quick); - assert!(q.ends_with("sketch/.fbuild/build/esp32s3/quick")); + assert!(q.ends_with(format!( + "sketch/{}/{}/esp32s3/quick", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + ))); } /// FastLED stages each board's project at diff --git a/crates/fbuild-build/tests/avr_build.rs b/crates/fbuild-build/tests/avr_build.rs index e7c94dbbd..475eb0814 100644 --- a/crates/fbuild-build/tests/avr_build.rs +++ b/crates/fbuild-build/tests/avr_build.rs @@ -122,7 +122,11 @@ async fn build_uno_minimal() { // `params.build_dir` is the resolved env-rooted dir per // `BuildLayout::resolve()`. let tmp = tempfile::TempDir::new().unwrap(); - let build_dir = tmp.path().join(".fbuild/build/uno/release"); + let build_dir = tmp.path().join(format!( + "{}/{}/uno/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: project_dir.clone(), @@ -210,7 +214,11 @@ async fn build_uno_minimal() { async fn compare_with_python_output() { let project_dir = home_dir().join("dev/fbuild/tests/uno_minimal"); - let python_hex = project_dir.join(".fbuild/build/uno/release/firmware.hex"); + let python_hex = project_dir.join(format!( + "{}/{}/uno/release/firmware.hex", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); if !python_hex.exists() { eprintln!( "SKIP: Python build output not found at {}", @@ -222,7 +230,11 @@ async fn compare_with_python_output() { // Build with Rust let tmp = tempfile::TempDir::new().unwrap(); - let build_dir = tmp.path().join(".fbuild/build/uno/release"); + let build_dir = tmp.path().join(format!( + "{}/{}/uno/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: project_dir.clone(), @@ -317,7 +329,11 @@ void loop() { ) .unwrap(); - let build_dir = project_dir.join(".fbuild/build/uno/release"); + let build_dir = project_dir.join(format!( + "{}/{}/uno/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: project_dir.to_path_buf(), env_name: "uno".to_string(), @@ -438,7 +454,11 @@ fn stomp_mtimes(root: &Path, mtime: FileTime) { } fn fingerprint_path(project_dir: &Path) -> PathBuf { - project_dir.join(".fbuild/build/uno/release/build_fingerprint.json") + project_dir.join(format!( + "{}/{}/uno/release/build_fingerprint.json", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )) } /// RAII guard for an env var: sets it on construction, restores the previous @@ -501,7 +521,11 @@ async fn cache_survives_tar_extract_uno() { let cold_result = under_test_timeout(orchestrator.build(&uno_build_params( &proj_a, - proj_a.join(".fbuild/build/uno/release"), + proj_a.join(format!( + "{}/{}/uno/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )), true, ))) .await @@ -533,7 +557,11 @@ async fn cache_survives_tar_extract_uno() { // because of an orchestrator/fast-path bug unrelated to tar restoration. let same_project_warm = under_test_timeout(orchestrator.build(&uno_build_params( &proj_a, - proj_a.join(".fbuild/build/uno/release"), + proj_a.join(format!( + "{}/{}/uno/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )), false, ))) .await @@ -564,8 +592,16 @@ async fn cache_survives_tar_extract_uno() { proj_b.display() ); assert!( - proj_b.join(".fbuild/build").exists(), - "tar restore left no .fbuild/build/ at {}", + proj_b + .join(format!( + "{}/{}", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )) + .exists(), + "tar restore left no {}/{}/ at {}", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME, proj_b.display() ); assert_ne!( @@ -578,7 +614,11 @@ async fn cache_survives_tar_extract_uno() { let warm_result = under_test_timeout(orchestrator.build(&uno_build_params( &proj_b, - proj_b.join(".fbuild/build/uno/release"), + proj_b.join(format!( + "{}/{}/uno/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )), false, ))) .await diff --git a/crates/fbuild-build/tests/clangd_check_parity.rs b/crates/fbuild-build/tests/clangd_check_parity.rs index 9c6100fd1..da20719bc 100644 --- a/crates/fbuild-build/tests/clangd_check_parity.rs +++ b/crates/fbuild-build/tests/clangd_check_parity.rs @@ -154,7 +154,11 @@ async fn clangd_check_parity_uno() { install_test_compile_backend().await; let tmp = tempfile::TempDir::new().expect("tempdir"); - let build_dir = tmp.path().join(".fbuild/build/uno/release"); + let build_dir = tmp.path().join(format!( + "{}/{}/uno/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: project_dir.clone(), diff --git a/crates/fbuild-build/tests/compile_many_stage2_perf.rs b/crates/fbuild-build/tests/compile_many_stage2_perf.rs index fd87f7e83..ce3d0887f 100644 --- a/crates/fbuild-build/tests/compile_many_stage2_perf.rs +++ b/crates/fbuild-build/tests/compile_many_stage2_perf.rs @@ -275,10 +275,13 @@ Compiled 5/26 files /// point) and embeds its head and tail so the failure is diagnosable after /// the TempDir is dropped — FastLED/fbuild#1346. fn stage2_failure_detail(r: &SketchResult) -> String { - let log_path = r - .log_path - .clone() - .unwrap_or_else(|| r.sketch.join(".fbuild/build/uno/release/compile_many.log")); + let log_path = r.log_path.clone().unwrap_or_else(|| { + r.sketch.join(format!( + "{}/{}/uno/release/compile_many.log", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )) + }); let log = fs::read_to_string(&log_path).unwrap_or_else(|e| { format!( "", diff --git a/crates/fbuild-build/tests/compile_many_two_stage.rs b/crates/fbuild-build/tests/compile_many_two_stage.rs index d5adba27b..02ea9bdb1 100644 --- a/crates/fbuild-build/tests/compile_many_two_stage.rs +++ b/crates/fbuild-build/tests/compile_many_two_stage.rs @@ -98,7 +98,7 @@ impl SketchBuilder for MockBuilder { // bug we are trying to rule out. let build_dir = inputs .sketch - .join(".fbuild") + .join(fbuild_paths::FBUILD_DIR_NAME) .join("build") .join(&inputs.env_name) .join(match inputs.profile { diff --git a/crates/fbuild-build/tests/eh_frame_strip_esp32.rs b/crates/fbuild-build/tests/eh_frame_strip_esp32.rs index da84cec9a..f595fef37 100644 --- a/crates/fbuild-build/tests/eh_frame_strip_esp32.rs +++ b/crates/fbuild-build/tests/eh_frame_strip_esp32.rs @@ -52,7 +52,11 @@ async fn install_test_compile_backend() { } fn make_params(project_dir: &Path) -> BuildParams { - let build_dir = project_dir.join(".fbuild/build/esp32dev/release"); + let build_dir = project_dir.join(format!( + "{}/{}/esp32dev/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); BuildParams { project_dir: project_dir.to_path_buf(), env_name: "esp32dev".to_string(), @@ -141,7 +145,11 @@ async fn eh_frame_strip_drops_firmware_at_least_150kb() { .elf_path .clone() .expect("preserve build should produce ELF path"); - let preserve_firmware_bin = preserve_dir.join(".fbuild/build/esp32dev/release/firmware.bin"); + let preserve_firmware_bin = preserve_dir.join(format!( + "{}/{}/esp32dev/release/firmware.bin", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); std::env::remove_var("FBUILD_KEEP_EH_FRAME"); // --- Build 2: strip eh_frame --- @@ -156,7 +164,11 @@ async fn eh_frame_strip_drops_firmware_at_least_150kb() { .elf_path .clone() .expect("strip build should produce ELF path"); - let strip_firmware_bin = strip_dir.join(".fbuild/build/esp32dev/release/firmware.bin"); + let strip_firmware_bin = strip_dir.join(format!( + "{}/{}/esp32dev/release/firmware.bin", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); std::env::remove_var("FBUILD_STRIP_EH_FRAME"); // --- firmware.bin delta --- diff --git a/crates/fbuild-build/tests/esp32_build.rs b/crates/fbuild-build/tests/esp32_build.rs index 1803d77cf..d89b1ba9a 100644 --- a/crates/fbuild-build/tests/esp32_build.rs +++ b/crates/fbuild-build/tests/esp32_build.rs @@ -93,7 +93,11 @@ void loop() { ) .unwrap(); - let build_dir = project_dir.join(".fbuild/build/esp32dev/release"); + let build_dir = project_dir.join(format!( + "{}/{}/esp32dev/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: project_dir.to_path_buf(), env_name: "esp32dev".to_string(), @@ -187,7 +191,11 @@ void loop() { ) .unwrap(); - let build_dir = project_dir.join(".fbuild/build/esp32c6/release"); + let build_dir = project_dir.join(format!( + "{}/{}/esp32c6/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: project_dir.to_path_buf(), env_name: "esp32c6".to_string(), @@ -274,7 +282,11 @@ void loop() { ) .unwrap(); - let build_dir = project_dir.join(".fbuild/build/esp32c3/release"); + let build_dir = project_dir.join(format!( + "{}/{}/esp32c3/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: project_dir.to_path_buf(), env_name: "esp32c3".to_string(), @@ -362,7 +374,11 @@ void loop() { ) .unwrap(); - let build_dir = project_dir.join(".fbuild/build/esp32s3/release"); + let build_dir = project_dir.join(format!( + "{}/{}/esp32s3/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: project_dir.to_path_buf(), env_name: "esp32s3".to_string(), @@ -440,7 +456,11 @@ async fn build_esp32s3_fixture() { } install_test_compile_backend().await; - let build_dir = project_dir.join(".fbuild/build/esp32s3/release"); + let build_dir = project_dir.join(format!( + "{}/{}/esp32s3/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: project_dir.clone(), env_name: "esp32s3".to_string(), @@ -509,7 +529,11 @@ async fn build_nightdriverstrip_demo() { install_test_compile_backend().await; let tmp = tempfile::TempDir::new().unwrap(); - let build_dir = tmp.path().join(".fbuild/build/demo/release"); + let build_dir = tmp.path().join(format!( + "{}/{}/demo/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: project_dir.clone(), @@ -595,7 +619,11 @@ async fn incremental_nightdriverstrip_no_changes() { async fn incremental_build_at(project_dir: &std::path::Path, env_name: &str) { // Verify there's an existing build let build_marker = project_dir - .join(".fbuild/build") + .join(format!( + "{}/{}", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )) .join(env_name) .join("release/firmware.elf"); if !build_marker.exists() { @@ -683,7 +711,11 @@ async fn incremental_nightdriverstrip_one_file_changed() { let env_name = "demo"; let build_marker = project_dir - .join(".fbuild/build") + .join(format!( + "{}/{}", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )) .join(env_name) .join("release/firmware.elf"); if !build_marker.exists() { diff --git a/crates/fbuild-build/tests/nxplpc_build_flags.rs b/crates/fbuild-build/tests/nxplpc_build_flags.rs index 3a6240bdd..6bf9b0978 100644 --- a/crates/fbuild-build/tests/nxplpc_build_flags.rs +++ b/crates/fbuild-build/tests/nxplpc_build_flags.rs @@ -83,7 +83,11 @@ async fn lpc845brk_propagates_build_flags_to_library_compile_587() { // Build into a temp dir so reruns are clean and don't litter the repo. let tmp = tempfile::TempDir::new().expect("tempdir"); - let build_dir = tmp.path().join(".fbuild/build/lpc845brk/release"); + let build_dir = tmp.path().join(format!( + "{}/{}/lpc845brk/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: fixture.clone(), diff --git a/crates/fbuild-build/tests/nxplpc_core_compile_commands.rs b/crates/fbuild-build/tests/nxplpc_core_compile_commands.rs index 917d9f3e0..843452f81 100644 --- a/crates/fbuild-build/tests/nxplpc_core_compile_commands.rs +++ b/crates/fbuild-build/tests/nxplpc_core_compile_commands.rs @@ -52,7 +52,11 @@ async fn build_core_repo(repo: &Path, env_name: &str) -> tempfile::TempDir { let tmp = tempfile::TempDir::new().expect("tempdir"); let build_dir = tmp .path() - .join(".fbuild/build") + .join(format!( + "{}/{}", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )) .join(env_name) .join("release"); @@ -96,9 +100,11 @@ async fn arduino_core_lpc845brk_compile_commands_match_platform_txt() { return; }; let tmp = build_core_repo(&repo, "lpc845brk").await; - let compile_db = tmp - .path() - .join(".fbuild/build/lpc845brk/release/compile_commands.json"); + let compile_db = tmp.path().join(format!( + "{}/{}/lpc845brk/release/compile_commands.json", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let text = fs::read_to_string(&compile_db).expect("compile_commands.json"); let entries: Vec = serde_json::from_str(&text).expect("valid compile database"); let args = entries diff --git a/crates/fbuild-build/tests/stm32_acceptance.rs b/crates/fbuild-build/tests/stm32_acceptance.rs index c6cd0c1b3..59efc0d43 100644 --- a/crates/fbuild-build/tests/stm32_acceptance.rs +++ b/crates/fbuild-build/tests/stm32_acceptance.rs @@ -82,7 +82,11 @@ async fn stm32f103c8_blink_with_spi_auto_discovers_library_205_ac4() { ) .unwrap(); - let build_dir = project_dir.join(".fbuild/build/stm32f103c8/release"); + let build_dir = project_dir.join(format!( + "{}/{}/stm32f103c8/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: project_dir.to_path_buf(), env_name: "stm32f103c8".to_string(), diff --git a/crates/fbuild-build/tests/teensy30_acceptance.rs b/crates/fbuild-build/tests/teensy30_acceptance.rs index 0391cf9d0..8b9f50390 100644 --- a/crates/fbuild-build/tests/teensy30_acceptance.rs +++ b/crates/fbuild-build/tests/teensy30_acceptance.rs @@ -97,7 +97,11 @@ async fn teensy30_analog_output_meets_205_ac2() { ) .unwrap(); - let build_dir = project_dir.join(".fbuild/build/teensy30/release"); + let build_dir = project_dir.join(format!( + "{}/{}/teensy30/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: project_dir.to_path_buf(), // WHY env_name = "teensy30": must match the [env:teensy30] key diff --git a/crates/fbuild-build/tests/teensy_build.rs b/crates/fbuild-build/tests/teensy_build.rs index d2d9b7314..084db350c 100644 --- a/crates/fbuild-build/tests/teensy_build.rs +++ b/crates/fbuild-build/tests/teensy_build.rs @@ -95,7 +95,11 @@ void loop() { ) .unwrap(); - let build_dir = project_dir.join(".fbuild/build/teensy41/release"); + let build_dir = project_dir.join(format!( + "{}/{}/teensy41/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: project_dir.to_path_buf(), env_name: "teensy41".to_string(), @@ -172,7 +176,11 @@ void loop() {} ) .unwrap(); - let build_dir = project_dir.join(".fbuild/build/teensy41/release"); + let build_dir = project_dir.join(format!( + "{}/{}/teensy41/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: project_dir.to_path_buf(), env_name: "teensy41".to_string(), @@ -226,7 +234,11 @@ async fn build_teensy41_fixture() { install_test_compile_backend().await; let tmp = tempfile::TempDir::new().unwrap(); - let build_dir = tmp.path().join(".fbuild/build/teensy41/release"); + let build_dir = tmp.path().join(format!( + "{}/{}/teensy41/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )); let params = BuildParams { project_dir: project_dir.clone(), @@ -349,7 +361,11 @@ void loop() { clean: true, clean_only: false, profile: BuildProfile::Release, - build_dir: tmp.path().join(".fbuild/build/teensy30/release"), + build_dir: tmp.path().join(format!( + "{}/{}/teensy30/release", + fbuild_paths::FBUILD_DIR_NAME, + fbuild_paths::BUILD_DIR_NAME + )), verbose: true, jobs: None, generate_compiledb: false, diff --git a/dylints/ban_raw_fbuild_path/Cargo.toml b/dylints/ban_raw_fbuild_path/Cargo.toml index 9da0f2960..721fe7467 100644 --- a/dylints/ban_raw_fbuild_path/Cargo.toml +++ b/dylints/ban_raw_fbuild_path/Cargo.toml @@ -3,7 +3,7 @@ name = "ban_raw_fbuild_path" # Bump the version to bust the dylint .so cache when allowlist.txt # changes (setup-soldr's dylint-cache key hashes the manifest but not # src/allowlist.txt). Same convention ban_manual_slash_normalize follows. -version = "0.1.6" +version = "0.1.7" description = "Ban raw '.fbuild' path literals outside fbuild-paths" edition = "2021" publish = false diff --git a/dylints/ban_raw_fbuild_path/src/allowlist.txt b/dylints/ban_raw_fbuild_path/src/allowlist.txt index 2de366a35..b248a18c5 100644 --- a/dylints/ban_raw_fbuild_path/src/allowlist.txt +++ b/dylints/ban_raw_fbuild_path/src/allowlist.txt @@ -5,11 +5,14 @@ # Rollout strategy (FastLED/fbuild#1349): # - The lint is ON and denies new raw `.fbuild` string literals by # default. -# - Everything below the "baseline" marker is a legacy site captured -# when the lint landed. The list may only SHRINK: sanitize the file -# (route through fbuild_paths) and delete its line. -# - New files MUST NOT be added here. If a call site needs a `.fbuild` -# path, it needs `fbuild_paths`, not an allowlist entry. +# - The baseline is EXHAUSTED. It started at 48 legacy sites when the +# lint landed and reached zero; every remaining line below is a +# sanctioned definition site with its rationale inline. +# - New files MUST NOT be added here — not as a baseline entry, and not +# as a "temporary" one. If a call site needs a `.fbuild` path, it +# needs `fbuild_paths`. A genuinely new sanctioned site needs the same +# kind of justification the three below carry: why no expression edit +# can remove it. # --- Sanctioned definition sites (permanent) --- @@ -35,18 +38,9 @@ crates/fbuild-core/src/path.rs crates/fbuild-cli/src/cli/args.rs # --- Baseline: legacy sites captured at landing (FastLED/fbuild#1349) --- -# Each line below is a file that spells `.fbuild` by hand today. Removing -# a line is the unit of progress on #1349; adding one is not allowed. +# +# Empty, and it stays that way. 48 files spelled `.fbuild` by hand when the +# lint landed; all 48 now route through `fbuild_paths`. This section is kept +# rather than deleted so the next person to reach for it sees that the +# baseline was closed deliberately, not that one was never opened. -crates/fbuild-build/src/compile_many.rs -crates/fbuild-build/tests/avr_build.rs -crates/fbuild-build/tests/clangd_check_parity.rs -crates/fbuild-build/tests/compile_many_stage2_perf.rs -crates/fbuild-build/tests/compile_many_two_stage.rs -crates/fbuild-build/tests/eh_frame_strip_esp32.rs -crates/fbuild-build/tests/esp32_build.rs -crates/fbuild-build/tests/nxplpc_build_flags.rs -crates/fbuild-build/tests/nxplpc_core_compile_commands.rs -crates/fbuild-build/tests/stm32_acceptance.rs -crates/fbuild-build/tests/teensy30_acceptance.rs -crates/fbuild-build/tests/teensy_build.rs From aa70463be9acca57b70994c629562d1a61498702 Mon Sep 17 00:00:00 2001 From: zackees Date: Sun, 23 Aug 2026 18:13:34 -0700 Subject: [PATCH 2/2] chore: use BUILD_DIR_NAME for the segment that follows FBUILD_DIR_NAME MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review follow-up on FastLED/fbuild#1349 batch 7. Two call sites reached for `FBUILD_DIR_NAME` and then hardcoded `"build"` as the next segment — half-migrated, and worse than either whole state: it reads as done while still carrying the literal it was supposed to remove. The lint cannot catch this. It bans `.fbuild`, and `"build"` is not that string, so both sites passed a clean workspace sweep. The gap is between the two consts, not in either one. Fixed in `compile_many_two_stage.rs` (this branch) and in `compiler_tests.rs`, which shipped with the same gap in #1394 — swept for the pattern rather than fixing only the one that was reported. Co-Authored-By: Claude Opus 5 (1M context) --- crates/fbuild-build-engine/src/compiler_tests.rs | 2 +- crates/fbuild-build/tests/compile_many_two_stage.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fbuild-build-engine/src/compiler_tests.rs b/crates/fbuild-build-engine/src/compiler_tests.rs index 96a4a32a1..2aa8e3d14 100644 --- a/crates/fbuild-build-engine/src/compiler_tests.rs +++ b/crates/fbuild-build-engine/src/compiler_tests.rs @@ -36,7 +36,7 @@ async fn compile_path_contract_pairs_cwd_and_output_arg_for_282() { let workspace = tmp_canon.join("proj_for_282"); let core = workspace .join(fbuild_paths::FBUILD_DIR_NAME) - .join("build") + .join(fbuild_paths::BUILD_DIR_NAME) .join("x") .join("quick") .join("core"); diff --git a/crates/fbuild-build/tests/compile_many_two_stage.rs b/crates/fbuild-build/tests/compile_many_two_stage.rs index 02ea9bdb1..5ec686337 100644 --- a/crates/fbuild-build/tests/compile_many_two_stage.rs +++ b/crates/fbuild-build/tests/compile_many_two_stage.rs @@ -99,7 +99,7 @@ impl SketchBuilder for MockBuilder { let build_dir = inputs .sketch .join(fbuild_paths::FBUILD_DIR_NAME) - .join("build") + .join(fbuild_paths::BUILD_DIR_NAME) .join(&inputs.env_name) .join(match inputs.profile { BuildProfile::Release => "release",