mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
WIP migrate OSX
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
use crate::shared::{
|
||||
self,
|
||||
bundle::{self, Manifest},
|
||||
dialogs,
|
||||
};
|
||||
use anyhow::{bail, Result};
|
||||
use std::{fs, path::PathBuf, process::Command};
|
||||
use velopack::locator::VelopackLocator;
|
||||
|
||||
pub fn apply_package_impl<'a>(root_path: &PathBuf, app: &Manifest, pkg: &PathBuf, _runhooks: bool) -> Result<Manifest> {
|
||||
pub fn apply_package_impl<'a>(locator: &VelopackLocator, pkg: &PathBuf, _runhooks: bool) -> Result<VelopackLocator> {
|
||||
#[allow(deprecated)]
|
||||
let mut cache_dir = std::env::home_dir().expect("Could not locate user home directory via $HOME or /etc/passwd");
|
||||
cache_dir.push("Library");
|
||||
|
||||
@@ -23,7 +23,7 @@ pub fn start(
|
||||
super::start_windows_impl::start_impl(&locator, exe_name, exe_args, legacy_args)?;
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
shared::start_package(&app, &root_dir, exe_args, None)?;
|
||||
shared::start_package(&locator, exe_args, None)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// pub mod bundle;
|
||||
// pub mod download;
|
||||
pub mod macho;
|
||||
pub mod runtime_arch;
|
||||
|
||||
mod dialogs_const;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use crate::shared::bundle;
|
||||
|
||||
use super::bundle::Manifest;
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use std::{path::Path, path::PathBuf, process::Command as Process, time::Duration};
|
||||
use std::{path::Path, process::Command as Process, time::Duration};
|
||||
use velopack::locator::VelopackLocator;
|
||||
|
||||
pub fn wait_for_pid_to_exit(pid: u32, ms_to_wait: u32) -> Result<()> {
|
||||
info!("Waiting {}ms for process ({}) to exit.", ms_to_wait, pid);
|
||||
@@ -32,8 +30,8 @@ pub fn force_stop_package<P: AsRef<Path>>(root_dir: P) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn start_package<P: AsRef<Path>>(_app: &Manifest, root_dir: P, exe_args: Option<Vec<&str>>, set_env: Option<&str>) -> Result<()> {
|
||||
let root_dir = root_dir.as_ref().to_string_lossy().to_string();
|
||||
pub fn start_package(locator: &VelopackLocator, exe_args: Option<Vec<&str>>, set_env: Option<&str>) -> Result<()> {
|
||||
let root_dir = locator.get_root_dir_as_string();
|
||||
let mut args = vec!["-n", &root_dir];
|
||||
if let Some(a) = exe_args {
|
||||
args.push("--args");
|
||||
@@ -49,47 +47,15 @@ pub fn start_package<P: AsRef<Path>>(_app: &Manifest, root_dir: P, exe_args: Opt
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn detect_manifest_from_update_path(update_exe: &PathBuf) -> Result<(PathBuf, Manifest)> {
|
||||
let mut manifest_path = update_exe.clone();
|
||||
manifest_path.pop();
|
||||
manifest_path.push("sq.version");
|
||||
let manifest = load_manifest(&manifest_path)?;
|
||||
|
||||
let my_path = std::env::current_exe()?;
|
||||
let my_path = my_path.to_string_lossy();
|
||||
let app_idx = my_path.find(".app/");
|
||||
if app_idx.is_none() {
|
||||
bail!("Unable to find .app/ directory in path: {}", my_path);
|
||||
}
|
||||
|
||||
let root_dir = &my_path[..app_idx.unwrap()];
|
||||
let root_dir = root_dir.to_owned() + ".app";
|
||||
|
||||
debug!("Detected Root: {}", root_dir);
|
||||
debug!("Detected AppId: {}", manifest.id);
|
||||
Ok((Path::new(&root_dir).to_path_buf(), manifest))
|
||||
}
|
||||
|
||||
pub fn detect_current_manifest() -> Result<(PathBuf, Manifest)> {
|
||||
let me = std::env::current_exe()?;
|
||||
detect_manifest_from_update_path(&me)
|
||||
}
|
||||
|
||||
fn load_manifest(nuspec_path: &PathBuf) -> Result<Manifest> {
|
||||
if Path::new(&nuspec_path).exists() {
|
||||
if let Ok(nuspec) = super::retry_io(|| std::fs::read_to_string(&nuspec_path)) {
|
||||
return Ok(bundle::read_manifest_from_string(&nuspec)?);
|
||||
}
|
||||
}
|
||||
bail!("Unable to read nuspec file in current directory.")
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_start_and_stop_package() {
|
||||
let mani = Manifest::default();
|
||||
let root_dir = "/Applications/Calcbot.app";
|
||||
let _ = force_stop_package(root_dir);
|
||||
let mani = velopack::bundle::Manifest::default();
|
||||
let mut paths = velopack::locator::VelopackLocatorConfig::default();
|
||||
paths.RootAppDir = std::path::PathBuf::from("/Applications/Calcbot.app");
|
||||
let locator = VelopackLocator::new(paths, mani);
|
||||
|
||||
let _ = force_stop_package(locator.get_root_dir());
|
||||
|
||||
fn is_running() -> bool {
|
||||
let output = Process::new("pgrep").arg("-f").arg("Calcbot.app").output().unwrap();
|
||||
@@ -99,11 +65,11 @@ fn test_start_and_stop_package() {
|
||||
std::thread::sleep(Duration::from_secs(1));
|
||||
assert!(!is_running());
|
||||
std::thread::sleep(Duration::from_secs(1));
|
||||
start_package(&mani, root_dir, None, None).unwrap();
|
||||
start_package(&locator, None, None).unwrap();
|
||||
std::thread::sleep(Duration::from_secs(1));
|
||||
assert!(is_running());
|
||||
std::thread::sleep(Duration::from_secs(1));
|
||||
force_stop_package(root_dir).unwrap();
|
||||
force_stop_package(locator.get_root_dir()).unwrap();
|
||||
std::thread::sleep(Duration::from_secs(1));
|
||||
assert!(!is_running());
|
||||
}
|
||||
|
||||
@@ -216,13 +216,17 @@ fn js_appbuilder_run(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
||||
};
|
||||
|
||||
let mut builder = VelopackApp::build()
|
||||
.on_after_install_fast_callback(|semver| hook_handler("after-install", semver))
|
||||
.on_before_uninstall_fast_callback(|semver| hook_handler("before-uninstall", semver))
|
||||
.on_before_update_fast_callback(|semver| hook_handler("before-update", semver))
|
||||
.on_after_update_fast_callback(|semver| hook_handler("after-update", semver))
|
||||
.on_restarted(|semver| hook_handler("restarted", semver))
|
||||
.on_first_run(|semver| hook_handler("first-run", semver));
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
builder.on_after_install_fast_callback(|semver| hook_handler("after-install", semver));
|
||||
builder.on_before_uninstall_fast_callback(|semver| hook_handler("before-uninstall", semver));
|
||||
builder.on_before_update_fast_callback(|semver| hook_handler("before-update", semver));
|
||||
builder.on_after_update_fast_callback(|semver| hook_handler("after-update", semver));
|
||||
}
|
||||
|
||||
if let Some(locator) = locator {
|
||||
builder = builder.set_locator(locator);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@ use zip::ZipArchive;
|
||||
|
||||
use crate::{Error, util};
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
use normpath::PathExt;
|
||||
|
||||
@@ -297,7 +300,7 @@ impl BundleZip<'_> {
|
||||
// on macos, we need to chmod +x the executable files
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
if let Ok(true) = super::macho::is_macho_image(&file_path_on_disk) {
|
||||
if let Ok(true) = super::bindetect::is_macho_image(&file_path_on_disk) {
|
||||
if let Err(e) = std::fs::set_permissions(&file_path_on_disk, std::fs::Permissions::from_mode(0o755)) {
|
||||
warn!("Failed to set executable permissions on '{}': {}", file_path_on_disk.to_string_lossy(), e);
|
||||
} else {
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
mod app;
|
||||
mod manager;
|
||||
mod util;
|
||||
mod bindetect;
|
||||
|
||||
/// Utility functions for loading and working with Velopack bundles and manifests.
|
||||
pub mod bundle;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
use semver::Version;
|
||||
use crate::{
|
||||
bundle::{self, Manifest},
|
||||
@@ -16,6 +16,7 @@ pub fn default_channel_name() -> String {
|
||||
}
|
||||
|
||||
/// Default log location for Velopack on the current OS.
|
||||
#[allow(unused_variables)]
|
||||
pub fn default_log_location(context: LocationContext) -> PathBuf {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
@@ -420,15 +421,21 @@ pub fn auto_locate<P: AsRef<Path>>(exe_path: P) -> Result<VelopackLocatorConfig,
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
/// Automatically locates the current app's important paths. If the app is not installed, it will return an error.
|
||||
pub fn auto_locate<P: AsRef<Path>>(exe_path: P) -> Result<VelopackLocatorConfig, Error> {
|
||||
let path = exe_path.as_ref().to_path_buf();
|
||||
let path = path.to_string_lossy();
|
||||
let idx = path.rfind(".app/");
|
||||
pub fn auto_locate_app_manifest(context: LocationContext) -> Result<VelopackLocator, Error> {
|
||||
let mut search_path = std::env::current_exe()?;
|
||||
match context {
|
||||
LocationContext::FromSpecifiedRootDir(dir) => search_path = dir.join("dummy"),
|
||||
LocationContext::FromSpecifiedAppExecutable(exe) => search_path = exe,
|
||||
_ => {},
|
||||
}
|
||||
|
||||
let search_string = search_path.to_string_lossy();
|
||||
let idx = search_string.rfind(".app/");
|
||||
if idx.is_none() {
|
||||
return Err(Error::NotInstalled(format!("Could not locate '.app' in executable path {}", path)));
|
||||
return Err(Error::NotInstalled(format!("Could not locate '.app' in executable path {}", search_string)));
|
||||
}
|
||||
let idx = idx.unwrap();
|
||||
let path = path[..(idx + 4)].to_string();
|
||||
let path = search_string[..(idx + 4)].to_string();
|
||||
|
||||
let root_app_dir = PathBuf::from(&path);
|
||||
let contents_dir = root_app_dir.join("Contents").join("MacOS");
|
||||
@@ -449,13 +456,16 @@ pub fn auto_locate<P: AsRef<Path>>(exe_path: P) -> Result<VelopackLocatorConfig,
|
||||
packages_dir.push(&app.id);
|
||||
packages_dir.push("packages");
|
||||
|
||||
Ok(VelopackLocatorConfig {
|
||||
let config = VelopackLocatorConfig {
|
||||
RootAppDir: root_app_dir,
|
||||
UpdateExePath: update_exe_path,
|
||||
PackagesDir: packages_dir,
|
||||
ManifestPath: metadata_path,
|
||||
TempDir: PathBuf::from("/tmp/velopack").join(&app.id),
|
||||
})
|
||||
CurrentBinaryDir: contents_dir,
|
||||
IsPortable: true,
|
||||
};
|
||||
|
||||
config_to_locator(&config)
|
||||
}
|
||||
|
||||
fn read_current_manifest(nuspec_path: &PathBuf) -> Result<Manifest, Error> {
|
||||
|
||||
Reference in New Issue
Block a user