Repository navigation
Description
Background
While fixing #515 / #518 it became clear that fbuild has several near-duplicate code paths that all want to resolve a board id (and other config pieces) but each reach for the underlying primitive independently. Every time one of those primitives gains a new parameter — like the recently added project_dir for project-local boards/*.json — every call site has to be updated by hand, and missing one is silent (the build just behaves as if the new feature isn't there).
The proximate example: #516 added BoardConfig::from_board_id_in_project(..., project_dir) and updated compile_many::platform_for_board. But pipeline::BuildContext::new_with_perf (the daemon's actual fbuild build path) and script_runtime::build_script_runtime_board_config were both missed — they kept calling the legacy from_board_id and silently dropped the project_dir context. End users still saw unknown board 'X' (no built-in defaults) even though the underlying lookup primitive could find it. PR #518 catches them up, but the structural issue remains.
Ask
Audit the workspace for duplicated config-resolution logic and consolidate into a small set of shared entry points that take ALL needed context (project_dir, env_name, overrides, etc.) once. Concretely:
Board lookup (immediate)
crates/fbuild-build/src/compile_many.rs:platform_for_boardcrates/fbuild-build/src/pipeline/context.rs:BuildContext::new_with_perfcrates/fbuild-build/src/script_runtime.rs:build_script_runtime_board_configcrates/fbuild-cli/src/cli/deploy.rs:run_deploy(two consecutivefrom_board_idcalls with a fallback pattern repeated 3+ times indaemon/src/handlers/operations/deploy.rs)crates/fbuild-daemon/src/handlers/operations/deploy.rs— there are ~5 instances of the samefrom_board_id(&board_id, &deploy_board_overrides).or_else(|_| from_board_id(&board_id, &HashMap::new()))pattern (lines ~154, ~427, ~667, ~699). That fallback strongly suggests a shared helper.
Other likely candidates worth checking
- platformio.ini reading: are there multiple places that parse / hold a
PlatformIOConfigper build?from_path+from_path_with_overrides+get_env_configare called from many sites. - project_dir handling: many places independently derive things like
project_dir.join(\"platformio.ini\"),project_dir.join(\".fbuild\"), etc. - toolchain resolution + extra-script overlay setup — large per-orchestrator copies might share a common pre-build shim.
Proposed shape
A small fbuild_build::resolution (or similar) module with a couple of entry points:
pub struct ResolutionContext<'a> {
pub project_dir: &'a Path,
pub env_name: &'a str,
pub config: &'a PlatformIOConfig,
pub board_overrides: &'a HashMap<String, String>,
}
impl ResolutionContext<'_> {
pub fn resolve_board(&self) -> Result<BoardConfig> { ... }
pub fn resolve_platform(&self) -> Result<Platform> { ... }
pub fn resolve_extra_script_overlay(&self) -> Result<BuildOverlay> { ... }
}Then every existing site becomes one call instead of three. Adding the next parameter is then a one-line change to the context struct rather than a workspace-wide rename.
Acceptance
- A single grep for
BoardConfig::from_board_id(and variants) returns ≤2 call sites outsidefbuild-config(the new entry points + one test helper), down from the ~12 production sites today. - Tests still green, no behavior change.
- A short doc comment on the new module pointing future feature work at the right injection point.
Why now
Every feature that adds a knob (project_dir was just the most recent) gets paid for N times instead of once, and N-1 of those payments are silent regressions waiting for a CI run to surface them. This is cheap to consolidate while the call-site list is still small enough to enumerate.
Filed alongside #518 (which is the minimum fix to unblock the immediate user).
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTriage
Activity
refactor(daemon): consolidate board-resolution fallback into helper (#…
refactor: consolidate board override-fallback resolution into helper (#…
refactor(build): add ResolutionContext board-resolution entry point (#…
refactor(daemon): route emulator board lookups through project-aware …
refactor(build): funnel build-side board resolution through resolutio…
refactor(config): thread project_dir through deploy board-resolution …
refactor(test-support): consolidate BoardConfig::from_board_id test s…