Init work on macos support

This commit is contained in:
Piotr Siuszko 2022-09-26 17:50:15 +02:00
parent 2257948203
commit c913f49e31
14 changed files with 335 additions and 73 deletions

View File

@ -46,4 +46,8 @@ jobs:
cache-on-failure: ""
- uses: actions/checkout@v2
- name: Build
run: cd egui_client && cargo build --verbose
run: cd egui_client && cargo build --verbose
- uses: actions/upload-artifact@v3
with:
name: upload executable
path: egui_client/target/release/rusty_hub_egui

111
egui_client/Cargo.lock generated
View File

@ -387,6 +387,75 @@ dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "crossbeam"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-epoch",
"crossbeam-queue",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1"
dependencies = [
"autocfg",
"cfg-if 1.0.0",
"crossbeam-utils",
"memoffset",
"once_cell",
"scopeguard",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
dependencies = [
"cfg-if 1.0.0",
"once_cell",
]
[[package]]
name = "crossfont"
version = "0.5.0"
@ -502,6 +571,15 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
[[package]]
name = "dpc-pariter"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a6f60e0061d01135c7e9b77486a7f5a8e63ba14acbdbca73e42007cfd8a1c91"
dependencies = [
"pariter",
]
[[package]]
name = "dwrote"
version = "0.11.0"
@ -949,6 +1027,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "hex"
version = "0.4.3"
@ -1323,6 +1410,16 @@ dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "num_enum"
version = "0.5.7"
@ -1415,6 +1512,17 @@ dependencies = [
"system-deps",
]
[[package]]
name = "pariter"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "324a62b9e7b5f270c0acc92a2040f8028bb643f959f9c068f11a7864f327e3d9"
dependencies = [
"crossbeam",
"crossbeam-channel",
"num_cpus",
]
[[package]]
name = "parking_lot"
version = "0.12.1"
@ -1596,6 +1704,7 @@ dependencies = [
name = "rusty_hub"
version = "0.1.0"
dependencies = [
"dpc-pariter",
"exe",
"registry",
"serde",
@ -1605,7 +1714,7 @@ dependencies = [
[[package]]
name = "rusty_hub_egui"
version = "0.1.0"
version = "0.2.0"
dependencies = [
"confy",
"eframe",

View File

@ -1,6 +1,6 @@
[package]
name = "rusty_hub_egui"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
homepage = "https://github.com/Leinnan/rusty_hub"
build = "build.rs"

View File

@ -9,5 +9,4 @@ fn main() {
}
#[cfg(unix)]
fn main() {
}
fn main() {}

0
egui_client/icon.png Normal file
View File

View File

@ -21,21 +21,23 @@ impl HubClient {
let hub_option = confy::load("lwa_unity_hub", "config");
let hub = if hub_option.is_ok() {
hub_option.unwrap()
let mut h: Hub = hub_option.unwrap();
h.update_projects_info();
h
} else {
Hub::default()
};
let mut client = Self {
let client = Self {
hub,
current_tab: WindowTab::Projects,
};
client.save_config(true);
client
}
fn save_config(&mut self, rebuild: bool) {
if rebuild {
self.hub.update_info();
self.hub.update_data();
}
let _ = confy::store("lwa_unity_hub", "config", &self.hub);
}

124
rusty_hub/Cargo.lock generated
View File

@ -80,6 +80,75 @@ dependencies = [
"libc",
]
[[package]]
name = "crossbeam"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c"
dependencies = [
"cfg-if",
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-epoch",
"crossbeam-queue",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"once_cell",
"scopeguard",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
name = "digest"
version = "0.9.0"
@ -89,6 +158,15 @@ dependencies = [
"generic-array",
]
[[package]]
name = "dpc-pariter"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a6f60e0061d01135c7e9b77486a7f5a8e63ba14acbdbca73e42007cfd8a1c91"
dependencies = [
"pariter",
]
[[package]]
name = "exe"
version = "0.5.4"
@ -117,6 +195,15 @@ dependencies = [
"version_check",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "hex"
version = "0.4.3"
@ -171,6 +258,15 @@ dependencies = [
"opaque-debug",
]
[[package]]
name = "memoffset"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
dependencies = [
"autocfg",
]
[[package]]
name = "num-integer"
version = "0.1.45"
@ -190,6 +286,16 @@ dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "once_cell"
version = "1.15.0"
@ -202,6 +308,17 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "pariter"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "324a62b9e7b5f270c0acc92a2040f8028bb643f959f9c068f11a7864f327e3d9"
dependencies = [
"crossbeam",
"crossbeam-channel",
"num_cpus",
]
[[package]]
name = "pkbuffer"
version = "0.4.1"
@ -257,6 +374,7 @@ dependencies = [
name = "rusty_hub"
version = "0.1.0"
dependencies = [
"dpc-pariter",
"exe",
"registry",
"serde",
@ -273,6 +391,12 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.145"

View File

@ -18,4 +18,5 @@ serde = "^1.0"
serde_derive = "^1.0"
walkdir = "^2.3.2"
exe = "^0.5.4"
registry = "1.2.2"
registry = "1.2.2"
dpc-pariter = "0.5.1"

View File

@ -1,7 +1,8 @@
use crate::{consts, unity_editor::UnityEditor};
use dpc_pariter::IteratorExt;
use std::collections::HashSet;
use walkdir::{DirEntry, WalkDir};
use crate::unity_editor::UnityEditor;
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Configuration {
pub unity_search_paths: Vec<String>,
@ -10,18 +11,13 @@ pub struct Configuration {
impl Configuration {
pub fn rebuild(&mut self) {
self.editors_configurations = Vec::new();
let paths = self.get_unity_paths();
for path in &paths {
let editor = UnityEditor::new(&path);
if editor.is_none() {
continue;
}
let editor = editor.unwrap();
if !self.editors_configurations.contains(&editor) {
self.editors_configurations.push(editor);
}
}
self.editors_configurations = paths
.into_iter()
.parallel_map(|path| UnityEditor::new(&path))
.parallel_filter(|editor| editor.is_some())
.parallel_map(|editor| editor.unwrap())
.collect();
}
pub fn get_unity_paths(&self) -> Vec<String> {
let mut paths = Vec::new();
@ -34,8 +30,11 @@ impl Configuration {
}
fn is_unity_dir(entry: &DirEntry) -> bool {
#[cfg(windows)]
let uninstall_exists = entry.path().clone().join("Uninstall.exe").exists();
let unity_exe_exists = entry.path().clone().join("Unity.exe").exists();
#[cfg(unix)]
let uninstall_exists = true; // just check that on windows only
let unity_exe_exists = entry.path().clone().join(consts::UNITY_EXE_NAME).exists();
uninstall_exists && unity_exe_exists
}
@ -45,29 +44,32 @@ impl Configuration {
if !path_exists {
return Vec::new();
}
let mut result_paths: Vec<String> = Vec::new();
for entry in WalkDir::new(path)
.max_depth(5)
let hashset: HashSet<String> = WalkDir::new(path)
.max_depth(2)
.into_iter()
.filter_entry(|_| true)
{
if entry.is_ok() {
let entry_unwraped = entry.unwrap();
let success = Configuration::is_unity_dir(&entry_unwraped);
if success {
result_paths.push(entry_unwraped.path().to_string_lossy().into());
}
}
}
result_paths
.parallel_filter(|entry| entry.is_ok())
.parallel_map(|entry| entry.unwrap())
.parallel_filter(|entry| Configuration::is_unity_dir(&entry))
.parallel_map(|entry| entry.path().to_string_lossy().into())
.collect();
Vec::from_iter(hashset)
}
}
impl Default for Configuration {
fn default() -> Self {
let mut default = Self {
unity_search_paths: vec!["C:\\Program Files\\Unity\\Hub".to_string()],
#[cfg(windows)]
unity_search_paths: vec!["C:\\Program Files\\Unity\\Hub\\Editor".to_string()],
#[cfg(target_os = "macos")]
unity_search_paths: vec![
"/Applications/Unity/Hub/Editor".to_string(),
"/Applications/Unity/".to_string(),
],
#[cfg(target_os = "linux")]
unity_search_paths: vec!["~/Unity/Hub/Editor".to_string()],
editors_configurations: Vec::new(),
};
default.rebuild();

6
rusty_hub/src/consts.rs Normal file
View File

@ -0,0 +1,6 @@
#[cfg(windows)]
pub const UNITY_EXE_NAME: &str = "Unity.exe";
#[cfg(target_os = "macos")]
pub const UNITY_EXE_NAME: &str = "Unity.app/Contents/MacOS/Unity";
#[cfg(target_os = "linux")]
pub const UNITY_EXE_NAME: &str = "Unity";

View File

@ -1,8 +1,7 @@
use std::{path::PathBuf, process::Command};
use walkdir::WalkDir;
use crate::{config::Configuration, unity_editor::UnityEditor, unity_project::UnityProject};
use dpc_pariter::IteratorExt;
use std::{path::PathBuf, process::Command};
use walkdir::WalkDir;
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Hub {
@ -15,11 +14,16 @@ impl Hub {
Self { config, projects }
}
pub fn update_info(&mut self) {
pub fn update_data(&mut self) {
self.config.rebuild();
for project in self.projects.iter_mut() {
self.update_projects_info();
}
pub fn update_projects_info(&mut self) {
self.projects.iter_mut().for_each(|project| {
project.update_info();
}
});
self.projects.sort_by(|a, b| b.edit_time.cmp(&a.edit_time));
}
pub fn run_project_nr(&self, nr: usize) {
@ -52,30 +56,28 @@ impl Hub {
pub fn search_for_projects_at_path(&mut self, path: &PathBuf) -> usize {
let path_exists = std::fs::metadata(path).is_ok();
let mut result = 0;
if !path_exists {
return result;
return 0;
}
for entry in WalkDir::new(path)
let projects = self.projects.clone();
let new_projects: Vec<UnityProject> = WalkDir::new(path)
.max_depth(3)
.into_iter()
.filter_entry(|_| true)
{
let projects = self.projects.clone();
if entry.is_err() {
continue;
}
.parallel_filter(|entry| entry.is_ok())
.parallel_map(|entry| {
UnityProject::try_get_project_at_path(
&entry.unwrap().path().as_os_str().to_str().unwrap(),
)
})
.parallel_filter(|project| project.is_some())
.parallel_map(|project| project.unwrap())
.parallel_filter(move |p| !projects.contains(p))
.collect();
let entry_unwraped = entry.unwrap();
let path_string = entry_unwraped.path().as_os_str().to_str();
if let Some(project) = UnityProject::try_get_project_at_path(&path_string.unwrap()) {
if !projects.contains(&project) {
self.projects.push(project);
result = result + 1;
}
}
}
result
let len = new_projects.len();
self.projects.extend(new_projects);
len
}
}
impl Default for Hub {

View File

@ -2,6 +2,7 @@
extern crate serde_derive;
pub mod config;
pub mod consts;
pub mod hub;
pub mod unity_editor;
pub mod unity_project;

View File

@ -4,7 +4,9 @@ use std::borrow::Borrow;
use std::collections::HashMap;
use std::path::Path;
#[derive(Debug, Serialize, Deserialize, Clone)]
use crate::consts;
#[derive(Debug, Serialize, Deserialize, Clone, Eq, Hash)]
pub struct UnityEditor {
pub version: String,
pub exe_path: String,
@ -21,12 +23,12 @@ impl PartialEq for UnityEditor {
impl UnityEditor {
pub fn new(path: &str) -> Option<Self> {
let base_path = Path::new(path);
let exe_path = base_path.join("Unity.exe");
let exe_path = base_path.join(consts::UNITY_EXE_NAME);
if !std::fs::metadata(&exe_path).is_ok() {
return None;
}
let image = VecPE::from_disk_file(base_path.join("Unity.exe")).unwrap();
let image = VecPE::from_disk_file(&exe_path).unwrap();
let vs_version_check = VSVersionInfo::parse(&image);
if vs_version_check.is_err() {
return None;

View File

@ -1,4 +1,4 @@
use std::{path::Path, str};
use std::{ops::Sub, path::Path, str};
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct UnityProject {
@ -7,6 +7,7 @@ pub struct UnityProject {
pub version: String,
pub branch: String,
pub is_valid: bool,
pub edit_time: std::time::SystemTime,
}
impl PartialEq for UnityProject {
@ -31,7 +32,6 @@ impl UnityProject {
Security::Read,
)
.unwrap();
println!("{}", key.to_string());
for value in key.values() {
if value.is_err() {
@ -48,7 +48,6 @@ impl UnityProject {
if let Some(result) = UnityProject::try_get_project_at_path(&project_path) {
projects.push(result);
}
println!("\t{}: {}", unwraped_name, project_path);
}
}
projects
@ -76,13 +75,19 @@ impl UnityProject {
iter.next();
let project_version = iter.next().unwrap().to_string();
Some(UnityProject {
let mut project = UnityProject {
path: path.to_string(),
title: path.split("\\").last().unwrap().to_string(),
version: project_version,
branch: String::new(),
is_valid: true,
})
edit_time: std::time::SystemTime::now()
.sub(std::time::Duration::new(60 * 60 * 24 * 365 * 30, 0)),
};
project.update_info();
Some(project)
}
pub fn update_info(&mut self) {
@ -109,5 +114,10 @@ impl UnityProject {
self.branch = head_content.replace(HEAD_PREFIX, "").trim().to_string();
}
}
if let Ok(meta) = std::fs::metadata(&self.path) {
if let Ok(data) = meta.modified() {
self.edit_time = data;
}
}
}
}