gpui_updater_core/lib.rs
1//! Blocking cross-platform self-update, hosted on GitHub Releases, static JSON
2//! manifests, or Sparkle appcasts. This core has no GPUI dependencies.
3//!
4//! GPUI ships no updater of its own, and Zed's `auto_update` is GPL-licensed and
5//! wired to Zed's private update server. This crate is an independent, MIT/Apache
6//! implementation of the same idea: a small state machine that checks a release
7//! source, downloads the platform artifact, verifies it, and swaps it into place.
8//!
9//! # Layers
10//!
11//! - [`UpdateSource`] — where releases come from. [`GitHubSource`],
12//! [`StaticManifestSource`], and [`AppcastSource`] are built in.
13//! - [`UpdateEngine`] — the blocking pipeline: [`check`](UpdateEngine::check) →
14//! [`download`](UpdateEngine::download) (with SHA-256, minisign, and
15//! Sparkle-compatible Ed25519 verification) → [`install`](UpdateEngine::install).
16//! - [`install`] / [`verify`] — the platform install strategies and integrity
17//! checks, usable on their own.
18//! - [`UpdateDriver`] — the contract for handing the whole flow to an external
19//! updater instead of the engine; `gpui-updater-sparkle` implements it with
20//! Sparkle on macOS.
21//! - `delta` (behind the `delta` feature) — binary delta updates: create a
22//! per-file bsdiff delta in release CI, and let the engine rebuild the new
23//! version from the installed one, falling back to the full download on any
24//! problem.
25//! - [`UpdateStatus`] — backend-independent state used by the separate
26//! `gpui-updater` (official GPUI) and `gpui-updater-pre` adapters, whichever
27//! backend (engine or driver) they run.
28//!
29//! # Guides
30//!
31//! | Topic | Page |
32//! | --- | --- |
33//! | Choosing a source, the static manifest format, appcasts, proxies and request headers | [`source`] |
34//! | Verification and trust: transport, the checks, policies, key rotation, signed manifests | [`verify`] |
35//! | Install strategies, the install location check, installs a package manager owns, platform notes | [`install`] |
36//! | Delta updates: enabling, generating, publishing, measurements (feature `delta`) | [delta module](delta/index.html) |
37//! | Error kinds and what to show the user | [`ErrorKind`] |
38//! | Status values for a user interface | [`UpdateStatus`] |
39//!
40//! For a GPUI app, start with the `gpui-updater` or `gpui-updater-pre` crate,
41//! which wraps the engine in an observable entity.
42//!
43//! # Example (blocking engine)
44//!
45//! ```no_run
46//! use gpui_updater_core::{EngineConfig, GitHubSource, UpdateEngine};
47//! use semver::Version;
48//!
49//! let source = GitHubSource::new("AprilNEA", "OpenLogi")
50//! .asset_contains("macos")
51//! .asset_contains(".dmg")
52//! .with_checksums("SHA256SUMS")
53//! .with_minisig();
54//!
55//! let engine = UpdateEngine::new(
56//! source,
57//! EngineConfig::new(Version::parse(env!("CARGO_PKG_VERSION")).unwrap())
58//! .minisign_public_key("RWQ…"),
59//! );
60//!
61//! if let Some(release) = engine.check()? {
62//! let artifact = engine.download(&release, |done, total| {
63//! if let Some(total) = total {
64//! eprintln!("{done}/{total}");
65//! }
66//! })?;
67//! engine.install(&artifact)?;
68//! }
69//! # Ok::<_, gpui_updater_core::Error>(())
70//! ```
71//!
72//! [GPUI]: https://www.gpui.rs/
73
74// Panicking on failure is the point of a test assertion.
75#![cfg_attr(docsrs, feature(doc_cfg))]
76#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used))]
77
78mod cancel;
79mod engine;
80mod error;
81mod http;
82mod release;
83mod staging;
84mod status;
85
86#[cfg(feature = "delta")]
87pub mod delta;
88pub mod driver;
89pub mod install;
90pub mod manifest;
91pub mod source;
92pub mod verify;
93
94pub use cancel::CancelToken;
95pub use driver::{DriverEvent, DriverEvents, UpdateDriver};
96pub use engine::{
97 Artifact, BundleVersion, CodeSigning, DEFAULT_MAX_DELTA_HOPS, DEFAULT_MAX_DOWNLOAD_SIZE,
98 EngineConfig, UpdateEngine, Verification, VersionBinding,
99};
100pub use error::{Error, ErrorKind, Result};
101pub use http::HttpOptions;
102pub use install::{
103 InstallOptions, Installed, MsiUi, Ownership, OwnershipHints, PackageManager,
104 current_install_root,
105};
106pub use release::{
107 Asset, DELTA_FORMAT_FILES_BSDIFF_V1, DeltaAsset, Release, parse_tag, parse_version_lenient,
108};
109/// Re-exported so consumers can build an [`EngineConfig`] without depending on
110/// `semver` directly (e.g. `Version::parse(env!("CARGO_PKG_VERSION"))`).
111pub use semver::Version;
112pub use source::{
113 AppcastSource, AppcastVersion, FallbackSource, GitHubSource, StaticManifestSource, UpdateSource,
114};
115pub use status::{UpdateError, UpdateStatus};