feat!: warn about missing pkexec; refactor dependencies check to use Depencendy struct methods

This commit is contained in:
Gabriele Musco 2024-01-30 00:00:27 +01:00
parent ba6ecf272b
commit 88e4affaca
No known key found for this signature in database
GPG key ID: 1068D795C80E51DE
13 changed files with 106 additions and 74 deletions

View file

@ -28,6 +28,54 @@ impl PartialOrd for Dependency {
}
}
impl Dependency {
pub fn check(&self) -> bool {
for dir in match self.dep_type {
DepType::SharedObject => shared_obj_paths(),
DepType::Executable => env::var("PATH")
.expect("PATH environment variable not defined")
.split(':')
.map(str::to_string)
.collect(),
DepType::Include => include_paths(),
} {
let path_s = &format!("{dir}/{fname}", dir = dir, fname = self.filename);
let path = Path::new(&path_s);
if path.is_file() {
return true;
}
}
false
}
pub fn check_many(deps: Vec<Self>) -> Vec<DependencyCheckResult> {
deps.iter()
.map(|dep| DependencyCheckResult {
dependency: dep.clone(),
found: dep.check(),
})
.collect()
}
pub fn package_name_for_distro(&self, distro: Option<&LinuxDistro>) -> String {
if let Some(distro) = distro {
if let Some(pname) = self
.packages
.iter()
.find(|(k, _)| *k == distro)
.map(|(_, v)| v)
{
return pname.clone();
}
}
self.name.clone()
}
pub fn package_name(&self) -> String {
self.package_name_for_distro(LinuxDistro::get().as_ref())
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DependencyCheckResult {
pub dependency: Dependency,
@ -73,40 +121,11 @@ fn include_paths() -> Vec<String> {
]
}
pub fn check_dependency(dep: Dependency) -> bool {
for dir in match dep.dep_type {
DepType::SharedObject => shared_obj_paths(),
DepType::Executable => env::var("PATH")
.expect("PATH environment variable not defined")
.split(':')
.map(str::to_string)
.collect(),
DepType::Include => include_paths(),
} {
let path_s = &format!("{dir}/{fname}", dir = dir, fname = dep.filename);
let path = Path::new(&path_s);
if path.is_file() {
return true;
}
}
false
}
pub fn check_dependencies(deps: Vec<Dependency>) -> Vec<DependencyCheckResult> {
deps.iter()
.map(|dep| DependencyCheckResult {
dependency: dep.clone(),
found: check_dependency(dep.clone()),
})
.collect()
}
#[cfg(test)]
mod tests {
use super::{DepType, Dependency};
use std::collections::HashMap;
use super::{check_dependency, DepType, Dependency};
#[test]
fn can_find_libc() {
let libc_dep = Dependency {
@ -116,19 +135,19 @@ mod tests {
packages: HashMap::new(),
};
assert!(check_dependency(libc_dep));
assert!(libc_dep.check());
}
#[test]
fn can_find_ls() {
let libc_dep = Dependency {
let ls_dep = Dependency {
name: "ls".into(),
dep_type: DepType::Executable,
filename: ("ls".into()),
packages: HashMap::new(),
};
assert!(check_dependency(libc_dep));
assert!(ls_dep.check());
}
#[test]
@ -140,6 +159,6 @@ mod tests {
packages: HashMap::new(),
};
assert!(!check_dependency(fake_dep));
assert!(!fake_dep.check());
}
}

View file

@ -1,5 +1,5 @@
use crate::{
depcheck::{check_dependencies, DepType, Dependency, DependencyCheckResult},
depcheck::{DepType, Dependency, DependencyCheckResult},
dependencies::common::{dep_eigen, dep_gpp},
linux_distro::LinuxDistro,
};
@ -134,7 +134,7 @@ fn basalt_deps() -> Vec<Dependency> {
}
pub fn check_basalt_deps() -> Vec<DependencyCheckResult> {
check_dependencies(basalt_deps())
Dependency::check_many(basalt_deps())
}
pub fn get_missing_basalt_deps() -> Vec<Dependency> {

View file

@ -143,3 +143,17 @@ pub fn dep_vulkan_headers() -> Dependency {
]),
}
}
pub fn dep_pkexec() -> Dependency {
Dependency {
name: "pkexec".into(),
dep_type: DepType::Executable,
filename: "pkexec".into(),
packages: HashMap::from([
(LinuxDistro::Arch, "polkit".into()),
(LinuxDistro::Debian, "pkexec".into()),
(LinuxDistro::Fedora, "polkit".into()),
(LinuxDistro::Alpine, "polkit".into()),
]),
}
}

View file

@ -1,5 +1,5 @@
use crate::{
depcheck::{check_dependencies, Dependency, DependencyCheckResult},
depcheck::{Dependency, DependencyCheckResult},
dependencies::common::{dep_cmake, dep_eigen, dep_gcc, dep_git, dep_gpp, dep_ninja},
};
@ -15,7 +15,7 @@ fn libsurvive_deps() -> Vec<Dependency> {
}
pub fn check_libsurvive_deps() -> Vec<DependencyCheckResult> {
check_dependencies(libsurvive_deps())
Dependency::check_many(libsurvive_deps())
}
pub fn get_missing_libsurvive_deps() -> Vec<Dependency> {

View file

@ -1,5 +1,5 @@
use crate::{
depcheck::{check_dependencies, DepType, Dependency, DependencyCheckResult},
depcheck::{DepType, Dependency, DependencyCheckResult},
linux_distro::LinuxDistro,
};
use std::collections::HashMap;
@ -37,7 +37,7 @@ fn mercury_deps() -> Vec<Dependency> {
}
pub fn check_mercury_deps() -> Vec<DependencyCheckResult> {
check_dependencies(mercury_deps())
Dependency::check_many(mercury_deps())
}
pub fn get_missing_mercury_deps() -> Vec<Dependency> {

View file

@ -5,5 +5,4 @@ pub mod libsurvive_deps;
pub mod mercury_deps;
pub mod monado_deps;
pub mod openhmd_deps;
pub mod pkexec_dep;
pub mod wivrn_deps;

View file

@ -1,5 +1,5 @@
use crate::{
depcheck::{check_dependencies, DepType, Dependency, DependencyCheckResult},
depcheck::{DepType, Dependency, DependencyCheckResult},
dependencies::common::{
dep_cmake, dep_eigen, dep_gcc, dep_git, dep_glslang_validator, dep_gpp, dep_libdrm,
dep_ninja, dep_openxr, dep_vulkan_headers, dep_vulkan_icd_loader,
@ -54,7 +54,7 @@ fn monado_deps() -> Vec<Dependency> {
}
pub fn check_monado_deps() -> Vec<DependencyCheckResult> {
check_dependencies(monado_deps())
Dependency::check_many(monado_deps())
}
pub fn get_missing_monado_deps() -> Vec<Dependency> {

View file

@ -1,5 +1,5 @@
use crate::{
depcheck::{check_dependencies, Dependency, DependencyCheckResult},
depcheck::{Dependency, DependencyCheckResult},
dependencies::common::{dep_cmake, dep_gcc, dep_git, dep_gpp, dep_ninja},
};
@ -8,7 +8,7 @@ fn openhmd_deps() -> Vec<Dependency> {
}
pub fn check_openhmd_deps() -> Vec<DependencyCheckResult> {
check_dependencies(openhmd_deps())
Dependency::check_many(openhmd_deps())
}
pub fn get_missing_openhmd_deps() -> Vec<Dependency> {

View file

@ -1,18 +0,0 @@
use crate::{
depcheck::{DepType, Dependency},
linux_distro::LinuxDistro,
};
use std::collections::HashMap;
pub fn pkexec_dep() -> Dependency {
Dependency {
name: "pkexec".into(),
dep_type: DepType::Executable,
filename: "pkexec".into(),
packages: HashMap::from([
(LinuxDistro::Arch, "polkit".into()),
(LinuxDistro::Debian, "pkexec".into()),
(LinuxDistro::Fedora, "polkit".into()),
]),
}
}

View file

@ -1,5 +1,5 @@
use crate::{
depcheck::{check_dependencies, DepType, Dependency, DependencyCheckResult},
depcheck::{DepType, Dependency, DependencyCheckResult},
dependencies::common::{
dep_cmake, dep_eigen, dep_gcc, dep_git, dep_glslang_validator, dep_gpp, dep_libdrm,
dep_ninja, dep_openxr, dep_vulkan_headers, dep_vulkan_icd_loader,
@ -146,7 +146,7 @@ fn wivrn_deps() -> Vec<Dependency> {
}
pub fn check_wivrn_deps() -> Vec<DependencyCheckResult> {
check_dependencies(wivrn_deps())
Dependency::check_many(wivrn_deps())
}
pub fn get_missing_wivrn_deps() -> Vec<Dependency> {

View file

@ -19,13 +19,12 @@ use crate::builders::build_openhmd::get_build_openhmd_jobs;
use crate::builders::build_wivrn::get_build_wivrn_jobs;
use crate::config::Config;
use crate::constants::APP_NAME;
use crate::depcheck::check_dependency;
use crate::dependencies::basalt_deps::get_missing_basalt_deps;
use crate::dependencies::common::dep_pkexec;
use crate::dependencies::libsurvive_deps::get_missing_libsurvive_deps;
use crate::dependencies::mercury_deps::get_missing_mercury_deps;
use crate::dependencies::monado_deps::get_missing_monado_deps;
use crate::dependencies::openhmd_deps::get_missing_openhmd_deps;
use crate::dependencies::pkexec_dep::pkexec_dep;
use crate::dependencies::wivrn_deps::get_missing_wivrn_deps;
use crate::file_builders::active_runtime_json::{
set_current_active_runtime_to_profile, set_current_active_runtime_to_steam,
@ -478,9 +477,7 @@ impl SimpleComponent for App {
(
missing_deps
.iter()
.map(|dep| {
dep.packages.get(&d).unwrap_or_else(|| &dep.name).clone()
})
.map(|dep| dep.package_name_for_distro(Some(&d)))
.collect::<Vec<String>>()
.join(", "),
{
@ -656,7 +653,7 @@ impl SimpleComponent for App {
));
}
Msg::RunSetCap => {
if !check_dependency(pkexec_dep()) {
if !dep_pkexec().check() {
println!("pkexec not found, skipping setcap");
} else {
let profile = self.get_selected_profile();

View file

@ -2,7 +2,6 @@ use super::alert::alert;
use crate::{
adb::get_adb_install_runner,
cmd_runner::CmdRunner,
depcheck::check_dependency,
dependencies::adb_dep::adb_dep,
downloader::download_file,
paths::wivrn_apk_download_path,
@ -177,7 +176,7 @@ impl SimpleComponent for InstallWivrnBox {
}
}
Self::Input::DownloadWivrn(link) => {
if !check_dependency(adb_dep()) {
if !adb_dep().check() {
alert("ADB is not installed", Some("Please install ADB on your computer to install WiVRn on your Android headset"), Some(&self.root_win));
} else {
self.set_install_wivrn_status(InstallWivrnStatus::InProgress);

View file

@ -5,6 +5,7 @@ use super::profile_editor::{ProfileEditor, ProfileEditorMsg, ProfileEditorOutMsg
use super::steam_launch_options_box::{SteamLaunchOptionsBox, SteamLaunchOptionsBoxMsg};
use super::steamvr_calibration_box::SteamVrCalibrationBox;
use crate::config::Config;
use crate::dependencies::common::dep_pkexec;
use crate::file_utils::mount_has_nosuid;
use crate::gpu_profile::{
get_amd_gpu_power_profile, get_first_amd_gpu, get_set_amd_vr_pow_prof_cmd, GpuPowerProfile,
@ -222,7 +223,7 @@ impl SimpleComponent for MainView {
gtk::Label {
set_label: concat!(
"Your current prefix is inside a partition ",
"mounted with the nosuid option. This will prevent ",
"mounted with the nosuid option.\nThis will prevent ",
"the XR runtime from acquiring certain privileges ",
"and will cause noticeable stutter when running XR ",
"applications."
@ -233,6 +234,27 @@ impl SimpleComponent for MainView {
set_wrap_mode: gtk::pango::WrapMode::Word,
}
},
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_hexpand: true,
set_vexpand: false,
set_spacing: 12,
add_css_class: "card",
add_css_class: "padded",
#[track = "model.changed(Self::selected_profile())"]
set_visible: true || !dep_pkexec().check(),
warning_heading(),
gtk::Label {
set_label: &format!(
"Pkexec wasn't found on your system.\nThis will prevent the XR runtime from acquiring certain priviledges and will cause noticeable stutter when running XR applications.\nYou can fix this by installing the following package on your system: <tt>{}</tt>", dep_pkexec().package_name()
),
set_use_markup: true,
add_css_class: "warning",
set_xalign: 0.0,
set_wrap: true,
set_wrap_mode: gtk::pango::WrapMode::Word,
}
},
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_hexpand: true,