mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
wip
This commit is contained in:
10
.gitignore
vendored
10
.gitignore
vendored
@@ -2,6 +2,16 @@
|
||||
target/
|
||||
_docyml/
|
||||
|
||||
target
|
||||
index.node
|
||||
**/node_modules
|
||||
**/.DS_Store
|
||||
npm-debug.log*
|
||||
lib
|
||||
cargo.log
|
||||
cross.log
|
||||
|
||||
|
||||
#################
|
||||
## Eclipse
|
||||
#################
|
||||
|
||||
57
Cargo.lock
generated
57
Cargo.lock
generated
@@ -1207,6 +1207,32 @@ dependencies = [
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "neon"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d75440242411c87dc39847b0e33e961ec1f10326a9d8ecf9c1ea64a3b3c13dc"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libloading",
|
||||
"neon-macros",
|
||||
"once_cell",
|
||||
"semver",
|
||||
"send_wrapper",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "neon-macros"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6813fde79b646e47e7ad75f480aa80ef76a5d9599e2717407961531169ee38b"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn-mid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.26.4"
|
||||
@@ -1718,6 +1744,12 @@ version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
||||
|
||||
[[package]]
|
||||
name = "send_wrapper"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.204"
|
||||
@@ -1791,6 +1823,12 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.10"
|
||||
@@ -1857,6 +1895,17 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn-mid"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5dc35bb08dd1ca3dfb09dce91fd2d13294d6711c88897d9a9d60acf39bce049"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.12.0"
|
||||
@@ -2139,6 +2188,14 @@ dependencies = [
|
||||
"zstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "velopack_nodeffi"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"neon",
|
||||
"velopack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "versions"
|
||||
version = "5.0.1"
|
||||
|
||||
@@ -3,6 +3,7 @@ resolver = "2"
|
||||
members = [
|
||||
"src/bins",
|
||||
"src/lib-rust",
|
||||
"src/lib-node/crates/velopack_nodeffi",
|
||||
# "src/lib-cpp/generator"
|
||||
]
|
||||
|
||||
|
||||
8
src/lib-node/.gitignore
vendored
8
src/lib-node/.gitignore
vendored
@@ -1,8 +0,0 @@
|
||||
target
|
||||
index.node
|
||||
**/node_modules
|
||||
**/.DS_Store
|
||||
npm-debug.log*
|
||||
lib
|
||||
cargo.log
|
||||
cross.log
|
||||
@@ -1,3 +0,0 @@
|
||||
[workspace]
|
||||
members = ["crates/veloz"]
|
||||
resolver = "2"
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "veloz"
|
||||
name = "velopack_nodeffi"
|
||||
version = "0.1.0"
|
||||
license = "ISC"
|
||||
license = "MIT"
|
||||
edition = "2021"
|
||||
exclude = ["index.node"]
|
||||
|
||||
@@ -12,3 +12,4 @@ crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
neon = "1"
|
||||
velopack = { path = "../../../lib-rust" }
|
||||
49
src/lib-node/crates/velopack_nodeffi/src/lib.rs
Normal file
49
src/lib-node/crates/velopack_nodeffi/src/lib.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
use neon::prelude::*;
|
||||
use velopack::*;
|
||||
use velopack::sources::*;
|
||||
|
||||
|
||||
struct UpdateManagerWrapper<'a> {
|
||||
manager: UpdateManager<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Finalize for UpdateManagerWrapper<'a> {}
|
||||
|
||||
|
||||
fn get_js_options(mut cx: FunctionContext, obj: &Handle<JsObject>) -> JsResult<UpdateOptions> {
|
||||
let allow_downgrade = obj.get(&mut cx, "allowDowngrade")?;
|
||||
|
||||
}
|
||||
|
||||
fn js_new_from_http_source(mut cx: FunctionContext) -> JsResult<JsBox<UpdateManagerWrapper>> {
|
||||
let url = cx.argument::<JsString>(0)?.value(&mut cx);
|
||||
|
||||
let options: Option<UpdateOptions> = None;
|
||||
|
||||
|
||||
let obj = cx.argument::<JsObject>(1)?;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
let source = HttpSource::new(&url);
|
||||
let um = UpdateManager::new(source, options).map_err(|e| cx.throw_error(e.to_string()))?;
|
||||
|
||||
let wrapper = UpdateManagerWrapper { manager: um };
|
||||
|
||||
|
||||
Ok(cx.boxed(wrapper))
|
||||
}
|
||||
|
||||
fn hello(mut cx: FunctionContext) -> JsResult<JsString> {
|
||||
Ok(cx.string("hello node"))
|
||||
}
|
||||
|
||||
#[neon::main]
|
||||
fn main(mut cx: ModuleContext) -> NeonResult<()> {
|
||||
cx.export_function("hello", hello)?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
use neon::prelude::*;
|
||||
|
||||
fn hello(mut cx: FunctionContext) -> JsResult<JsString> {
|
||||
Ok(cx.string("hello node"))
|
||||
}
|
||||
|
||||
#[neon::main]
|
||||
fn main(mut cx: ModuleContext) -> NeonResult<()> {
|
||||
cx.export_function("hello", hello)?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::{fs, process::Command as Process, process::exit};
|
||||
use std::{fs, process::{exit, Command as Process}, rc::Rc, sync::mpsc::Sender};
|
||||
#[cfg(target_os = "windows")]
|
||||
use std::os::windows::process::CommandExt;
|
||||
|
||||
@@ -91,26 +91,24 @@ pub struct UpdateOptions {
|
||||
}
|
||||
|
||||
/// Provides functionality for checking for updates, downloading updates, and applying updates to the current application.
|
||||
pub struct UpdateManager<T>
|
||||
where
|
||||
T: UpdateSource,
|
||||
pub struct UpdateManager<'a>
|
||||
{
|
||||
allow_version_downgrade: bool,
|
||||
explicit_channel: Option<String>,
|
||||
source: T,
|
||||
source: Rc<Box<dyn UpdateSource + 'a>>,
|
||||
paths: VelopackLocator,
|
||||
}
|
||||
|
||||
impl<T: UpdateSource> Clone for UpdateManager<T> {
|
||||
fn clone(&self) -> Self {
|
||||
UpdateManager {
|
||||
allow_version_downgrade: self.allow_version_downgrade,
|
||||
explicit_channel: self.explicit_channel.clone(),
|
||||
source: self.source.clone(),
|
||||
paths: self.paths.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
// impl Clone for UpdateManager {
|
||||
// fn clone(&self) -> Self {
|
||||
// UpdateManager {
|
||||
// allow_version_downgrade: self.allow_version_downgrade,
|
||||
// explicit_channel: self.explicit_channel.clone(),
|
||||
// source: self.source.clone(),
|
||||
// paths: self.paths.clone(),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/// Arguments to pass to the Update.exe process when restarting the application after applying updates.
|
||||
pub enum RestartArgs<'a> {
|
||||
@@ -145,7 +143,7 @@ pub enum UpdateCheck {
|
||||
UpdateAvailable(UpdateInfo),
|
||||
}
|
||||
|
||||
impl<T: UpdateSource> UpdateManager<T> {
|
||||
impl<'a> UpdateManager<'a> {
|
||||
/// Create a new UpdateManager instance using the specified UpdateSource.
|
||||
/// This will return an error if the application is not yet installed.
|
||||
/// ## Example:
|
||||
@@ -155,12 +153,12 @@ impl<T: UpdateSource> UpdateManager<T> {
|
||||
/// let source = sources::HttpSource::new("https://the.place/you-host/updates");
|
||||
/// let um = UpdateManager::new(source, None);
|
||||
/// ```
|
||||
pub fn new(source: T, options: Option<UpdateOptions>) -> Result<UpdateManager<T>, Error> {
|
||||
pub fn new<T: UpdateSource + 'a>(source: T, options: Option<UpdateOptions>) -> Result<UpdateManager::<'a>, Error> {
|
||||
Ok(UpdateManager {
|
||||
paths: locator::auto_locate()?,
|
||||
allow_version_downgrade: options.as_ref().map(|f| f.AllowVersionDowngrade).unwrap_or(false),
|
||||
explicit_channel: options.as_ref().map(|f| f.ExplicitChannel.clone()).unwrap_or(None),
|
||||
source,
|
||||
source: Rc::new(Box::new(source)),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -232,7 +230,6 @@ impl<T: UpdateSource> UpdateManager<T> {
|
||||
|
||||
debug!("Latest remote release: {} ({}).", remote_asset.FileName, remote_version.to_string());
|
||||
|
||||
|
||||
if remote_version > app.version {
|
||||
info!("Found newer remote release available ({} -> {}).", app.version, remote_version);
|
||||
Ok(UpdateCheck::UpdateAvailable(UpdateInfo { TargetFullRelease: remote_asset, IsDowngrade: false }))
|
||||
@@ -260,13 +257,13 @@ impl<T: UpdateSource> UpdateManager<T> {
|
||||
async_std::task::spawn_blocking(move || self_clone.check_for_updates())
|
||||
}
|
||||
|
||||
/// Downloads the specified updates to the local app packages directory. If the update contains delta packages and the delta feature is enabled
|
||||
/// this method will attempt to unpack and prepare them. If there is no delta update available, or there is an error preparing delta
|
||||
/// packages, this method will fall back to downloading the full version of the update. This function will acquire a global update lock
|
||||
/// so may fail if there is already another update operation in progress.
|
||||
pub fn download_updates<A>(&self, update: &UpdateInfo, progress: A) -> Result<(), Error>
|
||||
where
|
||||
A: FnMut(i16),
|
||||
/// Downloads the specified updates to the local app packages directory. Progress is reported back to the caller via an optional Sender.
|
||||
/// This function will acquire a global update lock so may fail if there is already another update operation in progress.
|
||||
/// - If the update contains delta packages and the delta feature is enabled
|
||||
/// this method will attempt to unpack and prepare them.
|
||||
/// - If there is no delta update available, or there is an error preparing delta
|
||||
/// packages, this method will fall back to downloading the full version of the update.
|
||||
pub fn download_updates(&self, update: &UpdateInfo, progress: Option<Sender<i16>>) -> Result<(), Error>
|
||||
{
|
||||
let name = &update.TargetFullRelease.FileName;
|
||||
let packages_dir = &self.paths.packages_dir;
|
||||
@@ -321,25 +318,17 @@ impl<T: UpdateSource> UpdateManager<T> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
/// Downloads the specified updates to the local app packages directory. If the update contains delta packages and the delta feature is enabled
|
||||
/// this method will attempt to unpack and prepare them. If there is no delta update available, or there is an error preparing delta
|
||||
/// packages, this method will fall back to downloading the full version of the update. This function will acquire a global update lock
|
||||
/// so may fail if there is already another update operation in progress.
|
||||
/// Downloads the specified updates to the local app packages directory. Progress is reported back to the caller via an optional Sender.
|
||||
/// This function will acquire a global update lock so may fail if there is already another update operation in progress.
|
||||
/// - If the update contains delta packages and the delta feature is enabled
|
||||
/// this method will attempt to unpack and prepare them.
|
||||
/// - If there is no delta update available, or there is an error preparing delta
|
||||
/// packages, this method will fall back to downloading the full version of the update.
|
||||
pub fn download_updates_async(&self, update: &UpdateInfo, progress: Option<Sender<i16>>) -> JoinHandle<Result<(), Error>>
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
let self_clone = self.clone();
|
||||
let update_clone = update.clone();
|
||||
if let Some(p) = progress {
|
||||
async_std::task::spawn_blocking(move || {
|
||||
self_clone.download_updates(&update_clone, move |x| {
|
||||
let _ = p.try_send(x);
|
||||
})
|
||||
})
|
||||
} else {
|
||||
async_std::task::spawn_blocking(move || self_clone.download_updates(&update_clone, |_| {}))
|
||||
}
|
||||
async_std::task::spawn_blocking(move || self_clone.download_updates(&update_clone, progress))
|
||||
}
|
||||
|
||||
/// This will exit your app immediately, apply updates, and then optionally relaunch the app using the specified
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
sync::mpsc::Sender,
|
||||
};
|
||||
|
||||
use crate::*;
|
||||
|
||||
/// 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,
|
||||
/// or even use third party services and parse proprietary data to produce a package feed.
|
||||
pub trait UpdateSource: Clone + Send + Sync {
|
||||
pub trait UpdateSource: Send + Sync {
|
||||
/// Retrieve the list of available remote releases from the package source. These releases
|
||||
/// can subsequently be downloaded with download_release_entry.
|
||||
fn get_release_feed(&self, channel: &str, app: &manifest::Manifest) -> Result<VelopackAssetFeed, Error>;
|
||||
/// Download the specified VelopackAsset to the provided local file path.
|
||||
fn download_release_entry<A>(&self, asset: &VelopackAsset, local_file: &str, progress: A) -> Result<(), Error>
|
||||
where A: FnMut(i16);
|
||||
fn download_release_entry(&self, asset: &VelopackAsset, local_file: &str, progress_sender: Option<Sender<i16>>) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -44,15 +46,17 @@ impl UpdateSource for HttpSource {
|
||||
Ok(feed)
|
||||
}
|
||||
|
||||
fn download_release_entry<A>(&self, asset: &VelopackAsset, local_file: &str, progress: A) -> Result<(), Error>
|
||||
where A: FnMut(i16),
|
||||
{
|
||||
fn download_release_entry(&self, asset: &VelopackAsset, local_file: &str, progress_sender: Option<Sender<i16>>) -> Result<(), Error> {
|
||||
let path = self.url.trim_end_matches('/').to_owned() + "/";
|
||||
let url = url::Url::parse(&path)?;
|
||||
let asset_url = url.join(&asset.FileName)?;
|
||||
|
||||
info!("About to download from URL '{}' to file '{}'", asset_url, local_file);
|
||||
download::download_url_to_file(asset_url.as_str(), local_file, progress)?;
|
||||
download::download_url_to_file(asset_url.as_str(), local_file, move |p| {
|
||||
if let Some(progress_sender) = &progress_sender {
|
||||
let _ = progress_sender.send(p);
|
||||
}
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -83,14 +87,16 @@ impl UpdateSource for FileSource {
|
||||
Ok(feed)
|
||||
}
|
||||
|
||||
fn download_release_entry<A>(&self, asset: &VelopackAsset, local_file: &str, mut progress: A) -> Result<(), Error>
|
||||
where A: FnMut(i16),
|
||||
{
|
||||
fn download_release_entry(&self, asset: &VelopackAsset, local_file: &str, progress_sender: Option<Sender<i16>>) -> Result<(), Error> {
|
||||
let asset_path = self.path.join(&asset.FileName);
|
||||
info!("About to copy from file '{}' to file '{}'", asset_path.display(), local_file);
|
||||
progress(50);
|
||||
if let Some(progress_sender) = &progress_sender {
|
||||
let _ = progress_sender.send(50);
|
||||
}
|
||||
std::fs::copy(asset_path, local_file)?;
|
||||
progress(100);
|
||||
if let Some(progress_sender) = &progress_sender {
|
||||
let _ = progress_sender.send(100);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user