mirror of
https://github.com/storytold/craft-launcher.git
synced 2026-11-07 19:05:37 +00:00
* refactor: delegate self_update to craft-update * ci: point craft-update patch to dylanmtaylor/craft-libs branch * nix: set allowBuiltinFetchGit for git dependencies * chore(deps): update craft-update commit * build: pin craft-update to storytold/craft-libs fe61243 and drop the temporary patch * fix(update): share craft_update::Stop so pause and cancel reach the self-update * build: pin craft-update to the dirs-free, zip 9 build Satisfies cargo-deny: no MPL-2.0 option-ext, no zip 8 advisories, and a versioned git dependency instead of a wildcard. * build: pin craft-update to craft-libs main (b9ba47f)
134 lines
4.9 KiB
Rust
134 lines
4.9 KiB
Rust
//! ArtCraft Launcher updating itself.
|
|
//!
|
|
//! Delegated to [`craft_update::self_update`].
|
|
|
|
use std::ffi::OsString;
|
|
|
|
use artcraft_launcher_core::platform::Platform;
|
|
use artcraft_launcher_core::protocol::JobPhase;
|
|
use artcraft_launcher_core::release::Release;
|
|
use artcraft_launcher_core::version::Version;
|
|
|
|
use crate::http::{Http, Stop};
|
|
use crate::paths::Paths;
|
|
|
|
pub use craft_update::self_update::{FINISH_FLAG, Install, PRETEND_VAR, is_self_updating};
|
|
|
|
/// The version this launcher counts as (see [`PRETEND_VAR`]).
|
|
pub fn current_version() -> Option<Version> {
|
|
craft_update::self_update::current_version(&craft_update::suite::LAUNCHER, env!("CARGO_PKG_VERSION"))
|
|
}
|
|
|
|
/// How this copy is installed, if it's one the launcher knows how to replace.
|
|
pub fn current() -> Option<Install> {
|
|
craft_update::self_update::current(&craft_update::suite::LAUNCHER)
|
|
}
|
|
|
|
fn to_update_paths(paths: &Paths) -> craft_update::Paths {
|
|
craft_update::Paths { data: paths.data.clone(), cache: paths.cache.clone() }
|
|
}
|
|
|
|
fn to_update_release(release: &Release) -> craft_update::Release {
|
|
craft_update::Release {
|
|
tag: release.tag.clone(),
|
|
version: release.version.clone(),
|
|
name: release.name.clone(),
|
|
published_at: release.published_at,
|
|
html_url: release.html_url.clone(),
|
|
notes: release.notes.clone(),
|
|
prerelease: release.prerelease,
|
|
assets: release
|
|
.assets
|
|
.iter()
|
|
.map(|a| craft_update::Asset { name: a.name.clone(), size: a.size, url: a.url.clone(), sha256: a.sha256.clone() })
|
|
.collect(),
|
|
}
|
|
}
|
|
|
|
fn to_update_platform(platform: Platform) -> craft_update::Platform {
|
|
craft_update::Platform {
|
|
os: match platform.os {
|
|
artcraft_launcher_core::Os::Windows => craft_update::Os::Windows,
|
|
artcraft_launcher_core::Os::MacOs => craft_update::Os::MacOs,
|
|
artcraft_launcher_core::Os::Linux => craft_update::Os::Linux,
|
|
artcraft_launcher_core::Os::FreeBsd => craft_update::Os::FreeBsd,
|
|
},
|
|
arch: match platform.arch {
|
|
artcraft_launcher_core::Arch::X64 => craft_update::Arch::X64,
|
|
artcraft_launcher_core::Arch::Arm64 => craft_update::Arch::Arm64,
|
|
artcraft_launcher_core::Arch::X86 => craft_update::Arch::X86,
|
|
artcraft_launcher_core::Arch::Riscv64 => craft_update::Arch::Riscv64,
|
|
},
|
|
}
|
|
}
|
|
|
|
/// Whether `release` is the version this launcher just updated itself to.
|
|
pub fn just_updated_to(paths: &Paths, release: &Release) -> bool {
|
|
let update_paths = to_update_paths(paths);
|
|
let update_release = to_update_release(release);
|
|
craft_update::self_update::just_updated_to(&update_paths, &update_release)
|
|
}
|
|
|
|
/// The error of the last update, if it failed, once.
|
|
pub fn take_failure(paths: &Paths) -> Option<String> {
|
|
let update_paths = to_update_paths(paths);
|
|
craft_update::self_update::take_failure(&update_paths)
|
|
}
|
|
|
|
/// Downloads `release` for `platform`, puts it in place and starts the helper that relaunches
|
|
/// it once this process has exited. On success the caller must quit promptly. `last` is called
|
|
/// once the download is ready and returns when the launcher may replace itself and restart.
|
|
#[allow(clippy::too_many_arguments)]
|
|
pub fn update(
|
|
install: &Install,
|
|
release: &Release,
|
|
platform: Platform,
|
|
_http: &Http,
|
|
paths: &Paths,
|
|
stop: &Stop,
|
|
phase: &mut dyn FnMut(JobPhase),
|
|
last: &dyn Fn() -> Result<(), String>,
|
|
) -> Result<(), String> {
|
|
let update_release = to_update_release(release);
|
|
let update_platform = to_update_platform(platform);
|
|
let update_paths = to_update_paths(paths);
|
|
let update_http = craft_update::Http::new("ArtCraft-Launcher/SelfUpdate")?;
|
|
let mut update_phase = |p: craft_update::JobPhase| {
|
|
phase(match p {
|
|
craft_update::JobPhase::Downloading { done, total } => JobPhase::Downloading { done, total },
|
|
craft_update::JobPhase::Reconnecting { done, total } => JobPhase::Reconnecting { done, total },
|
|
craft_update::JobPhase::Waiting => JobPhase::Waiting,
|
|
craft_update::JobPhase::Verifying => JobPhase::Verifying,
|
|
craft_update::JobPhase::Installing => JobPhase::Installing,
|
|
craft_update::JobPhase::Removing => JobPhase::Removing,
|
|
});
|
|
};
|
|
craft_update::self_update::update(
|
|
&craft_update::suite::LAUNCHER,
|
|
install,
|
|
&update_release,
|
|
update_platform,
|
|
&update_http,
|
|
&update_paths,
|
|
stop,
|
|
&mut update_phase,
|
|
last,
|
|
Some(env!("CARGO_PKG_VERSION")),
|
|
)
|
|
}
|
|
|
|
/// Finishes an update when this program was started as the update helper.
|
|
pub fn finish(args: &[OsString]) -> Option<Result<(), String>> {
|
|
craft_update::self_update::finish(&craft_update::suite::LAUNCHER, args)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn a_development_build_does_not_update_itself() {
|
|
assert_eq!(current(), None);
|
|
}
|
|
}
|