From 4c8c557e7b5d9b80ffb8b21f6d3b9960ee281ee1 Mon Sep 17 00:00:00 2001 From: Julien Calixte Date: Sat, 11 Jul 2026 12:39:24 +0200 Subject: [PATCH] feat(firmware): gate :sync publish behind the git feature Route :sync through publish(), whose git-push path is #[cfg(feature = "git")]. Git code in the firmware binary is now only ever compiled with --features git, so the default build stays a light editor build with no git2 crate and (since the justfile only sets LIBGIT2_SRC for git recipes) no libgit2 component. Feature is off by default; :sync saves locally. --- firmware/Cargo.toml | 13 +++++++++---- firmware/src/main.rs | 43 +++++++++++++++++++++++++++++++------------ 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/firmware/Cargo.toml b/firmware/Cargo.toml index 3516372..eef300d 100644 --- a/firmware/Cargo.toml +++ b/firmware/Cargo.toml @@ -76,10 +76,15 @@ esp-idf-hal = { git = "https://github.com/esp-rs/esp-idf-hal.git" } esp-idf-svc = { git = "https://github.com/esp-rs/esp-idf-svc.git" } [features] -# Pulls the git2 safe API. libgit2 itself is built by the esp-idf component -# (firmware/components/libgit2/) with mbedTLS; git2/libgit2-sys are used in -# system mode (LIBGIT2_NO_VENDOR=1) purely for the Rust bindings, so we disable -# their default features to avoid dragging in openssl-sys/libssh2-sys. +# OFF by default so the nominal `just build`/`just flash` is a LIGHT editor +# build. Enabling it (a) pulls the git2 safe API and (b) gates on the firmware's +# `:sync` publish path in main.rs (see `publish()`), so git code is only ever +# compiled with `--features git`. libgit2 itself is built by the esp-idf +# component (firmware/components/libgit2/) with mbedTLS — but ONLY when the +# justfile also sets LIBGIT2_SRC (the git recipes do; the light recipes don't, +# so the component is an empty no-op). git2/libgit2-sys run in system mode +# (LIBGIT2_NO_VENDOR=1) purely for the Rust bindings, with default features off +# to avoid dragging in openssl-sys/libssh2-sys. git = ["dep:git2"] [dependencies] diff --git a/firmware/src/main.rs b/firmware/src/main.rs index 5c9b73e..8c12beb 100644 --- a/firmware/src/main.rs +++ b/firmware/src/main.rs @@ -99,21 +99,13 @@ fn main() -> anyhow::Result<()> { } // Carry out any host-side effect a `:` command asked for. The SD save is - // wired (fast, inline). The git-push half of `:sync` is not yet: it must - // run off this task on a dedicated git thread with on-demand Wi-Fi (see - // src/bin/git_sync.rs for the persistent-clone push, git_push.rs for the - // TLS trust store), which is its own integration step — for now `:sync` - // saves and logs that push is pending. + // wired (fast, inline). Publishing (`:sync` → git push) lives behind the + // `git` Cargo feature via `publish()`, so the default light build carries + // no libgit2 / git2 at all — see the note on `publish`. match effect { Effect::None => {} Effect::Save => save_note(&storage, &ed), - Effect::Publish => { - save_note(&storage, &ed); - log::info!( - ":sync — note saved; git push not wired yet (needs git_sync \ - graduated into a module + on-demand Wi-Fi on the git thread)" - ); - } + Effect::Publish => publish(&storage, &ed), } // Keyboard attach/detach feeds the panel's disconnect flag. @@ -263,6 +255,33 @@ fn save_note(storage: &Storage, ed: &Editor) { } } +/// `:sync` — persist, then publish. Publishing (git push) is gated behind the +/// `git` Cargo feature so the default build stays a **light editor build**: no +/// `git2` crate and, because the justfile only sets `LIBGIT2_SRC` for git +/// recipes, no libgit2/mbedTLS component either (`just build`/`just flash`). +/// A full build turns both on together: `just flash-firmware-git`. +/// +/// This is the seam that keeps the light build light — the git-only code path +/// is only ever compiled under `--features git`, so an ordinary `:sync` in the +/// light build simply saves locally. +fn publish(storage: &Storage, ed: &Editor) { + // Publishing an unsaved buffer is meaningless, so save first in both builds. + save_note(storage, ed); + + #[cfg(feature = "git")] + { + // TODO(v0.1): signal the dedicated git thread here (channel, not an + // inline blocking push) once `git_sync` is graduated from its spike bin + // into a module. The feature is on but that integration hasn't landed, + // so for now this still just saves. + log::info!(":sync — saved; `git` feature ON, but the publish module isn't wired yet"); + } + #[cfg(not(feature = "git"))] + { + log::info!(":sync — saved; built without the `git` feature (light build) — push skipped"); + } +} + /// First and last (inclusive) framebuffer rows that differ between two frames, /// or `None` if identical. Lets the partial refresh target just the band a /// keystroke touched instead of all 272 rows.