Files
shorebird-updater/CLAUDE.md
T
Eric Seidel a6f84469f6 docs: add CLAUDE.md for Claude Code context (#324)
* docs: add CLAUDE.md for Claude Code context

* docs: remove boilerplate header from CLAUDE.md
2026-04-01 19:58:49 -07:00

2.6 KiB

What This Is

Shorebird's updater library — a Rust core that gets linked into Flutter Engine (libflutter.so) as a static C library to enable over-the-air code push for Flutter apps. The Dart package (shorebird_code_push) calls into it via FFI.

Build & Test

# Rust (from workspace root or individual crate dir)
cargo build --verbose
cargo test
cargo llvm-cov --lcov --output-path lcov.info   # tests + coverage (CI uses this)
# Prerequisites for coverage: rustup component add llvm-tools-preview && cargo install cargo-llvm-cov

# Dart package
cd shorebird_code_push
flutter pub get
flutter test --coverage
dart format --set-exit-if-changed .
dart analyze --fatal-warnings lib test

Rust tests that call shorebird_init must run single-threaded — use the #[serial] attribute from serial_test. The global static config means concurrent shorebird_init calls stomp each other, so any test that touches init needs #[serial].

Workspace Layout

Cargo workspace with two members: library (core updater) and patch (CLI tool for packaging patches). The Dart FFI package lives in shorebird_code_push/.

Architecture (library/)

Layers from outside in:

  1. C API (c_api/mod.rs) — stable C interface consumed by Flutter Engine; thin wrapper around Rust API. c_file.rs provides a read-seek interface for iOS patch files.
  2. Rust API (updater.rs, re-exported from lib.rs) — core logic including the boot state machine and patch check/update state machines.
  3. Cache (cache/) — on-disk state via patches_state.json. updater_state.rs is the public API; patch_manager.rs manages patch files; signing.rs handles cryptographic verification.
  4. Network (network.rs) — server communication for patch checks and downloads.
  5. Platform (android.rs, logging.rs) — platform-specific integration (Android logcat, iOS oslog, etc.).

Thread safety: global config object with locking, since it's called from both flutter_main thread (init) and Dart/UI thread (updates).

Design principle: "fail open" — always fall back to the currently installed version; never leave the app in a broken state.

Key Details

  • C header (include/updater.h) is auto-generated by cbindgen via build.rs — don't edit manually.
  • Dart FFI bindings (updater_bindings.g.dart) are generated by ffigen — don't edit manually.
  • Library builds as three crate types: lib (Rust tests), cdylib (Dart FFI testing), staticlib (engine linking).
  • Boot state machine docs: docs/boot_state_machine.md.
  • CI requires semantic PR titles (conventional commits style).