mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Add auto apply logic to rust/node
This commit is contained in:
13
samples/RustIced/Cargo.lock
generated
13
samples/RustIced/Cargo.lock
generated
@@ -3102,6 +3102,17 @@ dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.7"
|
||||
@@ -3683,6 +3694,8 @@ dependencies = [
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha1",
|
||||
"sha2",
|
||||
"thiserror",
|
||||
"ureq",
|
||||
"url",
|
||||
|
||||
@@ -43,6 +43,7 @@ declare module "./load" {
|
||||
cb: (hook_name: string, current_version: string) => void,
|
||||
customArgs: string[] | null,
|
||||
locator: string | null,
|
||||
autoApply: boolean,
|
||||
): void;
|
||||
|
||||
function js_set_logger_callback(
|
||||
@@ -66,6 +67,7 @@ export class VelopackApp {
|
||||
private _hooks = new Map<VelopackHookType, VelopackHook>();
|
||||
private _customArgs: string[] | null = null;
|
||||
private _customLocator: VelopackLocatorConfig | null = null;
|
||||
private _autoApply = true;
|
||||
|
||||
static build(): VelopackApp {
|
||||
return new VelopackApp();
|
||||
@@ -147,6 +149,15 @@ export class VelopackApp {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to automatically apply downloaded updates on startup. This is ON by default.
|
||||
*/
|
||||
setAutoApplyOnStartup(autoApply: boolean): VelopackApp {
|
||||
this._autoApply = autoApply;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs the Velopack startup logic. This should be the first thing to run in your app.
|
||||
* In some circumstances it may terminate/restart the process to perform tasks.
|
||||
@@ -161,6 +172,7 @@ export class VelopackApp {
|
||||
},
|
||||
this._customArgs,
|
||||
this._customLocator ? JSON.stringify(this._customLocator) : null,
|
||||
this._autoApply
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -191,7 +203,7 @@ export class UpdateManager {
|
||||
* Returns the currently installed app id.
|
||||
*/
|
||||
getAppId(): string {
|
||||
return addon.js_get_app_id.call(this.opaque);
|
||||
return addon.js_get_app_id(this.opaque);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,7 +211,7 @@ export class UpdateManager {
|
||||
* On MacOS and Linux this will always be true.
|
||||
*/
|
||||
isPortable(): boolean {
|
||||
return addon.js_is_portable.call(this.opaque);
|
||||
return addon.js_is_portable(this.opaque);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,7 +219,7 @@ export class UpdateManager {
|
||||
* You can pass the UpdateInfo object to waitExitThenApplyUpdate to apply the update.
|
||||
*/
|
||||
getUpdatePendingRestart(): UpdateInfo | null {
|
||||
return addon.js_update_pending_restart.call(this.opaque);
|
||||
return addon.js_update_pending_restart(this.opaque);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -68,7 +68,7 @@ fn js_new_update_manager(mut cx: FunctionContext) -> JsResult<BoxedUpdateManager
|
||||
fn js_get_current_version(mut cx: FunctionContext) -> JsResult<JsString> {
|
||||
let mgr_boxed = cx.argument::<BoxedUpdateManager>(0)?;
|
||||
let mgr_ref = &mgr_boxed.borrow().manager;
|
||||
let version = mgr_ref.get_current_version();
|
||||
let version = mgr_ref.get_current_version_as_string();
|
||||
Ok(cx.string(version))
|
||||
}
|
||||
|
||||
@@ -233,6 +233,8 @@ fn js_appbuilder_run(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
||||
}
|
||||
|
||||
let locator = args_get_locator(&mut cx, 2)?;
|
||||
|
||||
let auto_apply = cx.argument::<JsBoolean>(3)?.value(&mut cx);
|
||||
|
||||
let undefined = cx.undefined();
|
||||
let cx_ref = Rc::new(RefCell::new(cx));
|
||||
@@ -248,7 +250,8 @@ fn js_appbuilder_run(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
||||
|
||||
let mut builder = VelopackApp::build()
|
||||
.on_restarted(|semver| hook_handler("restarted", semver))
|
||||
.on_first_run(|semver| hook_handler("first-run", semver));
|
||||
.on_first_run(|semver| hook_handler("first-run", semver))
|
||||
.set_auto_apply_on_startup(auto_apply);
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
|
||||
@@ -3,10 +3,11 @@ use std::env;
|
||||
use std::process::exit;
|
||||
|
||||
use crate::{
|
||||
locator::{auto_locate_app_manifest, VelopackLocatorConfig},
|
||||
Error, constants::*,
|
||||
locator::{VelopackLocatorConfig},
|
||||
constants::*,
|
||||
manager,
|
||||
sources,
|
||||
};
|
||||
use crate::locator::{LocationContext, VelopackLocator};
|
||||
|
||||
/// VelopackApp helps you to handle app activation events correctly.
|
||||
/// This should be used as early as possible in your application startup code.
|
||||
@@ -18,7 +19,7 @@ pub struct VelopackApp<'a> {
|
||||
uninstall_hook: Option<Box<dyn FnOnce(Version) + 'a>>,
|
||||
firstrun_hook: Option<Box<dyn FnOnce(Version) + 'a>>,
|
||||
restarted_hook: Option<Box<dyn FnOnce(Version) + 'a>>,
|
||||
// auto_apply: bool,
|
||||
auto_apply: bool,
|
||||
args: Vec<String>,
|
||||
locator: Option<VelopackLocatorConfig>,
|
||||
}
|
||||
@@ -33,7 +34,7 @@ impl<'a> VelopackApp<'a> {
|
||||
uninstall_hook: None,
|
||||
firstrun_hook: None,
|
||||
restarted_hook: None,
|
||||
// auto_apply: true, // Default to true
|
||||
auto_apply: true, // Default to true
|
||||
args: env::args().skip(1).collect(),
|
||||
locator: None,
|
||||
}
|
||||
@@ -46,10 +47,10 @@ impl<'a> VelopackApp<'a> {
|
||||
}
|
||||
|
||||
/// Set whether to automatically apply downloaded updates on startup. This is ON by default.
|
||||
// pub fn set_auto_apply_on_startup(mut self, apply: bool) -> Self {
|
||||
// self.auto_apply = apply;
|
||||
// self
|
||||
// }
|
||||
pub fn set_auto_apply_on_startup(mut self, apply: bool) -> Self {
|
||||
self.auto_apply = apply;
|
||||
self
|
||||
}
|
||||
|
||||
/// Override the default file locator with a custom one (eg. for testing)
|
||||
pub fn set_locator(mut self, locator: VelopackLocatorConfig) -> Self {
|
||||
@@ -126,20 +127,39 @@ impl<'a> VelopackApp<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
let locator = self.load_locator();
|
||||
|
||||
if let Err(e) = locator {
|
||||
error!("VelopackApp: Error loading locator: {:?}", e);
|
||||
let manager = manager::UpdateManager::new(sources::NoneSource{}, None, self.locator.clone());
|
||||
if let Err(e) = manager {
|
||||
error!("VelopackApp: Error loading manager/locator: {:?}", e);
|
||||
return;
|
||||
}
|
||||
let manager = manager.unwrap();
|
||||
|
||||
let my_version = locator.unwrap().get_manifest_version();
|
||||
let my_version = manager.get_current_version();
|
||||
|
||||
let firstrun = env::var(HOOK_ENV_FIRSTRUN).is_ok();
|
||||
env::remove_var(HOOK_ENV_FIRSTRUN);
|
||||
|
||||
let restarted = env::var(HOOK_ENV_RESTART).is_ok();
|
||||
env::remove_var(HOOK_ENV_RESTART);
|
||||
|
||||
// if auto apply is true, we should check for a local package downloaded with a version
|
||||
// greater than ours. If it exists, we should quit and apply it now.
|
||||
if self.auto_apply {
|
||||
if let Some(asset) = manager.get_update_pending_restart() {
|
||||
match Version::parse(&asset.Version) {
|
||||
Ok(asset_version) => {
|
||||
if asset_version > my_version {
|
||||
if let Err(e) = manager.apply_updates_and_restart_with_args(&asset, &args) {
|
||||
error!("VelopackApp: Error applying pending updates on startup: {:?}", e);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
error!("VelopackApp: Error parsing asset version: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if firstrun {
|
||||
Self::call_hook(&mut self.firstrun_hook, &my_version);
|
||||
@@ -171,14 +191,4 @@ impl<'a> VelopackApp<'a> {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
fn load_locator(&self) -> Result<VelopackLocator, Error> {
|
||||
let locator = if let Some(config) = &self.locator {
|
||||
let manifest = config.load_manifest()?;
|
||||
VelopackLocator::new(config.clone(), manifest)
|
||||
} else {
|
||||
auto_locate_app_manifest(LocationContext::FromCurrentExe)?
|
||||
};
|
||||
Ok(locator)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,12 @@ impl AsRef<VelopackAsset> for UpdateInfo {
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<VelopackAsset> for VelopackAsset {
|
||||
fn as_ref(&self) -> &VelopackAsset {
|
||||
&self
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
|
||||
@@ -159,10 +165,15 @@ impl UpdateManager {
|
||||
channel
|
||||
}
|
||||
|
||||
/// The currently installed app version.
|
||||
pub fn get_current_version(&self) -> String {
|
||||
/// The currently installed app version as a string.
|
||||
pub fn get_current_version_as_string(&self) -> String {
|
||||
self.locator.get_manifest_version_full_string()
|
||||
}
|
||||
|
||||
/// The currently installed app version as a semver Version.
|
||||
pub fn get_current_version(&self) -> Version {
|
||||
self.locator.get_manifest_version()
|
||||
}
|
||||
|
||||
/// The currently installed app id.
|
||||
pub fn get_app_id(&self) -> String {
|
||||
@@ -393,7 +404,7 @@ impl UpdateManager {
|
||||
/// This will exit your app immediately and apply specified updates. It will not restart your app afterwards.
|
||||
/// If you need to save state or clean up, you should do that before calling this method.
|
||||
/// The user may be prompted during the update, if the update requires additional frameworks to be installed etc.
|
||||
pub fn apply_updates_and_exit<A, C, S>(&self, to_apply: A) -> Result<(), Error>
|
||||
pub fn apply_updates_and_exit<A>(&self, to_apply: A) -> Result<(), Error>
|
||||
where
|
||||
A: AsRef<VelopackAsset>,
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ use std::{
|
||||
};
|
||||
|
||||
use crate::*;
|
||||
use crate::bundle::Manifest;
|
||||
|
||||
/// Abstraction for finding and downloading updates from a package source / repository.
|
||||
/// An implementation may copy a file from a local repository, download from a web address,
|
||||
@@ -24,6 +25,22 @@ impl Clone for Box<dyn UpdateSource> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A source that does not provide any update capability.
|
||||
#[derive(Clone)]
|
||||
pub struct NoneSource {}
|
||||
|
||||
impl UpdateSource for NoneSource {
|
||||
fn get_release_feed(&self, _channel: &str, _app: &Manifest) -> Result<VelopackAssetFeed, Error> {
|
||||
Err(Error::Generic("None source does not checking release feed".to_owned()))
|
||||
}
|
||||
fn download_release_entry(&self, _asset: &VelopackAsset, _local_file: &str, _progress_sender: Option<Sender<i16>>) -> Result<(), Error> {
|
||||
Err(Error::Generic("None source does not support downloads".to_owned()))
|
||||
}
|
||||
fn clone_boxed(&self) -> Box<dyn UpdateSource> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
/// Automatically delegates to the appropriate source based on the provided input string. If the input is a local path,
|
||||
/// it will use a FileSource. If the input is a URL, it will use an HttpSource.
|
||||
|
||||
17
src/src/bindings/UpdateInfo.ts
Normal file
17
src/src/bindings/UpdateInfo.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { VelopackAsset } from "./VelopackAsset";
|
||||
|
||||
/**
|
||||
* Holds information about the current version and pending updates, such as how many there are, and access to release notes.
|
||||
*/
|
||||
export type UpdateInfo = {
|
||||
/**
|
||||
* The available version that we are updating to.
|
||||
*/
|
||||
TargetFullRelease: VelopackAsset,
|
||||
/**
|
||||
* True if the update is a version downgrade or lateral move (such as when switching channels to the same version number).
|
||||
* In this case, only full updates are allowed, and any local packages on disk newer than the downloaded version will be
|
||||
* deleted.
|
||||
*/
|
||||
IsDowngrade: boolean, };
|
||||
23
src/src/bindings/UpdateOptions.ts
Normal file
23
src/src/bindings/UpdateOptions.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
/**
|
||||
* Options to customise the behaviour of UpdateManager.
|
||||
*/
|
||||
export type UpdateOptions = {
|
||||
/**
|
||||
* Allows UpdateManager to update to a version that's lower than the current version (i.e. downgrading).
|
||||
* This could happen if a release has bugs and was retracted from the release feed, or if you're using
|
||||
* ExplicitChannel to switch channels to another channel where the latest version on that
|
||||
* channel is lower than the current version.
|
||||
*/
|
||||
AllowVersionDowngrade: boolean,
|
||||
/**
|
||||
* **This option should usually be left None**. <br/>
|
||||
* Overrides the default channel used to fetch updates.
|
||||
* The default channel will be whatever channel was specified on the command line when building this release.
|
||||
* For example, if the current release was packaged with '--channel beta', then the default channel will be 'beta'.
|
||||
* This allows users to automatically receive updates from the same channel they installed from. This options
|
||||
* allows you to explicitly switch channels, for example if the user wished to switch back to the 'stable' channel
|
||||
* without having to reinstall the application.
|
||||
*/
|
||||
ExplicitChannel: string | null, };
|
||||
42
src/src/bindings/VelopackAsset.ts
Normal file
42
src/src/bindings/VelopackAsset.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
/**
|
||||
* An individual Velopack asset, could refer to an asset on-disk or in a remote package feed.
|
||||
*/
|
||||
export type VelopackAsset = {
|
||||
/**
|
||||
* The name or Id of the package containing this release.
|
||||
*/
|
||||
PackageId: string,
|
||||
/**
|
||||
* The version of this release.
|
||||
*/
|
||||
Version: string,
|
||||
/**
|
||||
* The type of asset (eg. "Full" or "Delta").
|
||||
*/
|
||||
Type: string,
|
||||
/**
|
||||
* The filename of the update package containing this release.
|
||||
*/
|
||||
FileName: string,
|
||||
/**
|
||||
* The SHA1 checksum of the update package containing this release.
|
||||
*/
|
||||
SHA1: string,
|
||||
/**
|
||||
* The SHA256 checksum of the update package containing this release.
|
||||
*/
|
||||
SHA256: string,
|
||||
/**
|
||||
* The size in bytes of the update package containing this release.
|
||||
*/
|
||||
Size: bigint,
|
||||
/**
|
||||
* The release notes in markdown format, as passed to Velopack when packaging the release. This may be an empty string.
|
||||
*/
|
||||
NotesMarkdown: string,
|
||||
/**
|
||||
* The release notes in HTML format, transformed from Markdown when packaging the release. This may be an empty string.
|
||||
*/
|
||||
NotesHtml: string, };
|
||||
30
src/src/bindings/VelopackLocatorConfig.ts
Normal file
30
src/src/bindings/VelopackLocatorConfig.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
/**
|
||||
* VelopackLocator provides some utility functions for locating the current app important paths (eg. path to packages, update binary, and so forth).
|
||||
*/
|
||||
export type VelopackLocatorConfig = {
|
||||
/**
|
||||
* The root directory of the current app.
|
||||
*/
|
||||
RootAppDir: string,
|
||||
/**
|
||||
* The path to the Update.exe binary.
|
||||
*/
|
||||
UpdateExePath: string,
|
||||
/**
|
||||
* The path to the packages' directory.
|
||||
*/
|
||||
PackagesDir: string,
|
||||
/**
|
||||
* The current app manifest.
|
||||
*/
|
||||
ManifestPath: string,
|
||||
/**
|
||||
* The directory containing the application's user binaries.
|
||||
*/
|
||||
CurrentBinaryDir: string,
|
||||
/**
|
||||
* Whether the current application is portable or installed.
|
||||
*/
|
||||
IsPortable: boolean, };
|
||||
Reference in New Issue
Block a user