Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add apps support #964

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions AppxManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap uap10 rescap build"
xmlns:build="http://schemas.microsoft.com/developer/appx/2015/build">

<Identity Name="StringBuildersManifest"
Publisher="CN=Julialang, OID.2.25.311729368913984317654407730594956997722=1"
Version="1.0.0.6" />

<Properties>
<DisplayName>Number Guesser (Manifest)</DisplayName>
<PublisherDisplayName>AppModelSamples</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>

<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.19041.0" />
<uap10:HostRuntimeDependency Name="JuliaHubInc.JuliaDev" Publisher="CN=&quot;JuliaHub, Inc.&quot;, O=&quot;JuliaHub, Inc.&quot;, L=CAMBRIDGE, S=Massachusetts, C=US" MinVersion="1.0.0.0"/>
</Dependencies>

<Applications>
<Application Id="StringBuildersApp"
uap10:HostId="JuliaHost"
uap10:Parameters="--project=C:\Users\david\.julia\dev\StringBuilders\app">
<uap:VisualElements
DisplayName="Stringbuilders"
Description="Stringbuilders is a high-level, high-performance, dynamic programming language"
BackgroundColor="transparent"
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile
Wide310x150Logo="Images\Wide310x150Logo.png"
ShortName="Julia"
Square71x71Logo="Images\SmallTile.png"
Square310x310Logo="Images\LargeTile.png">
<uap:ShowNameOnTiles>
<uap:ShowOn Tile="square150x150Logo"/>
<uap:ShowOn Tile="wide310x150Logo"/>
<uap:ShowOn Tile="square310x310Logo"/>
</uap:ShowNameOnTiles>
</uap:DefaultTile >
<uap:SplashScreen Image="Images\SplashScreen.png" />
</uap:VisualElements>
<Extensions>
<uap5:Extension Category="windows.appExecutionAlias">
<uap5:AppExecutionAlias>
<uap5:ExecutionAlias Alias="foobarasdf.exe" />
</uap5:AppExecutionAlias>
</uap5:Extension>
</Extensions>
</Application>

</Applications>

<Capabilities>
<rescap:Capability Name="runFullTrust" />
<rescap:Capability Name="unvirtualizedResources"/>
</Capabilities>
</Package>
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
regex = "1.10.5"

[target.'cfg(windows)'.dependencies]
Expand Down
2 changes: 2 additions & 0 deletions deploy/winpkgidentityext/create-msix.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ $params = @{
}

Invoke-TrustedSigning @params

Move-Item .\juliaup.msix ..\..\target\debug\ -Force
Binary file removed deploy/winpkgidentityext/juliaup.msix
Binary file not shown.
15 changes: 12 additions & 3 deletions deploy/winpkgidentityext/msix/appxmanifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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">

<Identity Name="JuliaHubInc.JuliaDev" Publisher="CN=&quot;JuliaHub, Inc.&quot;, O=&quot;JuliaHub, Inc.&quot;, L=CAMBRIDGE, S=Massachusetts, C=US" Version="1.0.0.0" ProcessorArchitecture="x64"/>
<Identity Name="JuliaHubInc.JuliaDev" Publisher="CN=&quot;JuliaHub, Inc.&quot;, O=&quot;JuliaHub, Inc.&quot;, L=CAMBRIDGE, S=Massachusetts, C=US" Version="1.0.0.3" ProcessorArchitecture="x64"/>

<Properties>
<DisplayName>Julia Dev</DisplayName>
Expand Down Expand Up @@ -78,13 +78,22 @@
</uap:DefaultTile >
<uap:SplashScreen Image="Images\SplashScreen.png" />
</uap:VisualElements>
<Extensions>
</Extensions>

</Application>
</Applications>

<Extensions>
<uap10:Extension Category="windows.hostRuntime"
Executable="julialauncher.exe"
uap10:RuntimeBehavior="win32App"
uap10:TrustLevel="mediumIL">
<uap10:HostRuntime Id="JuliaHost"/>
</uap10:Extension>
</Extensions>

<Capabilities>
<rescap:Capability Name="runFullTrust" />
<rescap:Capability Name="unvirtualizedResources"/>
<rescap:Capability Name="packageManagement" />
</Capabilities>
</Package>
14 changes: 13 additions & 1 deletion src/bin/juliaup.rs
Original file line number Diff line number Diff line change
@@ -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};

Check warning on line 3 in src/bin/juliaup.rs

View workflow job for this annotation

GitHub Actions / Rustfmt Check

Diff in /home/runner/work/juliaup/juliaup/src/bin/juliaup.rs
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;
Expand Down Expand Up @@ -147,7 +150,16 @@
SelfSubCmd::Uninstall {} => run_command_selfuninstall(&paths),
#[cfg(not(feature = "selfupdate"))]
SelfSubCmd::Uninstall {} => run_command_selfuninstall_unavailable(),
},

Check warning on line 153 in src/bin/juliaup.rs

View workflow job for this annotation

GitHub Actions / Rustfmt Check

Diff in /home/runner/work/juliaup/juliaup/src/bin/juliaup.rs
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)
},
}
}
23 changes: 23 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
#[cfg(feature = "selfupdate")]
#[clap(name = "4c79c12db1d34bbbab1f6c6f838f423f", hide = true)]
SecretSelfUpdate {},
#[clap(subcommand, name = "app")]
/// Juliaup applications
Application(ApplicationSubCmd),
}

#[derive(Parser)]
Expand Down Expand Up @@ -154,3 +157,23 @@
value: Option<i64>,
},
}

