Skip to main content

self_update_extras/
lib.rs

1//! Self-updating support for CLI binaries.
2//!
3//! This crate provides composable wrappers around any type implementing
4//! [`self_update::update::ReleaseUpdate`], each exposed through a builder in
5//! the style of `self_update`'s own backends:
6//!
7//! - [`throttle::Update`] limits how often update checks run by recording the
8//!   time of the last check in a throttle file in the system temp directory.
9//! - [`restart::Update`] re-executes the process with the freshly installed
10//!   binary after a successful update, using a guard environment variable to
11//!   prevent restart loops.
12//! - [`silence::Update`] redirects the wrapped update's standard output (fd 1)
13//!   to either standard error or `/dev/null` while it runs, then restores it,
14//!   keeping a headless update from polluting a stdio stream a parent process
15//!   is monitoring (for example, a stdio-based MCP server).
16//!
17//! Both wrappers implement `ReleaseUpdate` themselves and their builders
18//! produce a `Box<dyn ReleaseUpdate>`, so they can be layered over a backend
19//! (or over each other) and used anywhere a `ReleaseUpdate` is expected.
20//!
21//! # Example
22//!
23//! ```ignore
24//! use self_update_extras::{restart, silence, throttle};
25//! use self_update::backends::github;
26//! use self_update::update::ReleaseUpdate;
27//! use std::time::Duration;
28//!
29//! // Any `ReleaseUpdate` implementation, e.g. a self_update GitHub backend.
30//! let backend = github::Update::configure().build()?;
31//!
32//! // `silence` sits closest to the backend so it diverts exactly the noisy
33//! // download/install output, and stays *inside* `restart` so the re-executed
34//! // process inherits the real stdout.
35//! let quiet = silence::Update::configure()
36//!     .release_update(backend)
37//!     .sink(silence::Sink::Null)
38//!     .build()?;
39//!
40//! let throttled = throttle::Update::configure()
41//!     .release_update(quiet)
42//!     .throttle_window(Duration::from_secs(15 * 60))
43//!     .build()?;
44//!
45//! let updater = restart::Update::configure()
46//!     .release_update(throttled)
47//!     .guard_env("MY_APP_AUTO_UPDATED")
48//!     .build()?;
49//!
50//! let status = updater.update()?;
51//! ```
52
53pub mod restart;
54pub mod silence;
55pub mod throttle;
56
57#[cfg(test)]
58mod test_support;