mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-09-22 21:30:44 +02:00
chore: update documentation
This commit is contained in:
@@ -2,12 +2,19 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/**
|
||||
* In-app updates for Tauri applications: check the configured endpoints for a new release,
|
||||
* download it and install it.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
import { invoke, Channel, Resource } from '@tauri-apps/api/core'
|
||||
|
||||
/** Options used when checking for updates */
|
||||
interface CheckOptions {
|
||||
/**
|
||||
* Request headers
|
||||
* The headers to send along with the update check request.
|
||||
*/
|
||||
headers?: HeadersInit
|
||||
/**
|
||||
@@ -27,7 +34,7 @@ interface CheckOptions {
|
||||
/** Options used when downloading an update */
|
||||
interface DownloadOptions {
|
||||
/**
|
||||
* Request headers
|
||||
* The headers to send along with the update download request.
|
||||
*/
|
||||
headers?: HeadersInit
|
||||
/**
|
||||
@@ -59,17 +66,58 @@ type DownloadEvent =
|
||||
| { event: 'Progress'; data: { chunkLength: number } }
|
||||
| { event: 'Finished' }
|
||||
|
||||
/**
|
||||
* An update announced by the update server, as returned by {@linkcode check}.
|
||||
*
|
||||
* It holds a resource on the Rust side, so call {@linkcode Update.close} when you are done with it
|
||||
* without installing it.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Update extends Resource {
|
||||
// TODO: remove this field in v3
|
||||
/** @deprecated This is always true, check if the return value is `null` instead when using {@linkcode check} */
|
||||
/**
|
||||
* Whether an update is available.
|
||||
*
|
||||
* @deprecated This is always true, check if the return value is `null` instead when using {@linkcode check}
|
||||
*/
|
||||
available: boolean
|
||||
/**
|
||||
* The version of the application that is currently running.
|
||||
*/
|
||||
currentVersion: string
|
||||
/**
|
||||
* The version announced by the update server.
|
||||
*/
|
||||
version: string
|
||||
/**
|
||||
* The publish date of the update as an RFC 3339 string, when the server provided one.
|
||||
*/
|
||||
date?: string
|
||||
/**
|
||||
* The release notes of the update, when the server provided them.
|
||||
*/
|
||||
body?: string
|
||||
/**
|
||||
* The raw update manifest returned by the server, useful when it contains
|
||||
* additional fields that the updater itself does not handle.
|
||||
*/
|
||||
rawJson: Record<string, unknown>
|
||||
private downloadedBytes?: Resource
|
||||
|
||||
/**
|
||||
* Creates an update from the metadata returned by the backend.
|
||||
* You should not need to call this yourself, use {@linkcode check} instead.
|
||||
*
|
||||
* @param metadata The update information returned by the backend, including the resource identifier of the update.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { check } from '@tauri-apps/plugin-updater';
|
||||
* // the update instance is created for you by `check`
|
||||
* const update = await check();
|
||||
* ```
|
||||
*/
|
||||
constructor(metadata: UpdateMetadata) {
|
||||
super(metadata.rid)
|
||||
this.available = true
|
||||
@@ -80,7 +128,29 @@ class Update extends Resource {
|
||||
this.rawJson = metadata.rawJson
|
||||
}
|
||||
|
||||
/** Download the updater package. Call {@linkcode install} later to install it */
|
||||
/**
|
||||
* Downloads the updater package. Call {@linkcode install} later to install it.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { check } from '@tauri-apps/plugin-updater';
|
||||
*
|
||||
* const update = await check();
|
||||
* if (update) {
|
||||
* let downloaded = 0;
|
||||
* await update.download((event) => {
|
||||
* if (event.event === 'Progress') {
|
||||
* downloaded += event.data.chunkLength;
|
||||
* console.log(`downloaded ${downloaded} bytes`);
|
||||
* }
|
||||
* });
|
||||
* await update.install();
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param onEvent Callback invoked with a `Started` event when the first chunk is received, a `Progress` event for every downloaded chunk and a `Finished` event when the download completes.
|
||||
* @param options The headers and the timeout to use for the download request.
|
||||
*/
|
||||
async download(
|
||||
onEvent?: (progress: DownloadEvent) => void,
|
||||
options?: DownloadOptions
|
||||
@@ -105,6 +175,19 @@ class Update extends Resource {
|
||||
*
|
||||
* - **Windows:** This function exits the app after launching the updater installer successfully
|
||||
* - **macOS / Linux:** You need to relaunch the app to run the newly install version
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { check } from '@tauri-apps/plugin-updater';
|
||||
*
|
||||
* const update = await check();
|
||||
* if (update) {
|
||||
* await update.download();
|
||||
* await update.install();
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param options Options for the installation, such as whether the Windows installer should restart the app afterwards.
|
||||
*/
|
||||
async install(options?: InstallOptions): Promise<void> {
|
||||
if (!this.downloadedBytes) {
|
||||
@@ -128,6 +211,21 @@ class Update extends Resource {
|
||||
*
|
||||
* - **Windows:** This function exits the app after launching the updater installer successfully
|
||||
* - **macOS / Linux:** You need to relaunch the app to run the newly install version
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { check } from '@tauri-apps/plugin-updater';
|
||||
*
|
||||
* const update = await check();
|
||||
* if (update) {
|
||||
* await update.downloadAndInstall((event) => {
|
||||
* console.log(event.event);
|
||||
* });
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param onEvent Callback invoked with a `Started` event when the first chunk is received, a `Progress` event for every downloaded chunk and a `Finished` event when the download completes.
|
||||
* @param options The headers and the timeout to use for the download request, and the installation options.
|
||||
*/
|
||||
async downloadAndInstall(
|
||||
onEvent?: (progress: DownloadEvent) => void,
|
||||
@@ -145,13 +243,45 @@ class Update extends Resource {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the update resource and the downloaded bytes held by the backend.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { check } from '@tauri-apps/plugin-updater';
|
||||
*
|
||||
* const update = await check();
|
||||
* if (update) {
|
||||
* await update.close();
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
async close(): Promise<void> {
|
||||
await this.downloadedBytes?.close()
|
||||
await super.close()
|
||||
}
|
||||
}
|
||||
|
||||
/** Check for updates, resolves to `null` if no updates are available */
|
||||
/**
|
||||
* Checks the configured endpoints for an available update.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { check } from '@tauri-apps/plugin-updater';
|
||||
*
|
||||
* const update = await check();
|
||||
* if (update) {
|
||||
* console.log(`update ${update.version} is available`);
|
||||
* await update.downloadAndInstall();
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param options The headers, timeout, proxy and target to use for the update check request.
|
||||
*
|
||||
* @returns A promise resolving to the available {@linkcode Update}, or `null` when no update is available.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
async function check(options?: CheckOptions): Promise<Update | null> {
|
||||
convertToRustHeaders(options)
|
||||
|
||||
|
||||
@@ -66,24 +66,35 @@ pub enum Error {
|
||||
/// Temp dir is not on same mount mount. This prevents our updater to rename the AppImage to a temp file.
|
||||
#[error("temp directory is not on the same mount point as the AppImage")]
|
||||
TempDirNotOnSameMountPoint,
|
||||
/// The downloaded archive does not contain a binary for the current target.
|
||||
#[error("binary for the current target not found in the archive")]
|
||||
BinaryNotFoundInArchive,
|
||||
/// Could not create a temporary directory to store the downloaded update.
|
||||
#[error("failed to create temporary directory")]
|
||||
TempDirNotFound,
|
||||
/// The privilege escalation prompt shown before installing a Linux package
|
||||
/// failed or was dismissed by the user.
|
||||
#[error("Authentication failed or was cancelled")]
|
||||
AuthenticationFailed,
|
||||
/// Installing the downloaded `.deb` package failed.
|
||||
#[error("Failed to install .deb package")]
|
||||
DebInstallFailed,
|
||||
/// The package manager could not install the downloaded Linux package.
|
||||
#[error("Failed to install package")]
|
||||
PackageInstallFailed,
|
||||
/// The downloaded update is not in a format the updater can install on the current platform.
|
||||
#[error("invalid updater binary format")]
|
||||
InvalidUpdaterFormat,
|
||||
/// `http` crate errors.
|
||||
#[error(transparent)]
|
||||
Http(#[from] http::Error),
|
||||
/// A request header value is not valid.
|
||||
#[error(transparent)]
|
||||
InvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
|
||||
/// A request header name is not valid.
|
||||
#[error(transparent)]
|
||||
InvalidHeaderName(#[from] http::header::InvalidHeaderName),
|
||||
/// The release publish date could not be formatted as an RFC 3339 string.
|
||||
#[error("Failed to format date")]
|
||||
FormatDate,
|
||||
/// The configured updater endpoint must use a secure protocol like `https`
|
||||
@@ -105,6 +116,7 @@ pub enum Error {
|
||||
"The update signature does not specify the version it was signed for, which `requireSignedVersion` requires. Re-sign and re-publish this release, or disable `requireSignedVersion`."
|
||||
)]
|
||||
MissingSignedVersion,
|
||||
/// Tauri errors.
|
||||
#[error(transparent)]
|
||||
Tauri(#[from] tauri::Error),
|
||||
}
|
||||
@@ -118,4 +130,5 @@ impl Serialize for Error {
|
||||
}
|
||||
}
|
||||
|
||||
/// A [`Result`](std::result::Result) alias whose error type is the updater [`Error`](enum@Error).
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
@@ -137,6 +137,21 @@ struct UpdaterState {
|
||||
headers: HeaderMap,
|
||||
}
|
||||
|
||||
/// Builder for the updater plugin.
|
||||
///
|
||||
/// The values set here are the defaults used by every [`Updater`] created through
|
||||
/// [`UpdaterExt::updater`] and [`UpdaterExt::updater_builder`]; they can still be overridden
|
||||
/// per updater instance on the [`UpdaterBuilder`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tauri::Runtime;
|
||||
///
|
||||
/// fn register_updater<R: Runtime>(builder: tauri::Builder<R>) -> tauri::Builder<R> {
|
||||
/// builder.plugin(tauri_plugin_updater::Builder::new().build())
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Default)]
|
||||
pub struct Builder {
|
||||
target: Option<String>,
|
||||
@@ -147,15 +162,26 @@ pub struct Builder {
|
||||
}
|
||||
|
||||
impl Builder {
|
||||
/// Creates a new builder with the default configuration.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Sets the target name used when checking for updates.
|
||||
///
|
||||
/// It replaces the `{{target}}` variable in the endpoint URLs and is used as the key to look
|
||||
/// up the release in the `platforms` object of a static update manifest.
|
||||
///
|
||||
/// When it is not set, the updater uses the current operating system name (`linux`, `darwin`
|
||||
/// or `windows`) in the endpoint URLs and looks for `{os}-{arch}-{bundle_type}` then
|
||||
/// `{os}-{arch}` in the manifest.
|
||||
pub fn target(mut self, target: impl Into<String>) -> Self {
|
||||
self.target.replace(target.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the public key used to verify the update signature,
|
||||
/// overriding the `pubkey` value of the plugin configuration.
|
||||
pub fn pubkey<S: Into<String>>(mut self, pubkey: S) -> Self {
|
||||
self.pubkey.replace(pubkey.into());
|
||||
self
|
||||
@@ -189,6 +215,11 @@ impl Builder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a header to be sent on every updater request.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the header name or the header value is not valid.
|
||||
pub fn header<K, V>(mut self, key: K, value: V) -> Result<Self>
|
||||
where
|
||||
HeaderName: TryFrom<K>,
|
||||
@@ -204,11 +235,22 @@ impl Builder {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Replaces all the headers sent on updater requests with the given map,
|
||||
/// discarding the ones previously added with [`Self::header`].
|
||||
pub fn headers(mut self, headers: HeaderMap) -> Self {
|
||||
self.headers = headers;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the default function used to decide whether a remote release should be installed.
|
||||
///
|
||||
/// The closure receives the current application version and the remote release,
|
||||
/// and must return `true` when the release should be treated as an update.
|
||||
///
|
||||
/// It applies to every updater created through [`UpdaterExt`] and takes precedence over the
|
||||
/// `allowDowngrades` configuration value; it can still be overridden per updater instance with
|
||||
/// [`UpdaterBuilder::version_comparator`]. When no comparator is set at all, a release is
|
||||
/// installed only if its version is greater than the current one.
|
||||
pub fn default_version_comparator<
|
||||
F: Fn(Version, RemoteRelease) -> bool + Send + Sync + 'static,
|
||||
>(
|
||||
@@ -219,6 +261,10 @@ impl Builder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Builds the updater plugin, registering the `check`, `download`, `install`
|
||||
/// and `download_and_install` commands used by the JavaScript API.
|
||||
///
|
||||
/// Pass the returned plugin to [`tauri::Builder::plugin`].
|
||||
pub fn build<R: Runtime>(self) -> TauriPlugin<R, Config> {
|
||||
let pubkey = self.pubkey;
|
||||
let target = self.target;
|
||||
|
||||
@@ -43,15 +43,26 @@ use crate::{
|
||||
|
||||
const UPDATER_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"),);
|
||||
|
||||
/// The kind of bundle the running application was installed from.
|
||||
///
|
||||
/// Its name is appended to the updater target string (`{os}-{arch}-{bundle_type}`) when looking
|
||||
/// up the release in the update manifest and replaces the `{{bundle_type}}` variable in the
|
||||
/// endpoint URLs.
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Installer {
|
||||
/// Linux AppImage bundle, named `appimage`.
|
||||
AppImage,
|
||||
/// Debian package, named `deb`.
|
||||
Deb,
|
||||
/// RPM package, named `rpm`.
|
||||
Rpm,
|
||||
|
||||
/// macOS application bundle, named `app`. Also used for applications distributed as DMG.
|
||||
App,
|
||||
|
||||
/// Windows WiX (MSI) installer, named `msi`.
|
||||
Msi,
|
||||
/// Windows NSIS installer, named `nsis`.
|
||||
Nsis,
|
||||
}
|
||||
|
||||
@@ -68,6 +79,7 @@ impl Installer {
|
||||
}
|
||||
}
|
||||
|
||||
/// The update information of a single platform in the update manifest.
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct ReleaseManifestPlatform {
|
||||
/// Download URL for the platform
|
||||
@@ -76,11 +88,18 @@ pub struct ReleaseManifestPlatform {
|
||||
pub signature: String,
|
||||
}
|
||||
|
||||
/// The platform specific data of a [`RemoteRelease`], in either of the two supported shapes.
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[serde(untagged)]
|
||||
pub enum RemoteReleaseInner {
|
||||
/// Server Format: the endpoint resolved the platform itself and returned a single
|
||||
/// download URL and signature.
|
||||
Dynamic(ReleaseManifestPlatform),
|
||||
/// Static Format: the manifest describes every platform it supports and the updater
|
||||
/// picks the entry matching the current target.
|
||||
Static {
|
||||
/// Update information for each platform, keyed by the updater target string
|
||||
/// (e.g. `darwin-aarch64`).
|
||||
platforms: HashMap<String, ReleaseManifestPlatform>,
|
||||
},
|
||||
}
|
||||
@@ -126,8 +145,16 @@ impl RemoteRelease {
|
||||
}
|
||||
}
|
||||
|
||||
/// Function executed right before the Windows installer is spawned and the app exits.
|
||||
/// See [`UpdaterBuilder::on_before_exit`].
|
||||
pub type OnBeforeExit = Arc<dyn Fn() + Send + Sync + 'static>;
|
||||
/// Function that customizes the `reqwest` client builder used for the updater requests.
|
||||
/// See [`UpdaterBuilder::configure_client`].
|
||||
pub type OnBeforeRequest = Arc<dyn Fn(ClientBuilder) -> ClientBuilder + Send + Sync + 'static>;
|
||||
/// Function that decides whether a remote release must be installed.
|
||||
///
|
||||
/// It receives the current application version and the remote release,
|
||||
/// and returns `true` when the release should be treated as an update.
|
||||
pub type VersionComparator = Arc<dyn Fn(Version, RemoteRelease) -> bool + Send + Sync>;
|
||||
#[cfg(target_os = "macos")]
|
||||
type MainThreadClosure = Box<dyn FnOnce() + Send + Sync + 'static>;
|
||||
@@ -155,6 +182,10 @@ struct UpdaterContext {
|
||||
restart_after_install: bool,
|
||||
}
|
||||
|
||||
/// Builder for an [`Updater`] instance.
|
||||
///
|
||||
/// Get one from [`crate::UpdaterExt::updater_builder`], which pre-fills it with the plugin
|
||||
/// configuration, then call [`UpdaterBuilder::build`].
|
||||
pub struct UpdaterBuilder {
|
||||
current_version: Version,
|
||||
pub(crate) version_comparator: Option<VersionComparator>,
|
||||
@@ -208,6 +239,12 @@ impl UpdaterBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the function used to decide whether the remote release must be installed,
|
||||
/// replacing the comparator set with [`crate::Builder::default_version_comparator`]
|
||||
/// and the behavior of the `allowDowngrades` configuration value.
|
||||
///
|
||||
/// When no comparator is set, a release is only installed if its version is greater
|
||||
/// than the current application version.
|
||||
pub fn version_comparator<F: Fn(Version, RemoteRelease) -> bool + Send + Sync + 'static>(
|
||||
mut self,
|
||||
f: F,
|
||||
@@ -216,11 +253,29 @@ impl UpdaterBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the target name used when checking for updates.
|
||||
///
|
||||
/// It replaces the `{{target}}` variable in the endpoint URLs and is used as the key to look
|
||||
/// up the release in the `platforms` object of a static update manifest.
|
||||
///
|
||||
/// When it is not set, the updater uses the current operating system name (`linux`, `darwin`
|
||||
/// or `windows`) in the endpoint URLs and looks for `{os}-{arch}-{bundle_type}` then
|
||||
/// `{os}-{arch}` in the manifest.
|
||||
pub fn target(mut self, target: impl Into<String>) -> Self {
|
||||
self.target.replace(target.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the endpoints to fetch the update manifest from,
|
||||
/// overriding the `endpoints` configuration value.
|
||||
///
|
||||
/// They are checked in order and the first one that returns a valid release wins.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns [`Error::InsecureTransportProtocol`] on release builds if an endpoint does not use
|
||||
/// the `https` protocol and the `dangerousInsecureTransportProtocol` configuration value is
|
||||
/// not enabled. On debug builds a warning is printed instead.
|
||||
pub fn endpoints(mut self, endpoints: Vec<Url>) -> Result<Self> {
|
||||
crate::config::validate_endpoints(
|
||||
&endpoints,
|
||||
@@ -231,11 +286,19 @@ impl UpdaterBuilder {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Sets the path of the application executable, which is used to determine where the update
|
||||
/// must be installed. Defaults to the path of the current executable, or to the AppImage path
|
||||
/// when the application runs as an AppImage.
|
||||
pub fn executable_path<P: AsRef<Path>>(mut self, p: P) -> Self {
|
||||
self.executable_path.replace(p.as_ref().into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a header to be sent on the update check and download requests.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the header name or the header value is not valid.
|
||||
pub fn header<K, V>(mut self, key: K, value: V) -> Result<Self>
|
||||
where
|
||||
HeaderName: TryFrom<K>,
|
||||
@@ -251,21 +314,28 @@ impl UpdaterBuilder {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Replaces all the headers sent on the update check and download requests with the given map,
|
||||
/// discarding the ones previously added with [`Self::header`].
|
||||
pub fn headers(mut self, headers: HeaderMap) -> Self {
|
||||
self.headers = headers;
|
||||
self
|
||||
}
|
||||
|
||||
/// Removes all the headers previously set on this builder.
|
||||
pub fn clear_headers(mut self) -> Self {
|
||||
self.headers.clear();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the timeout of the update check and download requests.
|
||||
/// When it is not set, the requests do not time out.
|
||||
pub fn timeout(mut self, timeout: Duration) -> Self {
|
||||
self.timeout = Some(timeout);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the proxy used for the update check and download requests.
|
||||
/// It is ignored when [`Self::no_proxy`] was called.
|
||||
pub fn proxy(mut self, proxy: Url) -> Self {
|
||||
self.proxy.replace(proxy);
|
||||
self
|
||||
@@ -277,6 +347,8 @@ impl UpdaterBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the public key used to verify the update signature,
|
||||
/// overriding the `pubkey` value of the plugin configuration.
|
||||
pub fn pubkey<S: Into<String>>(mut self, pubkey: S) -> Self {
|
||||
self.context.config.pubkey = pubkey.into();
|
||||
self
|
||||
@@ -362,6 +434,15 @@ impl UpdaterBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Builds the [`Updater`].
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// - [`Error::EmptyEndpoints`]: neither [`Self::endpoints`] nor the `endpoints`
|
||||
/// configuration value provided an endpoint to check.
|
||||
/// - [`Error::UnsupportedArch`]: the updater does not support the current architecture.
|
||||
/// - [`Error::FailedToDetermineExtractPath`]: the install directory could not be resolved
|
||||
/// from the executable path.
|
||||
pub fn build(self) -> Result<Updater> {
|
||||
let endpoints = self
|
||||
.endpoints
|
||||
@@ -412,6 +493,9 @@ impl UpdaterBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks the configured endpoints for an application update.
|
||||
///
|
||||
/// Get one from [`crate::UpdaterExt::updater`] or by calling [`UpdaterBuilder::build`].
|
||||
pub struct Updater {
|
||||
current_version: Version,
|
||||
version_comparator: Option<VersionComparator>,
|
||||
@@ -429,6 +513,25 @@ pub struct Updater {
|
||||
}
|
||||
|
||||
impl Updater {
|
||||
/// Checks the endpoints for an update, returning the first release that the version
|
||||
/// comparator accepts.
|
||||
///
|
||||
/// Each endpoint is requested in order, with the `{{current_version}}`, `{{target}}`,
|
||||
/// `{{arch}}` and `{{bundle_type}}` variables replaced in its URL, until one of them
|
||||
/// answers with a release manifest the updater can parse.
|
||||
///
|
||||
/// Resolves to `None` when an endpoint replies with `204 No Content` or when the release it
|
||||
/// announced is not considered an update - by default when its version is not greater than the
|
||||
/// current application version.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// - [`Error::UnsupportedOs`]: no target was set and the updater does not support the
|
||||
/// current operating system.
|
||||
/// - [`Error::ReleaseNotFound`]: no endpoint returned a release manifest.
|
||||
/// - The last request or deserialization error when every endpoint failed.
|
||||
/// - [`Error::TargetNotFound`] or [`Error::TargetsNotFound`]: the manifest has no entry
|
||||
/// for the current target.
|
||||
pub async fn check(&self) -> Result<Option<Update>> {
|
||||
// we want JSON only
|
||||
let mut headers = self.headers.clone();
|
||||
@@ -638,6 +741,10 @@ impl Updater {
|
||||
}
|
||||
}
|
||||
|
||||
/// An update announced by the remote server, returned by [`Updater::check`].
|
||||
///
|
||||
/// Use [`Update::download`] followed by [`Update::install`], or [`Update::download_and_install`],
|
||||
/// to apply it.
|
||||
#[derive(Clone)]
|
||||
pub struct Update {
|
||||
/// Update description
|
||||
@@ -1427,6 +1534,14 @@ fn updater_arch() -> Option<&'static str> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves the path the update must be installed to from the path of the application executable.
|
||||
///
|
||||
/// This is the directory holding the executable, except on macOS where the `.app` bundle path is
|
||||
/// returned for executables living in `Contents/MacOS`.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns [`Error::FailedToDetermineExtractPath`] when the path has no parent directory.
|
||||
pub fn extract_path_from_executable(executable_path: &Path) -> Result<PathBuf> {
|
||||
// Return the path of the current executable by default
|
||||
// Example C:\Program Files\My App\
|
||||
|
||||
Reference in New Issue
Block a user