diff --git a/crates/fbuild-build-engine/src/compiler_tests.rs b/crates/fbuild-build-engine/src/compiler_tests.rs index 96a4a32a..2aa8e3d1 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/src/compile_many.rs b/crates/fbuild-build/src/compile_many.rs index 2bfe39d7..cddb0a4e 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 e7c94dbb..475eb081 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 9c6100fd..da20719b 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 fd87f7e8..ce3d0887 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 d5adba27..5ec68633 100644 --- a/crates/fbuild-build/tests/compile_many_two_stage.rs +++ b/crates/fbuild-build/tests/compile_many_two_stage.rs @@ -98,8 +98,8 @@ impl SketchBuilder for MockBuilder { // bug we are trying to rule out. let build_dir = inputs .sketch - .join(".fbuild") - .join("build") + .join(fbuild_paths::FBUILD_DIR_NAME) + .join(fbuild_paths::BUILD_DIR_NAME) .join(&inputs.env_name) .join(match inputs.profile { BuildProfile::Release => "release", diff --git a/crates/fbuild-build/tests/eh_frame_strip_esp32.rs b/crates/fbuild-build/tests/eh_frame_strip_esp32.rs index da84cec9..f595fef3 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 1803d77c..d89b1ba9 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 3a6240bd..6bf9b097 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 917d9f3e..843452f8 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 c6cd0c1b..59efc0d4 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 0391cf9d..8b9f5039 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 d2d9b731..084db350 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 9da0f296..721fe746 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 2de366a3..b248a18c 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