## 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 ```bash # 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 headers (`include/updater_dart.h` for the ffigen-consumed Dart-stable surface, `include/updater_engine.h` for the engine-internal surface) are auto-generated by `cbindgen` via `build.rs` — don't edit manually. The two configs live at `library/cbindgen_dart.toml` and `library/cbindgen_engine.toml`. - 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).