Skip to content

feat(fbuild-config): resolve project-local boards/*.json (closes #515)#516

Merged
zackees merged 1 commit into
mainfrom
feat/project-local-boards
Jun 8, 2026
Merged

feat(fbuild-config): resolve project-local boards/*.json (closes #515)#516
zackees merged 1 commit into
mainfrom
feat/project-local-boards

Conversation

@zackees

@zackees zackees commented Jun 8, 2026

Copy link
Copy Markdown
Member

Closes #515.

Summary

When the built-in board database has no entry for the requested board id, fall back to <project_dir>/boards/<board_id>.json. This matches PlatformIO's behavior of auto-discovering project-local board manifests next to platformio.ini, so well-formed PIO projects that ship a boards/ directory build under fbuild without per-board upstream changes.

Why

Reproducer from #515:

build error: config error: unknown board 'lpc845brk' (no built-in defaults)

A user's platformio.ini declared board = lpc845brk with a boards/lpc845brk.json sitting next to it. PlatformIO finds it automatically; fbuild didn't even look. After this PR fbuild does the same lookup.

Lookup order

  1. Built-in DB (compile-time include_dir!)
  2. <project_dir>/boards/<id>.json (NEW — only consulted when (1) misses)

Precedence is fallback-only. Bundled wins over project-local. Explicit override of a bundled board via the project-local path is intentionally not supported here — open a separate FR if you want that.

Public API

// New
BoardConfig::from_board_id_in_project(board_id, overrides, project_dir: Option<&Path>)

// Existing — now a thin wrapper
BoardConfig::from_board_id(board_id, overrides)
  -> from_board_id_in_project(board_id, overrides, None)

compile_many internally passes the first sketch's project_dir through platform_for_board, so fbuild build <dir> -e <env> resolves <dir>/boards/<env_board>.json automatically.

Format handling

flatten_board_entry was extended to accept BOTH:

  • enriched format (top-level mcu, fcpu, ram, rom)
  • raw PIO format (build.mcu, build.f_cpu, upload.maximum_ram_size, upload.maximum_size)

so project-local PIO board manifests work without an enrich_boards pre-pass.

Tests

6 new tests in tests_project_local.rs cover:

  • project-local hit when bundled misses
  • bundled wins over project-local (precedence)
  • project_dir = None disables the fallback (back-compat with from_board_id)
  • missing file returns unknown-board
  • unparseable JSON returns unknown-board (with a tracing::warn!)
  • from_board_id == from_board_id_in_project(None) (equivalence)

All 77 board module tests pass under soldr cargo test -p fbuild-config board::; workspace builds cleanly under soldr cargo build --workspace --tests --bins.

Reproducer that motivated this

Failing fbuild CI run on the ArduinoCore-LPC8xx side:
https://github.com/zackees/ArduinoCore-LPC8xx/actions/runs/27172681316/job/80214987717

Out of scope

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Projects can now define custom board configurations locally via files in a boards/ directory, providing fallback definitions when built-in board information is unavailable. Built-in configurations take precedence.
  • Tests

    • Added comprehensive test coverage for project-local board configuration resolution behavior.

When the built-in board database has no entry for the requested board
id, fall back to `<project_dir>/boards/<board_id>.json`. This matches
PlatformIO's behavior of auto-discovering project-local board manifests
next to platformio.ini, so well-formed PIO projects that ship a boards/
directory build under fbuild without per-board upstream changes.

Lookup order (fallback-only — bundled wins):
  1. bundled DB                        (compile-time `include_dir!`)
  2. <project_dir>/boards/<id>.json    (NEW — only consulted on miss)

Explicit override of a bundled board via the project-local path is
intentionally NOT supported in this PR. Open a separate FR if needed.

Public API:
  + BoardConfig::from_board_id_in_project(board_id, overrides, project_dir)
    Existing `from_board_id` becomes a thin wrapper that passes None.

  + compile_many internally passes the first sketch's project_dir
    through to platform_for_board, so `fbuild build <dir> -e <env>`
    resolves <dir>/boards/<env_board>.json automatically.

Format handling:
  flatten_board_entry now accepts BOTH enriched (top-level `mcu`,
  `fcpu`, `ram`, `rom`) and PIO-format (`build.mcu`, `build.f_cpu`,
  `upload.maximum_ram_size`, `upload.maximum_size`) JSON so project-
  local PIO board manifests work without an enrichment pre-pass.

Tests:
  6 new tests in `tests_project_local.rs` cover:
   - project-local hit when bundled misses
   - bundled wins over project-local (precedence)
   - project_dir=None disables the fallback
   - missing file returns unknown-board
   - unparseable JSON returns unknown-board (warns)
   - from_board_id == from_board_id_in_project(None)

All 77 board-module tests pass (soldr cargo test); workspace builds.

Closes #515

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0b8db8c9-5122-4688-a665-5db36d9cd003

📥 Commits

Reviewing files that changed from the base of the PR and between e09e056 and 4ae46c9.

📒 Files selected for processing (5)
  • crates/fbuild-build/src/compile_many.rs
  • crates/fbuild-config/src/board/db.rs
  • crates/fbuild-config/src/board/loaders.rs
  • crates/fbuild-config/src/board/mod.rs
  • crates/fbuild-config/src/board/tests_project_local.rs

📝 Walkthrough

Walkthrough

fbuild now discovers and resolves board definitions from project-local boards/<board>.json files as a fallback when the bundled board database lacks an entry. The two-stage lookup is threaded through the board database, BoardConfig API, and compilation pipeline.

Changes

Project-local board resolution

Layer / File(s) Summary
Board database two-stage resolution
crates/fbuild-config/src/board/db.rs
New get_board_defaults_with_project_dir(board_id, project_dir) function checks the embedded board database first, then reads <project_dir>/boards/<board_id>.json as a fallback when available. Refactors JSON parsing into shared flatten_board_entry helper supporting both enriched and PlatformIO JSON formats (top-level and nested build.*/upload.* keys).
BoardConfig API with project directory
crates/fbuild-config/src/board/loaders.rs
from_board_id delegates to new public from_board_id_in_project(board_id, overrides, project_dir) method. Error messages conditionally include the checked project-local path when project_dir is provided.
Compilation pipeline integration
crates/fbuild-build/src/compile_many.rs
platform_for_board accepts project_dir: Option<&Path> and resolves via from_board_id_in_project. compile_many_with extracts project_dir from the first sketch and threads it through board→platform resolution.
Test coverage
crates/fbuild-config/src/board/mod.rs, crates/fbuild-config/src/board/tests_project_local.rs
New tests_project_local module with comprehensive test suite validating fallback behavior, precedence rules, error handling for missing/malformed files, and API equivalence.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • FastLED/fbuild#241: Introduces compile_many board→platform resolution infrastructure that this PR extends to support project-local board discovery.

Poem

🐰 A rabbit hops through project lands,
Finding boards in JSON sands.
No more "unknown"—local files shine,
PlatformIO's path, now fbuild's design!
Happy bundling 🎉

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/project-local-boards

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

fbuild should resolve project-local boards/*.json like PlatformIO does

1 participant