whisker_cng/lib.rs
1//! Whisker CNG (Continuous Native Generation).
2//!
3//! Renders the Android / iOS host projects under `gen/{android,ios}/`
4//! from the user's `whisker.rs` (= [`whisker_config::Config`]).
5//! Drift between the in-tree files and the current config is detected
6//! via a content-hashed fingerprint stored alongside each generated
7//! tree (`gen/<platform>/.whisker-fingerprint`).
8//!
9//! Modelled on Expo's CNG: the source of truth is the declarative
10//! config, the platforms directory are build artifacts (never
11//! committed). Unlike Expo, regeneration is *implicit* — there's no
12//! separate `whisker generate` command. Whichever command needs the
13//! native tree (today: `whisker run`) calls
14//! [`sync_android`] / [`sync_ios`] first; the fast path (fingerprint
15//! match) is a single file read and returns instantly.
16//!
17//! ## Public entry points
18//!
19//! - [`sync_android`] / [`sync_ios`] — render-or-skip for one
20//! platform. Returns whether files were actually rewritten.
21//! - [`AndroidInputs`] / [`IosInputs`] — the renderer's input bundle.
22//! Build them yourself for full control, or use
23//! [`android::inputs_from`] / [`ios::inputs_from`] for the
24//! "extract from Config + defaults" path.
25//!
26//! The crate has no CLI surface and shells out to nothing —
27//! `whisker-cli` is responsible for running `xcodegen`, `gradle`, etc.
28//! after a sync completes. Keeping side-effects out of the renderer
29//! makes it cheap to unit-test against tempdirs.
30
31pub mod android;
32pub mod compose;
33pub mod discovery;
34mod fingerprint;
35pub mod ios;
36pub mod plugins;
37mod render;
38
39pub use android::{sync as sync_android, AndroidInputs};
40pub use compose::{EnabledTargets, Engine, SubprocessPlugin};
41pub use discovery::{discover_plugins, DiscoveredPlugin};
42pub use ios::{sync as sync_ios, IosInputs};
43pub use whisker_config::Config;