WIP migrate OSX

This commit is contained in:
Caelan Sayler
2024-09-29 12:17:39 -06:00
committed by Caelan
parent 358de3577e
commit 13f35209ac
9 changed files with 48 additions and 67 deletions

View File

@@ -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");

View File

@@ -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(())
}

View File

@@ -1,6 +1,3 @@
// pub mod bundle;
// pub mod download;
pub mod macho;
pub mod runtime_arch;
mod dialogs_const;

View File

@@ -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());
}

View File

@@ -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);
}

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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> {