#[derive(Parser)]
pub enum ApplicationSubCmd {

Check warning on line 162 in src/cli.rs

View workflow job for this annotation

GitHub Actions / Rustfmt Check

Diff in /home/runner/work/juliaup/juliaup/src/cli.rs
#[clap(name = "add")]
/// Add a Julia application
Add {
value: String
},
#[clap(name = "run")]
/// Run a Julia application
Run {
name: String,
args: Vec<String>
},
#[clap(name = "remove", alias = "rm")]
/// Remove a Julia application
Remove {
name: String
}
}
108 changes: 108 additions & 0 deletions src/command_app_add.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
use std::fs;
use std::path::PathBuf;

Check warning on line 2 in src/command_app_add.rs

View workflow job for this annotation

GitHub Actions / Rustfmt Check

Diff in /home/runner/work/juliaup/juliaup/src/command_app_add.rs
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::install_version;
use crate::versions_file::load_versions_db;
use anyhow::{Context, Result};
use bstr::ByteVec;
use normpath::PathExt;

pub fn run_command_app_add(path: &str, paths: &GlobalPaths) -> Result<()> {
let app_folder_path = PathBuf::from(path);

let project_path = app_folder_path.join("Project.toml");
let manifest_path = app_folder_path.join("Manifest.toml");

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(&manifest_path).unwrap();

Check warning on line 22 in src/command_app_add.rs

View workflow job for this annotation

GitHub Actions / Rustfmt Check

Diff in /home/runner/work/juliaup/juliaup/src/command_app_add.rs
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 exec_aliases: Vec<(String, String)> = project_parsed
.as_table()
.get_key_value("executionaliases")
.unwrap()
.1
.clone()
.into_table()

Check warning on line 34 in src/command_app_add.rs

View workflow job for this annotation

GitHub Actions / Rustfmt Check

Diff in /home/runner/work/juliaup/juliaup/src/command_app_add.rs
.unwrap()
.iter()
.map(|i| (i.0.to_string(), i.1.clone().into_value().unwrap().as_str().unwrap().to_string()))
.collect();

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.")?;

Check warning on line 47 in src/command_app_add.rs

View workflow job for this annotation

GitHub Actions / Rustfmt Check

Diff in /home/runner/work/juliaup/juliaup/src/command_app_add.rs
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()

Check warning on line 61 in src/command_app_add.rs

View workflow job for this annotation

GitHub Actions / Rustfmt Check

Diff in /home/runner/work/juliaup/juliaup/src/command_app_add.rs
.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::DevedApplication {

Check warning on line 68 in src/command_app_add.rs

View workflow job for this annotation

GitHub Actions / Rustfmt Check

Diff in /home/runner/work/juliaup/juliaup/src/command_app_add.rs
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()

Check warning on line 72 in src/command_app_add.rs

View workflow job for this annotation

GitHub Actions / Rustfmt Check

Diff in /home/runner/work/juliaup/juliaup/src/command_app_add.rs
}
);

save_config_db(&mut config_file).unwrap();

std::process::Command::new(julia_binary_path)
.env("JULIA_PROJECT", &app_folder_path)
.arg("-e")
.arg("using Pkg; Pkg.instantiate()")
.status()
.unwrap();

// #[cfg(feature = "winpkgidentityext")]
{
use windows::Management::Deployment::{RegisterPackageOptions, PackageManager};

Check failure on line 87 in src/command_app_add.rs

View workflow job for this annotation

GitHub Actions / test-juliaup (x86_64-unknown-linux-gnu)

failed to resolve: use of undeclared crate or module `windows`

Check failure on line 87 in src/command_app_add.rs

View workflow job for this annotation

GitHub Actions / check-juliaup (x86_64-unknown-linux-gnu)

failed to resolve: use of undeclared crate or module `windows`

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

Check failure on line 99 in src/command_app_add.rs

View workflow job for this annotation

GitHub Actions / test-juliaup (x86_64-unknown-linux-gnu)

failed to resolve: use of undeclared crate or module `windows`

Check failure on line 99 in src/command_app_add.rs

View workflow job for this annotation

GitHub Actions / test-juliaup (x86_64-unknown-linux-gnu)

failed to resolve: use of undeclared crate or module `windows`

Check failure on line 99 in src/command_app_add.rs

View workflow job for this annotation

GitHub Actions / check-juliaup (x86_64-unknown-linux-gnu)

failed to resolve: use of undeclared crate or module `windows`

Check failure on line 99 in src/command_app_add.rs

View workflow job for this annotation

GitHub Actions / check-juliaup (x86_64-unknown-linux-gnu)

failed to resolve: use of undeclared crate or module `windows`
.unwrap();

let asdf = package_manager.RegisterPackageByUriAsync(&external_loc, &register_package_options).unwrap().get().unwrap();

println!("DEPLOY WAS {:?} with {:?}", asdf.IsRegistered().unwrap(), asdf.ErrorText().unwrap());
}

return Ok(())
}
21 changes: 21 additions & 0 deletions src/command_app_remove.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use anyhow::{Context,Result};

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)
.with_context(|| "`app remove` command failed to load configuration data.")?;

if !config_file.data.installed_apps.contains_key(name) {
println!("Unknown app {}.", name);
}
else {
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(())
}
54 changes: 54 additions & 0 deletions src/command_app_run.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
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<String>, paths: &GlobalPaths) -> Result<()> {

let config_file = load_config_db(paths)
.with_context(|| "`app run` command failed to load configuration data.")?;

let target: HashMap<String,(String,String,String,String)> = config_file
.data
.installed_apps
.iter()
.flat_map(|i| match&i.1 {
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();

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 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())
.join("bin")
.join(format!("julia{}", std::env::consts::EXE_SUFFIX))
.normalize().unwrap();

std::process::Command::new(julia_binary_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))
.args(args)
.status()
.unwrap();

}
else {
println!("Could not find app.");
}
return Ok(())
}
Loading
Loading