From 35407c43632325a3ce02f58ae09b30baff77d2ef Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Thu, 20 Jun 2024 18:34:49 +0200 Subject: [PATCH 1/7] Add apps support --- Cargo.lock | 11 +++++ Cargo.toml | 1 + src/bin/juliaup.rs | 14 +++++- src/cli.rs | 23 ++++++++++ src/command_app_add.rs | 93 +++++++++++++++++++++++++++++++++++++++ src/command_app_remove.rs | 31 +++++++++++++ src/command_app_run.rs | 52 ++++++++++++++++++++++ src/config_file.rs | 29 ++++++++++++ src/lib.rs | 3 ++ src/operations.rs | 67 +++++++++++++++++++++++++++- 10 files changed, 322 insertions(+), 2 deletions(-) create mode 100644 src/command_app_add.rs create mode 100644 src/command_app_remove.rs create mode 100644 src/command_app_run.rs diff --git a/Cargo.lock b/Cargo.lock index 329d3c83..7ea69341 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1026,6 +1026,7 @@ dependencies = [ "tar", "tempfile", "thiserror", + "toml_edit", "url", "windows", "winres", @@ -1906,6 +1907,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", + "winnow", ] [[package]] @@ -2367,6 +2369,15 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +[[package]] +name = "winnow" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index 778fbc4e..d87cb9e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,6 +59,7 @@ indoc = "2.0.3" is-terminal = "0.4.9" path-absolutize = "3.1.0" human-sort = "0.2.2" +toml_edit = "0.22" [target.'cfg(windows)'.dependencies] windows = { version = "0.56.0", features = ["Win32_Foundation", "Win32_UI_Shell", "Win32_System_Console", "Services_Store", "Foundation", "Foundation_Collections", "Web_Http", "Web_Http_Headers", "Storage_Streams",] } diff --git a/src/bin/juliaup.rs b/src/bin/juliaup.rs index 37fcca95..e482a915 100644 --- a/src/bin/juliaup.rs +++ b/src/bin/juliaup.rs @@ -1,7 +1,10 @@ use anyhow::{Context, Result}; use clap::Parser; -use juliaup::cli::{ConfigSubCmd, Juliaup, OverrideSubCmd, SelfSubCmd}; +use juliaup::cli::{ApplicationSubCmd, ConfigSubCmd, Juliaup, OverrideSubCmd, SelfSubCmd}; use juliaup::command_api::run_command_api; +use juliaup::command_app_add::run_command_app_add; +use juliaup::command_app_run::run_command_app_run; +use juliaup::command_app_remove::run_command_app_remove; use juliaup::command_completions::run_command_completions; #[cfg(not(windows))] use juliaup::command_config_symlinks::run_command_config_symlinks; @@ -111,5 +114,14 @@ fn main() -> Result<()> { SelfSubCmd::Uninstall {} => run_command_selfuninstall_unavailable(), }, Juliaup::Completions { shell } => run_command_completions(&shell), + Juliaup::Application(subcmd) => match subcmd { + ApplicationSubCmd::Add { value } => { + run_command_app_add(&value, &paths) + }, + ApplicationSubCmd::Run { name, args } => { + run_command_app_run(&name, &args, &paths) + }, + ApplicationSubCmd::Remove { name } => run_command_app_remove(&name, &paths) + } } } diff --git a/src/cli.rs b/src/cli.rs index f288ce86..2686db5a 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -54,6 +54,9 @@ pub enum Juliaup { #[cfg(feature = "selfupdate")] #[clap(name = "4c79c12db1d34bbbab1f6c6f838f423f", hide = true)] SecretSelfUpdate {}, + #[clap(subcommand, name = "app")] + /// Juliaup applications + Application(ApplicationSubCmd), } #[derive(Parser)] @@ -154,3 +157,23 @@ pub enum ConfigSubCmd { value: Option, }, } + +#[derive(Parser)] +pub enum ApplicationSubCmd { + #[clap(name = "add")] + /// Add a Julia application + Add { + value: String + }, + #[clap(name = "run")] + /// Run a Julia application + Run { + name: String, + args: Vec + }, + #[clap(name = "remove", alias = "rm")] + /// Remove a Julia application + Remove { + name: String + } +} diff --git a/src/command_app_add.rs b/src/command_app_add.rs new file mode 100644 index 00000000..3cefc467 --- /dev/null +++ b/src/command_app_add.rs @@ -0,0 +1,93 @@ +use std::fs; +use std::str::FromStr; + +use crate::config_file::{load_mut_config_db, save_config_db, JuliaupConfigApplication, JuliaupConfigExcutionAlias}; +use crate::global_paths::GlobalPaths; +use crate::operations::{download_file, install_version}; +use crate::versions_file::load_versions_db; +use anyhow::{Context, Result}; +use tempfile::Builder; +use normpath::PathExt; + +pub fn run_command_app_add(url: &str, paths: &GlobalPaths) -> Result<()> { + let download_uri_project = format!("{}/Project.toml", url); + let download_uri_manifest = format!("{}/Manifest.toml", url); + + let temp_dir = Builder::new() + .prefix("julia-temp-app-") + .tempdir_in(&paths.juliauphome) + .expect("Failed to create temporary directory"); + + download_file(&download_uri_project, temp_dir.path(), "Project.toml").unwrap(); + download_file(&download_uri_manifest, temp_dir.path(), "Manifest.toml").unwrap(); + + let project_content = fs::read_to_string(temp_dir.path().join("Project.toml")).unwrap(); + let project_parsed = toml_edit::DocumentMut::from_str(&project_content).unwrap(); + + let manifest_content = fs::read_to_string(temp_dir.path().join("Manifest.toml")).unwrap(); + let manifest_parsed = toml_edit::DocumentMut::from_str(&manifest_content).unwrap(); + + let app_name = project_parsed.as_table().get_key_value("name").unwrap().1.as_str().unwrap(); + let julia_version = manifest_parsed.as_table().get_key_value("julia_version").unwrap().1.as_str().unwrap(); + + let target_path = paths.juliauphome.join("applications").join(app_name); + + let exec_aliases: Vec<(String, String)> = project_parsed + .as_table() + .get_key_value("executionaliases") + .unwrap() + .1 + .clone() + .into_table() + .unwrap() + .iter() + .map(|i| (i.0.to_string(), i.1.clone().into_value().unwrap().as_str().unwrap().to_string())) + .collect(); + + if target_path.exists() { + std::fs::remove_dir_all(&target_path)?; + } + std::fs::create_dir_all(paths.juliauphome.join("applications")).unwrap(); + std::fs::rename(temp_dir.into_path(), &target_path)?; + + let version_db = + load_versions_db(paths).with_context(|| "`add app` command failed to load versions db.")?; + + let asdf = version_db.available_channels.get(julia_version).unwrap(); + + let mut config_file = load_mut_config_db(paths) + .with_context(|| "`app add` command failed to load configuration data.")?; + + install_version(&asdf.version, &mut config_file.data, &version_db, paths).unwrap(); + + config_file.data.installed_apps.insert( + app_name.to_string(), + JuliaupConfigApplication::DirectDownloadApplication { + path: target_path.to_str().unwrap().to_string(), + url: url.to_string(), + local_etag: "".to_string(), + server_etag: "".to_string(), + version: asdf.version.to_string(), + execution_aliases: exec_aliases.iter().map(|i| (i.0.clone(), JuliaupConfigExcutionAlias { target: i.1.to_string() })).collect() + } + ); + + save_config_db(&mut config_file).unwrap(); + + let absolute_path = &paths.juliaupconfig + .parent() + .unwrap() // unwrap OK because there should always be a parent + .join(config_file.data.installed_versions.get(&asdf.version).unwrap().path.clone()) + .join("bin") + .join(format!("julia{}", std::env::consts::EXE_SUFFIX)) + .normalize().unwrap(); + + std::process::Command::new(absolute_path) + .env("JULIA_PROJECT", target_path) + .arg("-e") + .arg("using Pkg; Pkg.instantiate()") + .status() + .unwrap(); + + return Ok(()) +} diff --git a/src/command_app_remove.rs b/src/command_app_remove.rs new file mode 100644 index 00000000..6d21f7de --- /dev/null +++ b/src/command_app_remove.rs @@ -0,0 +1,31 @@ +use std::fs; + +use anyhow::{Context,Result}; + +use crate::{config_file::{load_mut_config_db, save_config_db, JuliaupConfigApplication}, global_paths::GlobalPaths, operations::garbage_collect_versions}; + +pub fn run_command_app_remove(name: &str, paths: &GlobalPaths) -> Result<()> { + let mut config_file = load_mut_config_db(paths) + .with_context(|| "`app remove` command failed to load configuration data.")?; + + if !config_file.data.installed_apps.contains_key(name) { + println!("Unknown app {}.", name); + } + else { + let install_path = match &config_file.data.installed_apps.get(name).unwrap() { + JuliaupConfigApplication::DirectDownloadApplication { path, url: _, local_etag: _, server_etag: _, version: _, execution_aliases: _ } => { + path + } + }; + + fs::remove_dir_all(install_path).unwrap(); + + config_file.data.installed_apps.remove(name).unwrap(); + + garbage_collect_versions(&mut config_file.data, paths).unwrap(); + + save_config_db(&mut config_file).unwrap(); + } + + return Ok(()) +} diff --git a/src/command_app_run.rs b/src/command_app_run.rs new file mode 100644 index 00000000..8a4c900a --- /dev/null +++ b/src/command_app_run.rs @@ -0,0 +1,52 @@ +use std::collections::HashMap; + +use crate::{config_file::{load_config_db, JuliaupConfigApplication}, global_paths::GlobalPaths}; +use anyhow::{Context,Result}; +use normpath::PathExt; + +pub fn run_command_app_run(name: &str, args: &Vec, paths: &GlobalPaths) -> Result<()> { + + let config_file = load_config_db(paths) + .with_context(|| "`app run` command failed to load configuration data.")?; + + let target: HashMap = config_file + .data + .installed_apps + .iter() + .flat_map(|i| match&i.1 { + JuliaupConfigApplication::DirectDownloadApplication { path, url: _, local_etag: _, server_etag: _, version, execution_aliases } => execution_aliases.iter().map(|j| (j.0.clone(), (j.1.target.clone(), path.clone(), version.clone()))) + }) + .map(|i| (i.0.clone(), (i.1.0.clone(), i.1.1.clone(), i.1.2.clone()))) + .collect(); + + if target.contains_key(name) { + let foo = target.get(name).unwrap(); + + let parts: Vec<&str> = foo.0.split(".").collect(); + + // println!("First arg {}, second arg {}", foo.0, foo.1) + + let target_path = foo.1.clone(); + + let absolute_path = &paths.juliaupconfig + .parent() + .unwrap() // unwrap OK because there should always be a parent + .join(config_file.data.installed_versions.get(&foo.2).unwrap().path.clone()) + .join("bin") + .join(format!("julia{}", std::env::consts::EXE_SUFFIX)) + .normalize().unwrap(); + + std::process::Command::new(absolute_path) + .env("JULIA_PROJECT", target_path) + .arg("-e") + .arg(format!("import {}; {}(ARGS)", parts[0], foo.0)) + .args(args) + .status() + .unwrap(); + + } + else { + println!("Could not find app."); + } + return Ok(()) +} diff --git a/src/config_file.rs b/src/config_file.rs index 0928d9aa..435880ef 100644 --- a/src/config_file.rs +++ b/src/config_file.rs @@ -53,6 +53,31 @@ pub enum JuliaupConfigChannel { }, } +#[derive(Serialize, Deserialize, Clone)] +pub struct JuliaupConfigExcutionAlias { + #[serde(rename = "Target")] + pub target: String +} + +#[derive(Serialize, Deserialize, Clone)] +#[serde(untagged)] +pub enum JuliaupConfigApplication { + DirectDownloadApplication { + #[serde(rename = "Path")] + path: String, + #[serde(rename = "Url")] + url: String, + #[serde(rename = "LocalETag")] + local_etag: String, + #[serde(rename = "ServerETag")] + server_etag: String, + #[serde(rename = "Version")] + version: String, + #[serde(rename = "ExecutionAliases")] + execution_aliases: HashMap + }, +} + #[derive(Serialize, Deserialize, Clone)] pub struct JuliaupConfigSettings { #[serde( @@ -94,6 +119,8 @@ pub struct JuliaupConfig { pub installed_versions: HashMap, #[serde(rename = "InstalledChannels")] pub installed_channels: HashMap, + #[serde(rename = "InstalledApplications", default)] + pub installed_apps: HashMap, #[serde(rename = "Settings", default)] pub settings: JuliaupConfigSettings, #[serde(rename = "Overrides", default)] @@ -186,6 +213,7 @@ pub fn load_config_db(paths: &GlobalPaths) -> Result default: None, installed_versions: HashMap::new(), installed_channels: HashMap::new(), + installed_apps: HashMap::new(), overrides: Vec::new(), settings: JuliaupConfigSettings { create_channel_symlinks: false, @@ -282,6 +310,7 @@ pub fn load_mut_config_db(paths: &GlobalPaths) -> Result { default: None, installed_versions: HashMap::new(), installed_channels: HashMap::new(), + installed_apps: HashMap::new(), overrides: Vec::new(), settings: JuliaupConfigSettings { create_channel_symlinks: false, diff --git a/src/lib.rs b/src/lib.rs index 92675479..4ec3101d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,9 @@ use anyhow::Context; pub mod cli; pub mod command_add; pub mod command_api; +pub mod command_app_add; +pub mod command_app_run; +pub mod command_app_remove; pub mod command_completions; pub mod command_config_backgroundselfupdate; pub mod command_config_modifypath; diff --git a/src/operations.rs b/src/operations.rs index 8ff0e638..a02bd056 100644 --- a/src/operations.rs +++ b/src/operations.rs @@ -1,6 +1,7 @@ use crate::config_file::load_mut_config_db; use crate::config_file::save_config_db; use crate::config_file::JuliaupConfig; +use crate::config_file::JuliaupConfigApplication; use crate::config_file::JuliaupConfigChannel; use crate::config_file::JuliaupConfigVersion; use crate::get_bundled_dbversion; @@ -186,6 +187,68 @@ pub fn download_extract_sans_parent( Ok(last_modified) } +#[cfg(not(windows))] +pub fn download_filed( + url: &str, + target_path: &Path, + filename: &str +) -> Result { + log::debug!("Downloading from url `{}`.", url); + let response = reqwest::blocking::get(url) + .with_context(|| format!("Failed to download from url `{}`.", url))?; + + let mut file = std::fs::File::create(target_path)?; + let mut content = Cursor::new(response.bytes().get()); + std::io::copy(&mut content, &mut file)?; + + Ok(()) +} + +#[cfg(windows)] +pub fn download_file( + url: &str, + target_path: &Path, + filename: &str +) -> Result { + use windows::{core::HSTRING, Storage::FileAccessMode}; + + let http_client = + windows::Web::Http::HttpClient::new().with_context(|| "Failed to create HttpClient.")?; + + let request_uri = windows::Foundation::Uri::CreateUri(&windows::core::HSTRING::from(url)) + .with_context(|| "Failed to convert url string to Uri.")?; + + let http_response = http_client + .GetAsync(&request_uri) + .with_context(|| "Failed to initiate download.")? + .get() + .with_context(|| "Failed to complete async download operation.")?; + + http_response + .EnsureSuccessStatusCode() + .with_context(|| "HTTP download reported error status code.")?; + + let last_modified = http_response + .Headers() + .unwrap() + .Lookup(&HSTRING::from("etag")) + .unwrap() + .to_string(); + + let http_response_content = http_response + .Content() + .with_context(|| "Failed to obtain content from http response.")?; + + let folder = windows::Storage::StorageFolder::GetFolderFromPathAsync(&HSTRING::from(target_path)).unwrap().get().unwrap(); + let file = folder.CreateFileAsync(&HSTRING::from(filename), windows::Storage::CreationCollisionOption::ReplaceExisting).unwrap().get().unwrap(); + + let stream = file.OpenAsync(FileAccessMode::ReadWrite).unwrap().get().unwrap(); + + http_response_content.WriteToStreamAsync(&stream).unwrap().get().unwrap(); + + Ok(last_modified) +} + #[cfg(not(windows))] pub fn download_juliaup_version(url: &str) -> Result { let response = reqwest::blocking::get(url) @@ -547,7 +610,9 @@ pub fn garbage_collect_versions( server_etag: _, version: _, } => true, - }) { + }) && config_data.installed_apps.iter().all(|j| match &j.1 { + JuliaupConfigApplication::DirectDownloadApplication { path: _, url: _, local_etag: _, server_etag: _, version, execution_aliases: _ } => version != installed_version + } ) { let path_to_delete = paths.juliauphome.join(&detail.path); let display = path_to_delete.display(); From f420491db863870278591c0d786ca94a80900544 Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Thu, 20 Jun 2024 19:00:39 +0200 Subject: [PATCH 2/7] Fix app download on Linux --- src/operations.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/operations.rs b/src/operations.rs index a02bd056..ee9e71ff 100644 --- a/src/operations.rs +++ b/src/operations.rs @@ -188,17 +188,17 @@ pub fn download_extract_sans_parent( } #[cfg(not(windows))] -pub fn download_filed( +pub fn download_file( url: &str, target_path: &Path, filename: &str -) -> Result { +) -> Result<()> { log::debug!("Downloading from url `{}`.", url); let response = reqwest::blocking::get(url) .with_context(|| format!("Failed to download from url `{}`.", url))?; - let mut file = std::fs::File::create(target_path)?; - let mut content = Cursor::new(response.bytes().get()); + let mut file = std::fs::File::create(target_path.join(filename))?; + let mut content = std::io::Cursor::new(response.bytes().unwrap()); std::io::copy(&mut content, &mut file)?; Ok(()) From 414559e1e792b2cb3952723672e085259b7bb8aa Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Thu, 20 Jun 2024 23:00:20 +0200 Subject: [PATCH 3/7] Handle multi depot scenario for apps --- src/command_app_add.rs | 31 +++++++++++++++++++++---------- src/command_app_remove.rs | 2 +- src/command_app_run.rs | 11 ++++++----- src/config_file.rs | 6 ++++-- src/operations.rs | 2 +- 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/command_app_add.rs b/src/command_app_add.rs index 3cefc467..5a749c59 100644 --- a/src/command_app_add.rs +++ b/src/command_app_add.rs @@ -6,6 +6,7 @@ use crate::global_paths::GlobalPaths; use crate::operations::{download_file, install_version}; use crate::versions_file::load_versions_db; use anyhow::{Context, Result}; +use bstr::ByteVec; use tempfile::Builder; use normpath::PathExt; @@ -60,6 +61,22 @@ pub fn run_command_app_add(url: &str, paths: &GlobalPaths) -> Result<()> { install_version(&asdf.version, &mut config_file.data, &version_db, paths).unwrap(); + let julia_binary_path = &paths.juliaupconfig + .parent() + .unwrap() // unwrap OK because there should always be a parent + .join(config_file.data.installed_versions.get(&asdf.version).unwrap().path.clone()) + .join("bin") + .join(format!("julia{}", std::env::consts::EXE_SUFFIX)) + .normalize().unwrap(); + + let depot_detection_output = std::process::Command::new(julia_binary_path) + .arg("-e") + .arg("println(Base.DEPOT_PATH[1])") + .output() + .unwrap(); + + let depot_detection_output = depot_detection_output.stdout.into_string().unwrap().trim().to_string(); + config_file.data.installed_apps.insert( app_name.to_string(), JuliaupConfigApplication::DirectDownloadApplication { @@ -67,22 +84,16 @@ pub fn run_command_app_add(url: &str, paths: &GlobalPaths) -> Result<()> { url: url.to_string(), local_etag: "".to_string(), server_etag: "".to_string(), - version: asdf.version.to_string(), + julia_version: asdf.version.to_string(), + julia_depot: depot_detection_output, execution_aliases: exec_aliases.iter().map(|i| (i.0.clone(), JuliaupConfigExcutionAlias { target: i.1.to_string() })).collect() } ); save_config_db(&mut config_file).unwrap(); - let absolute_path = &paths.juliaupconfig - .parent() - .unwrap() // unwrap OK because there should always be a parent - .join(config_file.data.installed_versions.get(&asdf.version).unwrap().path.clone()) - .join("bin") - .join(format!("julia{}", std::env::consts::EXE_SUFFIX)) - .normalize().unwrap(); - - std::process::Command::new(absolute_path) + + std::process::Command::new(julia_binary_path) .env("JULIA_PROJECT", target_path) .arg("-e") .arg("using Pkg; Pkg.instantiate()") diff --git a/src/command_app_remove.rs b/src/command_app_remove.rs index 6d21f7de..9517180a 100644 --- a/src/command_app_remove.rs +++ b/src/command_app_remove.rs @@ -13,7 +13,7 @@ pub fn run_command_app_remove(name: &str, paths: &GlobalPaths) -> Result<()> { } else { let install_path = match &config_file.data.installed_apps.get(name).unwrap() { - JuliaupConfigApplication::DirectDownloadApplication { path, url: _, local_etag: _, server_etag: _, version: _, execution_aliases: _ } => { + JuliaupConfigApplication::DirectDownloadApplication { path, url: _, local_etag: _, server_etag: _, julia_version: _, julia_depot: _, execution_aliases: _ } => { path } }; diff --git a/src/command_app_run.rs b/src/command_app_run.rs index 8a4c900a..876b15ed 100644 --- a/src/command_app_run.rs +++ b/src/command_app_run.rs @@ -9,14 +9,14 @@ pub fn run_command_app_run(name: &str, args: &Vec, paths: &GlobalPaths) let config_file = load_config_db(paths) .with_context(|| "`app run` command failed to load configuration data.")?; - let target: HashMap = config_file + let target: HashMap = config_file .data .installed_apps .iter() .flat_map(|i| match&i.1 { - JuliaupConfigApplication::DirectDownloadApplication { path, url: _, local_etag: _, server_etag: _, version, execution_aliases } => execution_aliases.iter().map(|j| (j.0.clone(), (j.1.target.clone(), path.clone(), version.clone()))) + JuliaupConfigApplication::DirectDownloadApplication { path, url: _, local_etag: _, server_etag: _, julia_version, julia_depot, execution_aliases } => execution_aliases.iter().map(|j| (j.0.clone(), (j.1.target.clone(), path.clone(), julia_version.clone(), julia_depot.clone()))) }) - .map(|i| (i.0.clone(), (i.1.0.clone(), i.1.1.clone(), i.1.2.clone()))) + .map(|i| (i.0.clone(), (i.1.0.clone(), i.1.1.clone(), i.1.2.clone(), i.1.3.clone()))) .collect(); if target.contains_key(name) { @@ -28,7 +28,7 @@ pub fn run_command_app_run(name: &str, args: &Vec, paths: &GlobalPaths) let target_path = foo.1.clone(); - let absolute_path = &paths.juliaupconfig + let julia_binary_path = &paths.juliaupconfig .parent() .unwrap() // unwrap OK because there should always be a parent .join(config_file.data.installed_versions.get(&foo.2).unwrap().path.clone()) @@ -36,8 +36,9 @@ pub fn run_command_app_run(name: &str, args: &Vec, paths: &GlobalPaths) .join(format!("julia{}", std::env::consts::EXE_SUFFIX)) .normalize().unwrap(); - std::process::Command::new(absolute_path) + std::process::Command::new(julia_binary_path) .env("JULIA_PROJECT", target_path) + .env("JULIA_DEPOT_PATH", foo.3.clone()) .arg("-e") .arg(format!("import {}; {}(ARGS)", parts[0], foo.0)) .args(args) diff --git a/src/config_file.rs b/src/config_file.rs index 435880ef..8211b438 100644 --- a/src/config_file.rs +++ b/src/config_file.rs @@ -71,8 +71,10 @@ pub enum JuliaupConfigApplication { local_etag: String, #[serde(rename = "ServerETag")] server_etag: String, - #[serde(rename = "Version")] - version: String, + #[serde(rename = "JuliaVersion")] + julia_version: String, + #[serde(rename = "JuliaDepot")] + julia_depot: String, #[serde(rename = "ExecutionAliases")] execution_aliases: HashMap }, diff --git a/src/operations.rs b/src/operations.rs index ee9e71ff..01106c6d 100644 --- a/src/operations.rs +++ b/src/operations.rs @@ -611,7 +611,7 @@ pub fn garbage_collect_versions( version: _, } => true, }) && config_data.installed_apps.iter().all(|j| match &j.1 { - JuliaupConfigApplication::DirectDownloadApplication { path: _, url: _, local_etag: _, server_etag: _, version, execution_aliases: _ } => version != installed_version + JuliaupConfigApplication::DirectDownloadApplication { path: _, url: _, local_etag: _, server_etag: _, julia_version, julia_depot: _, execution_aliases: _ } => julia_version != installed_version } ) { let path_to_delete = paths.juliauphome.join(&detail.path); let display = path_to_delete.display(); From 501e3b656a0c1c0427da7ee1d87d685db50b1c0c Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Fri, 16 Aug 2024 15:07:49 -0700 Subject: [PATCH 4/7] Remove download option --- src/command_app_add.rs | 40 +++++++++++---------------------------- src/command_app_remove.rs | 12 +----------- src/command_app_run.rs | 5 +++-- src/config_file.rs | 8 +------- src/operations.rs | 2 +- 5 files changed, 17 insertions(+), 50 deletions(-) diff --git a/src/command_app_add.rs b/src/command_app_add.rs index 5a749c59..7eae1e69 100644 --- a/src/command_app_add.rs +++ b/src/command_app_add.rs @@ -1,38 +1,30 @@ use std::fs; +use std::path::PathBuf; use std::str::FromStr; use crate::config_file::{load_mut_config_db, save_config_db, JuliaupConfigApplication, JuliaupConfigExcutionAlias}; use crate::global_paths::GlobalPaths; -use crate::operations::{download_file, install_version}; +use crate::operations::install_version; use crate::versions_file::load_versions_db; use anyhow::{Context, Result}; use bstr::ByteVec; -use tempfile::Builder; use normpath::PathExt; -pub fn run_command_app_add(url: &str, paths: &GlobalPaths) -> Result<()> { - let download_uri_project = format!("{}/Project.toml", url); - let download_uri_manifest = format!("{}/Manifest.toml", url); +pub fn run_command_app_add(path: &str, paths: &GlobalPaths) -> Result<()> { + let app_folder_path = PathBuf::from(path); - let temp_dir = Builder::new() - .prefix("julia-temp-app-") - .tempdir_in(&paths.juliauphome) - .expect("Failed to create temporary directory"); + let project_path = app_folder_path.join("Project.toml"); + let manifest_path = app_folder_path.join("Manifest.toml"); - download_file(&download_uri_project, temp_dir.path(), "Project.toml").unwrap(); - download_file(&download_uri_manifest, temp_dir.path(), "Manifest.toml").unwrap(); - - let project_content = fs::read_to_string(temp_dir.path().join("Project.toml")).unwrap(); + let project_content = fs::read_to_string(project_path).unwrap(); let project_parsed = toml_edit::DocumentMut::from_str(&project_content).unwrap(); - let manifest_content = fs::read_to_string(temp_dir.path().join("Manifest.toml")).unwrap(); + let manifest_content = fs::read_to_string(&manifest_path).unwrap(); let manifest_parsed = toml_edit::DocumentMut::from_str(&manifest_content).unwrap(); let app_name = project_parsed.as_table().get_key_value("name").unwrap().1.as_str().unwrap(); let julia_version = manifest_parsed.as_table().get_key_value("julia_version").unwrap().1.as_str().unwrap(); - let target_path = paths.juliauphome.join("applications").join(app_name); - let exec_aliases: Vec<(String, String)> = project_parsed .as_table() .get_key_value("executionaliases") @@ -45,12 +37,6 @@ pub fn run_command_app_add(url: &str, paths: &GlobalPaths) -> Result<()> { .map(|i| (i.0.to_string(), i.1.clone().into_value().unwrap().as_str().unwrap().to_string())) .collect(); - if target_path.exists() { - std::fs::remove_dir_all(&target_path)?; - } - std::fs::create_dir_all(paths.juliauphome.join("applications")).unwrap(); - std::fs::rename(temp_dir.into_path(), &target_path)?; - let version_db = load_versions_db(paths).with_context(|| "`add app` command failed to load versions db.")?; @@ -79,11 +65,8 @@ pub fn run_command_app_add(url: &str, paths: &GlobalPaths) -> Result<()> { config_file.data.installed_apps.insert( app_name.to_string(), - JuliaupConfigApplication::DirectDownloadApplication { - path: target_path.to_str().unwrap().to_string(), - url: url.to_string(), - local_etag: "".to_string(), - server_etag: "".to_string(), + JuliaupConfigApplication::DevedApplication { + path: app_folder_path.to_str().unwrap().to_string(), julia_version: asdf.version.to_string(), julia_depot: depot_detection_output, execution_aliases: exec_aliases.iter().map(|i| (i.0.clone(), JuliaupConfigExcutionAlias { target: i.1.to_string() })).collect() @@ -91,10 +74,9 @@ pub fn run_command_app_add(url: &str, paths: &GlobalPaths) -> Result<()> { ); save_config_db(&mut config_file).unwrap(); - std::process::Command::new(julia_binary_path) - .env("JULIA_PROJECT", target_path) + .env("JULIA_PROJECT", &app_folder_path) .arg("-e") .arg("using Pkg; Pkg.instantiate()") .status() diff --git a/src/command_app_remove.rs b/src/command_app_remove.rs index 9517180a..55c3720f 100644 --- a/src/command_app_remove.rs +++ b/src/command_app_remove.rs @@ -1,8 +1,6 @@ -use std::fs; - use anyhow::{Context,Result}; -use crate::{config_file::{load_mut_config_db, save_config_db, JuliaupConfigApplication}, global_paths::GlobalPaths, operations::garbage_collect_versions}; +use crate::{config_file::{load_mut_config_db, save_config_db}, global_paths::GlobalPaths, operations::garbage_collect_versions}; pub fn run_command_app_remove(name: &str, paths: &GlobalPaths) -> Result<()> { let mut config_file = load_mut_config_db(paths) @@ -12,14 +10,6 @@ pub fn run_command_app_remove(name: &str, paths: &GlobalPaths) -> Result<()> { println!("Unknown app {}.", name); } else { - let install_path = match &config_file.data.installed_apps.get(name).unwrap() { - JuliaupConfigApplication::DirectDownloadApplication { path, url: _, local_etag: _, server_etag: _, julia_version: _, julia_depot: _, execution_aliases: _ } => { - path - } - }; - - fs::remove_dir_all(install_path).unwrap(); - config_file.data.installed_apps.remove(name).unwrap(); garbage_collect_versions(&mut config_file.data, paths).unwrap(); diff --git a/src/command_app_run.rs b/src/command_app_run.rs index 876b15ed..13c06bb7 100644 --- a/src/command_app_run.rs +++ b/src/command_app_run.rs @@ -14,7 +14,7 @@ pub fn run_command_app_run(name: &str, args: &Vec, paths: &GlobalPaths) .installed_apps .iter() .flat_map(|i| match&i.1 { - JuliaupConfigApplication::DirectDownloadApplication { path, url: _, local_etag: _, server_etag: _, julia_version, julia_depot, execution_aliases } => execution_aliases.iter().map(|j| (j.0.clone(), (j.1.target.clone(), path.clone(), julia_version.clone(), julia_depot.clone()))) + JuliaupConfigApplication::DevedApplication { path, julia_version, julia_depot, execution_aliases } => execution_aliases.iter().map(|j| (j.0.clone(), (j.1.target.clone(), path.clone(), julia_version.clone(), julia_depot.clone()))) }) .map(|i| (i.0.clone(), (i.1.0.clone(), i.1.1.clone(), i.1.2.clone(), i.1.3.clone()))) .collect(); @@ -37,7 +37,8 @@ pub fn run_command_app_run(name: &str, args: &Vec, paths: &GlobalPaths) .normalize().unwrap(); std::process::Command::new(julia_binary_path) - .env("JULIA_PROJECT", target_path) + .arg(format!("--project={}", target_path)) + // .env("JULIA_PROJECT", target_path) .env("JULIA_DEPOT_PATH", foo.3.clone()) .arg("-e") .arg(format!("import {}; {}(ARGS)", parts[0], foo.0)) diff --git a/src/config_file.rs b/src/config_file.rs index 8211b438..0d3e80a5 100644 --- a/src/config_file.rs +++ b/src/config_file.rs @@ -62,15 +62,9 @@ pub struct JuliaupConfigExcutionAlias { #[derive(Serialize, Deserialize, Clone)] #[serde(untagged)] pub enum JuliaupConfigApplication { - DirectDownloadApplication { + DevedApplication { #[serde(rename = "Path")] path: String, - #[serde(rename = "Url")] - url: String, - #[serde(rename = "LocalETag")] - local_etag: String, - #[serde(rename = "ServerETag")] - server_etag: String, #[serde(rename = "JuliaVersion")] julia_version: String, #[serde(rename = "JuliaDepot")] diff --git a/src/operations.rs b/src/operations.rs index 47e1c597..a121d862 100644 --- a/src/operations.rs +++ b/src/operations.rs @@ -684,7 +684,7 @@ pub fn garbage_collect_versions( version: _, } => true, }) && config_data.installed_apps.iter().all(|j| match &j.1 { - JuliaupConfigApplication::DirectDownloadApplication { path: _, url: _, local_etag: _, server_etag: _, julia_version, julia_depot: _, execution_aliases: _ } => julia_version != installed_version + JuliaupConfigApplication::DevedApplication { path: _, julia_version, julia_depot: _, execution_aliases: _ } => julia_version != installed_version } ) { let path_to_delete = paths.juliauphome.join(&detail.path); let display = path_to_delete.display(); From 50ea0b677f65586378e711232f0693f489ed5114 Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Mon, 19 Aug 2024 10:37:12 -0700 Subject: [PATCH 5/7] Change how sparse package is created --- deploy/winpkgidentityext/create-msix.ps1 | 2 ++ deploy/winpkgidentityext/juliaup.msix | Bin 12060 -> 0 bytes 2 files changed, 2 insertions(+) delete mode 100644 deploy/winpkgidentityext/juliaup.msix diff --git a/deploy/winpkgidentityext/create-msix.ps1 b/deploy/winpkgidentityext/create-msix.ps1 index 4aaf6147..45054748 100644 --- a/deploy/winpkgidentityext/create-msix.ps1 +++ b/deploy/winpkgidentityext/create-msix.ps1 @@ -22,3 +22,5 @@ $params = @{ } Invoke-TrustedSigning @params + +Move-Item .\juliaup.msix ..\..\target\debug\ -Force diff --git a/deploy/winpkgidentityext/juliaup.msix b/deploy/winpkgidentityext/juliaup.msix deleted file mode 100644 index 6c117e524469b2d69f50421268ebeb27ffe65da4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12060 zcmZ{~V~{4_((c{1r)}G|?P;6Swr$(CZQFMDwEJ$`#v|HF{}#zOY??sA5<7N#an&h+j!)|VPG$|M{}y~-`$ zLK!0RYsSVyrg(8}8lX63)53=6^c~??hBQ?PrcXdg`gy6xhBIrNS82L%hmO4{$X)Q7M&=!KIDlekA+m z;s$c){ym<_@={R`95PX#rF|0~G8?%v9(CMHgn zd|0Dq8$Wfu1boX2ILC$5FKj-Cw7 zN5Hf&0|&88j$cYyByLNGpM*-=Fc$fBh+~tftm9G)*-HeGf1qV3pZ1sG4YXBY%*UES zj73L`EtQZb8ndJ8h#W;Xv;M-g{b_#&ZT03LLqSS{8_DqO=o)jBZ9e`ZW&%r|ie~Db z-7e@^>e|_VmP#KjvL@*|OnwKx!l|2$=Bx7!$L#Lip~sLTQAit_ZDq{t(!oK#@hgJ zk6H!^?P?9|MjImbh*9Ynp(zYbxTAJE0?9Pu=RmSRMcQVjru^v*+vb>U5C8-Lq7I=!PnI_h zBA^Id20pyO;|~ZlI_aK-+)&C9nvUYuQTFj#S-V}iU-+s!Xy zf44QL@LJOxoNAOuO^*JZtYNCvbor9@`32Es3DAsDGrew?ALnD2)dv-*A%y}g20wOQ z)UvMN#QM{~5Me9AHzuLQYpni+BgtIwEPdi6D8y@}J)+aE6caTusc ztfX?M#=zC|KrKJUg4`3>;9Ws9hJ;;?E;BrEcaOU1*qXw!Ja&Q*t3_|pKmqwo>!hcT zTmR9aEK)V&wCj0O9qdYMf8^4k{aLZ>==BVdf*aF7?nIQQSMTBIFH+R&cJf zTS>ar4^@UszEP5|Q}_BYEtsPbdn;+m_tG=q;527y6uH1vZbkH>cdL9o68dNz#-LL9 z!{X2^tciMfZd5h%L>B@vXPd+v8VnS74XUZthY?gOP~@e3EhhU_wtiSX=R> zSHym%{b$vY>Z%qvya+>>wprK&yDVZ-4`2%@tW`dCe=^2ET5zYtCG}e$J}3n(dki&~ zNOwsLIIQY5PU@%n8xxiHZd(qj$xGi;H07uJXRR-Q18Q_!mmCoA1IB*~m?N*V{7Yk4j=Vq=oVN-yCR-lWWwx zlSliF$199E?J=QPM|^9&NKEZMo7_4rAjtI1ego>p2-Z9sHMM-x-~@Ui38L_oTPM)7 zZtA|}_A+~K)u21lF}vSpdfX#>pxV0TOwdHN88g0o<}MyI1oZND+|G{u^;gdS=sZ}t zmrwjx_kS$;-~Jz+|B)OD=pUWIA4Awr|Bhn+&i?r8wMFb~olR_=^;JCVO`LT9CG~{- z5F?V{jpRqr5lti>Cy=lM^$Jdu=$rpQMzPvegNZ`bIW`XOd%5>ej^_L25H8(rg$^{Vu2S=yLH8hK=(c?4oeoNN#yjhfC@o;9B2t>o z9%H+@@Gu#j2I^4Gy^-6+dJXr2h^yTToMNeWPhNL%e;Yocr1D#c0Mn1{oZh;E4nTHHT?>H z^CG=%ExqkAzAODK6u97ZF)j?ocZ<%#;^g|!>`>ZsWlB~~OU?)bn+2P$j$)fuhex)l z=7O}R=UQib&hG!>Z#9~1nf4n`xV9o%q6ZbQPy0#O*SNW{x7 zayfOI2xuNG_MCriX*-e7vpP(Ed0ovm)9pw3r>#vDz^5 zbhOqsp6rVvRPWT#b-dvF#Ou7oLLp$Ym=wyp07-}Zuqj^^KS>8t~`3Qd2@WJ z?Q~o!rioD~rDy9V?!0VuUq+Y;Ez@-Kdb#objV(xPF*>3V0J zLo_L!4TiEqxetH19I%@(seqWujo-fY809#=gY!-N$Yn;c2 zAqZSAZ9U={fO+acxdBs*lNylwP^MyjzZ~8^| z?3Ll$J4qikA)qifR=%)V zj%YeFu3q!g4&1mf$EL8n)hp&9?tDrtaExkER0{l*tb#^mOgK#}1iuQnYQu!&$y~vs zdzxT5-lZXl&l(ZmO0tG&L9yh!wbtzhAS!)@SBogMMDq*Sxzo;twzriFei1Isy{Vl) zivyKu7?-_!5w!Euo?a!N8)S2G+}O+pFt<(eope7IlUxY%#E?KRD&{}G9V7@?DGAY? z=p~z~3=_NXyx7YC#gVhhQlH3--eRfh>Xs6DDg&b$-)g>*L|D~-q)nXFxkqTf+9br< zY5gL{6a%qS;8XT}r6mc0m)~_7^?|z-bLx!vIY}068xUQy$k65>qQ-M3^G2Yl66UEF{(VtpT^n7V3V%v-PRN9 z^pmiK8_+3dHQcu#A92;%qH8Aol3L*;)~TSvI9+}_5GD)+{SHOApqI1Z#K{0vZG|?b zc}ljHZVe2QBiYAs2H`j7*a%u(mYVbxeU$uW%ThyYQPN^gwp?scLS_Lx%%GNqh$Nh0 zf$u9MIKSIP`JoGj>$}MTE$B>aFnFgj0|3m>S@QvEczL&wPkvevq{IP_C8nyREUF|Y zq>06Y43`}YtKT~}v#8&8j|x?tS`R!G0sVOg0fMIg2r7Zt5!JM`hXaE~045tsm)YTA zCfAa=skM#d*{oQ)2Z!4-Iy|a?la=w0^pum=vHjxCW476PB_3dTJW^@kZksI`uMqBN z|FKVZu$^f7?_A zwzVj2K6~oc)GJt!?x}&wxPmU#UoHw3mU#Kb$lf54=`eHnXGNSAd_4Rm1Ew{n+Thz& zvsmy^#({SA!q`6a!4aHV!6_}$hecalGwhITyZbG1p2oR;?)*TeA@QynNN7044;b+| zQx7avtF-61nRFnSBZmmMYULm9@O2kG3jg2oAy-vt8{jT6F9V*P-G0r z@T|rQfmT-0Ck4j3mFGvxLRl&bbb(+)5?KGI1s)O5XeB1*UvO%%ixi`P=OiqXOuOAq-(yGx6+%fx4-VS&a><(tRAyn7bwO>eSJEEj4_u zl{X0gvNUVmd8P zxAtgz$Is8t$BusrFm%xA<+o}PT-!>;i;)=LOSzNPe`dE zI)R|*f71z$=Md~b!->O6K?*AYPZ4kdkqX~1bcu1%U;FhLBlG3-Kh-t@F{YIkU~ zcYW2CCDHc(`6X<=APa0P2panCbFC^2I$$7(g7m$B4kkPJu1=CF)G}6Madf_Kd$PBG zJY{mR2WBv6z)sX&&i)Y>@W&ZL0&Bx7Mr`msH-CS*>JDGp;In01bW1$Q z{m6CUj^Z@H*aC&W0}eVvD+xyLmlj;< zi_jD(%@c`!s9m|huWtC@m5Vu8jC%euegxmABRjBZmM#Uq8!O+b2l#kQ1l5gP#Wy|l z^EfZ(ieg{9N#b!YY-_;l&$qmbaH>}ajjNZaw>sQj4Simlx5@NY;Ns3WseEme-vo0d zh_EbajBdL0HGOBHLJs81%>dmcd~$kwrTR#0db6vZL+6F+8dV%s>29)xN&Zj`<< z$vyVUv|ZIkZ6j?A|Ln9+kxaeV{Tli#JA+D1+mQcLvN94iI2?hq3i_x6y_1zVvVp!k z=Me_iO&vRy)bZ#&$+q75Tab=h8o4~EYk?t!$#!R+rQ8zpLNjSI?2a+xak4$_X7Tc1 z*aS=&D+Un9c!hfpz{!>GT)@XS%CaJrxX@+Wr>-Ri?mEFug?!?fB;`PLI|MVOO-d}J zhZG=Q?*1igU&Fg5bk_OV7x7}Z|C#0fO}_oF@LQM{4iqSY{wc|w5Gm9k+i<{YsQu^s z1mfsTgxTFo_!#7EHb}@P0n*&aVx-#C?CARJdZ-#6I6uDs391j2KjJ_X(xKSxLr%WJ zZuF~uB%m*Hkj>jBtkJ-kO~2P8)(*e+w&Up3d!lOWGLCOT5FuTmdh&wSk%?@|n`kBy zVk`O4h;)9rkpdTZ!P|6ZIr8LOSLF|wwX-Op$cH*enl??^yJ0}&1^2cUL$FwErXE|; z1u!m{w~lCOmg!asZg{jTRVE)O8(U>}YdD05k`oQd^j#kysgXUwI?XB&I}6>+vnVn_G69lK0JJx~XdY zo_v^%8eO%-n`#AHb-~o61@Q@G&w;$eoUNeA03OnMilf+j;&`jnV6!5x*me%MHPHo( zCuUO~#ZcjS$g1U-{91vHFBkIuM)cl5dmZ5zKYT+msWCREt0kNIb+q$J{(A)mzQq&` z^j2&K8~jeDu-|mmAWGK5Ao(Z2YJvG=qwHABPPgmF=|%3^VwI_GEWC9(*|zdP(~+|M zd4Bw~n-fb*7rsQIgL?p0MD9z)aJ7uBHCmvC36miGa+OnM%tHG84yaMIEh12C8 z?rSpVA=f!e`O9-w!Y_ohZpkJCXkVpI+yT(Y<){A^#9{>=GMA|hl$-*80=Urv~!NUS=R*74}$ zKb+x7;S<4TzaQZlficeyenp#Qd}<}Og!=anIt7}G127Q5|8eqg}4{OP*|T>wTQ zC9&>`-PlDknb%7~lin*Yd>{O)Hs1jMFsZGMs5MdRr2xY&m zJvBt~74kncvOPo!yd5Tbb;``kI$Hekc$MqZBm*08RZVT!`%J?}1eO{oxvHHMFRDxe zdPD_NjE3m?99M-rO4cTaka zGtCqq8neJW)-0=%aRWEM^XAwl*f#oLubo(a)(#v_r$3aQop}T(Bp5daYTm4pf+7~iQvIAimiA>vRmtH~g?Bv%t8 zY&tLtw6)Kr(yLLYyRp=`K?WLborqE6c>u!y$Z3{2u!(RnJc`#WGts+_n7ilZ`IT>7 z(}tGKPniUrap$LIv0|JEo9vyha-kh78999BY!->NhO>s&&SPH`=zeVCm;R#cJT5%N zc1W#F5c3xMazml~&aVBg$ugqc2Z2(_%!3p}PE+4i5zP+&#=iVU^Ca-LtRs&z%J8eY zDl0rS532}Lt@5}mYu>!eO*pE8ui&UUfB(&(f3vJFBPI^3;_V;1)p)TPYIM-y`Bbo6 zCu1OO3hBiVo>{9QK!;$nJH=Q+bIn`&dbs3mE3$*PgwYv`=vjWvxrqH_&gR~d^x_LP z%28UPKJD-9`{0-pe;w|*hUsq&U0shVP>75}+<(7+=2ywts_tO5e_q(uB)DJ|EhqDt z*>7gwN{rMpa7_DD>=m~Li%>;_bvrsNjnam2?}(1P!zV;ON{F^z#{+%p}5o?M4Kd*x7JJ0LGC?HadeMH(w%jxywfIFP<#hBNLzooo1Q7B*j(Gk zI9Dkgk8@l&%bKVYcx>YGxYSX9pu*ExWe2u_`&#Qx$(j`BxQupWel^lO2kuxk>y z9HfE?P{tJCgFWyhJS0LwaSR>J{YGT{Qb4@O6FManZ`~?dxNm7&SyS%BP|cLXwWGrn z$Ap38Cu#S&8g#l2M$lzDi|;uqVk$UIiGE58mWj~`X;A>v0;NA1qvCU9GFV zF5jitcfp`f8q^o<5HrH6%eMGq#y4XwL_~FzOkoDZF*n=+vhMaNApBVeup*Y!)$)QZ zBa9L*V|4BzSl9YX$p}998pI_?I34vMa>s~b<%5|6tur_zcna7v!$D%k&R7Z=i~t*F z(<<^g1$-Q_8DM%puIh};(6ZTBUYRl|M&Jt9;*fUo%BMJ&6o$6CPaWfM2Yjh3&sI#{ zHtwWi74e`6ReysQaql`EkE#osZtKI3_qmwx(tv$s&qpgNX#C@}ST3uzfOOz#>9RQ0 zWMyGt@iL(MkpUaa?RclyAh-A`6j6`JIO`Z<8;CJW8hSVzGIr%Cnuc7CZ}X8@C5m9* zziwes2!|Hqa$+gOo54bP&ROU9DbIM!Q?d;LA4gffOZJ<56sYb&d|C%N=15yx-Upcl zKnXz>I;zXtP+5;#0Cp`sIpwDQ=j2j=MrEBa9`yu>6r3Im4x;v3y;tpP$oxK|iSLb^ z66g7XiAZNy>NfV{q;MpV*nTdT7Np&ePFQ5VXn{OY{C7)Js1+iuARb($EZdv(4hn;` zJREg1#O9ts6}>og$&cVCq`LBJF^}aQr4Z?g8X!Mc%amSx%q_;bI*9yW@*G* zt7eB`amU;o)!_p^cSe_yY@1{EVOwkqQB;q;=0@aXPUsjPHDriQMgdh%j%Ev z>yn_u>t;hgFJ9*gWPXznH{L^-&g(t2yUbzDzJn!7oEyW7r;L31&~bA9N7_QG)B5D% z47Z*ab~T-`z7B#%-%Zb;ac*_;`i_&LEL?-3Ctu0ip`WX1=FgJ8N+W+R0Bp6OuvwKH z5jxK$L%fGn<~WN{>)L$VV;qhC*!9*%z0V0*{CA zf-*%hp=i#+O@&L%53kzLKMwYPT)G&1g6aNv@Q+CYh{*C$RP z!UIsG7C_WaUu2y(W!A@RYkcqFqMM9Ewz0dc%^ah z;Gp3<1QbOzI3~_YOI3C*QXFVmh8{$OCP+mkKY3{ItR1H-<@vba12hFn0|@bx27a2p zq+LNJhfxLtwS&EZ!2vZJK)KTh{A%Sqq(fqU(|!s74KBk$S?fH$Zl#o%11(`W@f~2t zhQJkBnp~V1S-)p!iAHXBSBeEK`)JWwgf1~gKW?_HRV!=RLY4&@vS6dO(RPxcanrJ) zqtnu?p&|DEU>Q|2U@R zc)uNiH(EHVQ)%=G8$`=e5;oyv`!Z@o1JI^Son0^GVS1o;nij1?uE^ zE%Vm{C9Osz#U^9t@QrLD#kQJTfOZNwM&Y_JT;r$f@l6AAPx~ZSRZa7LuYNlRHc(4` zSR@k^^{kIU)P9qmZze9;P=u?1nf9D}Gfx>0X;!D&Ie*$v2?w|hJ1m^^w+2*G#>@Ir8d*79A-9T7{?>!#*6fM)t!Nd#glqCcuP_1r=WF zh8TMbi`F&CDVR}HuC3A4tWDZ|YX_zB?diq-tM7@kJGd|MS@Zm8pf~JPv)&9Hj@!Z} zrX7n%siME{)u`=py;C!N;15yZ_-xK()PDAfr@7{YvLxOe_i-rBDW%Ld7cfq6GA z>=Mv~TR5ejt7Kc{C2Nt@+getSkD;_ae=X!rln4|C*E7$e8Q*+xUA=FF%}B0>Ui7qP&C|!NlMs%#4GY8L+pyf7GeqAL@K;e_KRMV( z7X3}!qW(BBAo};b*nV&+`F?t6$>*ZQVRB9031FEGLNuKn(7nLqN;HS_4aJQ%hM(Ax z>!<5oL)j5;Juf>iWB7Da$qs(f%A(vD>qrvCYC}6boq-%rdUhGfeG=`F#!g^o2 z;7v;0sOZ0#mdZQ+b!kGY)3MjFwYUdKAb2G5V76Nzcu&b1kUPKF=vKtpI}A7 zv7%YuMpqu%AJ`G*D(PD7;rd8!QB$^PqlDex5UZF@@xDGK8BCs6;lIbM@aDe@0F0%t zQFs<;c5&oRiV^5BIX)D!*a48}l#q3%`<50k^IT(q`ghlhM+IBM9So{WUdM`5lnzYa7wr;Jr6W( zOW;uI$$}0#AE_}$s=Z)u(tLC15IX?5e|tUul2d&#(bl3>i*a>O-hAMN!OXX@?WEEM zw=eUwkkk-vMtzUhcWv>#fgcTrmSFxy(T;B*iX3eFiQ4NBItWq+PFd8@fh+7=P~U$; z^}*l|IQt2oo1}=vAn-kr;E4alvj1(lddeWRQ-a*KLK%zkYs)KlKq&HA27fdpqn7GN z2^G4@h;#4j&#(n??HWMTjEb9gOv4+2Y{eZK#~ntu4D)47#F=lD98UY?S{loHaiXA4 zPB&?-_HZ;C&v35=-|V{(_ciRM`pNQ@|0CTBZ!b}>ga)PL3$V3fQ|*V1+q)^ z>hcq?uvy{5W{NX`77XBf&7LL?Yw9lz;&nJyu%8QV^8i!*M^ za);eW^BLxd0B$^1zH)9E^Pw|KMxaRiq%rnfrbu2-P|m?u;nc2Ik<$j2U`_HK3~l~x zDZ%^_a3}k7W)sUyRU6^R@%#zDU%_qHs&UIth7&ZsHJ+Wm*dwNBvmen%+8Qd2RyFR% z3~c5i`;^*J!555gO_Ec)@iGmx7bYgvSxe)^{DC^i^8sv%S#HYDoGx{wvL+G0J5xy| z&moB7iSjOaBHd^68$5GCU5d0p@LU_W>M?Ubz)9u%Uw<;eb$`iTSbu;*K;jyTmrS`8 zF0C8g#KJi6+kcd24J6j5VacC@^7ScjE`5*x37=%Byls))G+t?TJ(+3;Q67`E!ZgN| zr>Cx~ZR7qm&3ff%g;t5O)4kZQe{V=p;@vk23A-h-AnLLzF^F1JYWXapua%9PYUVo> z#MM|7Pd5kWz!ZLK#IxNWxI*ly!CqVbXY$4PLegH~Jmhd4D|QOcH6k+;$@w;Q{}2~2 zYV-d5b-c6#^q?Sg<31@v(+|Qp$1%eZ%lOgN&8xdefxF1Pe#2EYFEH!yaaeeRMavD0 z;19qe$Nu&q|Jrf8y6a-$CGB%3rdYJgN!ZD|dRxsV3;4jwICv}QETndkO4HeWTDsYm zO+-2uwp|%z1WeG1#{d1!yc28Xtk6`50?T?&yF8Ms)rbGRg2O+lx1`6rz}u2|XYZEB z4Pfg6RsYC@<-*hMD-s!uahjumFsUxyz^)K!lW@FwxWKk`xmv6 zj$m6gDhf3yt;Oy!BcL0!)FO=@zA-cqFi}-Rw~+56BSU!+1ig``MXQTY<6HhgX8VqV zsEUzc4!DEd#l@!{3vxh}mPE04K3c|T*GvyjO?C}W(6Ed*lG!M-cJQNejXv&r{c6{x z+G2t6q!Hxa0b4q^O)Nak@7d*}CG)FZjzsDN>zU}`AH$=4KEv>cVQ>Z`5eG&7T5Uq3`7hk}tF4{)&gHB|Qg`_w(ydMHQcwl?0BPke^l+lw4Ac}Q zk^Q%j=tpDmFXo(q0UI?0FpKPY^Ntk$#dq&JX=Of0&{;R_lE@^V_fq9TXdD$RF!s2X z5iXncyP7oBbqxy8a4+d?>kR)Wj&o@Eo^ObW^+Rwlk1WC&h+hq1%43d3$Xb5=Om5Hxjz5SZ=^3X z5lcx{YE&yf_&7l*B&1{oK?nBA(3h-RXv=(osd;2D0R+QbaXz>&Bxfh}?MwEcIzgRE zVJG8}ArPlt!>5|~Gp*KqG|^BGhHWt6%vsmD7$_>9x4PbVVnR}am{dgWS_G_Pqc~++ zI{z|=V}656aE^%(h@QfA@7X0WV{kAawGs4ho1}=~>1@0Y4=|K_+>~{7|6u1L{=EFJ zH3fVQlxWS{J^?5dcVwI=T_%Im%U4Ax@MKIC`!L~X*xJ|3%LK;^*d18c545d4?<~KC zA3Rop3kyQ!sy(J@E70>v$RAL@fd`?4l3(6fL~gwxcHzT6vC%|9N!o$sf!@79DQ-5_ zD87AQI*?$6dIpR>63LwfY7F|Qos@)jr>~H}VEe&#bD>#;?;C)plQ#1)!JEMa7I(ux zcHptFQ9!8i$l|@;sO+fdTF$+r8Dm>AVq?~W$mTw>Z$IH0j)doEbb07*!@;{>O=LGM zaBhIa1C1J>st!mHC>Gp`R6=*qYoIwKtGJ{EVSPDdhZ|)fd8ggoe4@I|gI7wIFJC%> zEt8mNAYnJIX>_sI_~Y|x?jWr3PHp$v)by07La=K-iOB!{V=Np}&dfFPbm8j|m{b4w z(+<>`XQR@QaxE3ogA?KMnR_4)6`|Dj(9tzQ(vd)5@ruuLJz%P`0v!YB6W4LQOHjoF zq1y`D1?3Y6Y(anx< zVA*H=<({&Z&s_fdL}gn2l%T98U|PN>CKOqob&*bPj>ATu*~_c8fP&Pt2XBzjSBP8Z zaWBcb=y)pMA17z@>od-UR0?%SC0aEEe}|~5Gu-!5L1zTWxDuvoT3)2`{Th>05-h1F zdO3MgM=WQwo0+uh237zy#`kMvOAVn**s-rR(tOpP#JjlQ^x>K3c~ahC7mYJ8PGqMS zHY_xG`}Fg-DGX@#l{aIfr*hr3?(_C3&|HU;NR?+2+ah@VeR3EcgTR?SE#9vpl!p0R zZDKcl)|=*UEt5>)8Jo{fuQbWr5j%V_T6o3LIuydFExX6is# zcG9RG>LwRu(4EN~Z>1A8TEw_V9d=c0iq&M5brL2I?lFHeBUOFNF=mN_8{g3q`D<{C zp9{%2Xf?PEDhR%!G2KbJb`|26Rs7N{r# P{`VRG!QlRDKtTT=K!E9a From d110cae5ee8d166adcc2f11c0ad35467b19752fb Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Mon, 19 Aug 2024 10:37:34 -0700 Subject: [PATCH 6/7] Update winpkg identity --- deploy/winpkgidentityext/msix/appxmanifest.xml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/deploy/winpkgidentityext/msix/appxmanifest.xml b/deploy/winpkgidentityext/msix/appxmanifest.xml index 38a87dfc..225e0fdd 100644 --- a/deploy/winpkgidentityext/msix/appxmanifest.xml +++ b/deploy/winpkgidentityext/msix/appxmanifest.xml @@ -12,7 +12,7 @@ xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6" xmlns:iot2="http://schemas.microsoft.com/appx/manifest/iot/windows10/2" IgnorableNamespaces="mp uap uap3 uap5 rescap desktop desktop4 desktop6 iot2"> - + Julia Dev @@ -78,13 +78,22 @@ - - + + + + + + + + From 07018fac86b7fff38e10a22204f416174e0480f3 Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Mon, 19 Aug 2024 10:37:39 -0700 Subject: [PATCH 7/7] Update add command --- AppxManifest.xml | 66 ++++++++++++++++++++++++++++++++++++++++++ src/command_app_add.rs | 22 ++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 AppxManifest.xml diff --git a/AppxManifest.xml b/AppxManifest.xml new file mode 100644 index 00000000..80bb3cc4 --- /dev/null +++ b/AppxManifest.xml @@ -0,0 +1,66 @@ + + + + + + + Number Guesser (Manifest) + AppModelSamples + Images\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/command_app_add.rs b/src/command_app_add.rs index 7eae1e69..579cb3f4 100644 --- a/src/command_app_add.rs +++ b/src/command_app_add.rs @@ -82,5 +82,27 @@ pub fn run_command_app_add(path: &str, paths: &GlobalPaths) -> Result<()> { .status() .unwrap(); + // #[cfg(feature = "winpkgidentityext")] + { + use windows::Management::Deployment::{RegisterPackageOptions, PackageManager}; + + let package_manager = PackageManager::new().unwrap(); + let register_package_options = RegisterPackageOptions::new().unwrap(); + register_package_options.SetAllowUnsigned(true)?; + + let self_location = std::env::current_exe().unwrap(); + let self_location = self_location.parent().unwrap().parent().unwrap().parent().unwrap().join("stringbuislders.xml"); + + println!("WE ARE AT {:?}", self_location); + + let external_loc = + windows::Foundation::Uri::CreateUri(&windows::core::HSTRING::from("C:\\Users\\david\\source\\juliaup\\AppxManifest.xml")) + .unwrap(); + + let asdf = package_manager.RegisterPackageByUriAsync(&external_loc, ®ister_package_options).unwrap().get().unwrap(); + + println!("DEPLOY WAS {:?} with {:?}", asdf.IsRegistered().unwrap(), asdf.ErrorText().unwrap()); + } + return Ok(()) }