Erste Version: Tauri-Grundgerüst, WinGet-Anbindung, Selbst-Updater und Release-Skript
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
commit
e0773ba299
84 files changed
+12688
No files matched your search
@@ -0,0 +1,126 @@
|
||||
//! Tauri-Befehle, die die Oberfläche aufruft.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use tauri::State;
|
||||
|
||||
use crate::error::{AppError, AppResult};
|
||||
use crate::managers::winget::WingetManager;
|
||||
use crate::managers::PackageManager;
|
||||
use crate::models::{ManagerId, ManagerInfo, Package, PackageDetails, Source};
|
||||
use crate::process;
|
||||
|
||||
/// Registrierte Paketmanager.
|
||||
pub struct Registry {
|
||||
managers: HashMap<ManagerId, Arc<dyn PackageManager>>,
|
||||
}
|
||||
|
||||
impl Registry {
|
||||
/// Erstellt die Registry mit allen verfügbaren Implementierungen.
|
||||
pub fn new() -> Self {
|
||||
let mut managers: HashMap<ManagerId, Arc<dyn PackageManager>> = HashMap::new();
|
||||
managers.insert(ManagerId::Winget, Arc::new(WingetManager::new()));
|
||||
Self { managers }
|
||||
}
|
||||
|
||||
fn get(&self, id: ManagerId) -> AppResult<Arc<dyn PackageManager>> {
|
||||
self.managers
|
||||
.get(&id)
|
||||
.cloned()
|
||||
.ok_or_else(|| AppError::Command("Dieser Paketmanager wird noch nicht unterstützt.".to_owned()))
|
||||
}
|
||||
|
||||
async fn detect_all(&self) -> Vec<ManagerInfo> {
|
||||
let mut infos = Vec::new();
|
||||
for manager in self.managers.values() {
|
||||
infos.push(manager.detect().await);
|
||||
}
|
||||
infos
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Registry {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
fn logged<T>(what: &str, result: AppResult<T>) -> AppResult<T> {
|
||||
if let Err(err) = &result {
|
||||
tracing::error!(%err, "{what} fehlgeschlagen");
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/// Erkennt alle Paketmanager (Pfad, Version, Zusatzkomponenten).
|
||||
#[tauri::command]
|
||||
pub async fn detect_managers(registry: State<'_, Registry>) -> AppResult<Vec<ManagerInfo>> {
|
||||
Ok(registry.detect_all().await)
|
||||
}
|
||||
|
||||
/// Sucht Pakete.
|
||||
#[tauri::command]
|
||||
pub async fn search_packages(registry: State<'_, Registry>, manager: ManagerId, query: String) -> AppResult<Vec<Package>> {
|
||||
let query = query.trim().to_owned();
|
||||
if query.is_empty() {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
logged("Paketsuche", registry.get(manager)?.search(&query).await)
|
||||
}
|
||||
|
||||
/// Listet installierte Pakete.
|
||||
#[tauri::command]
|
||||
pub async fn list_installed(registry: State<'_, Registry>, manager: ManagerId) -> AppResult<Vec<Package>> {
|
||||
logged("Liste der installierten Pakete", registry.get(manager)?.list_installed().await)
|
||||
}
|
||||
|
||||
/// Listet verfügbare Aktualisierungen.
|
||||
#[tauri::command]
|
||||
pub async fn list_updates(registry: State<'_, Registry>, manager: ManagerId) -> AppResult<Vec<Package>> {
|
||||
logged("Suche nach Aktualisierungen", registry.get(manager)?.list_updates().await)
|
||||
}
|
||||
|
||||
/// Lädt Paketdetails.
|
||||
#[tauri::command]
|
||||
pub async fn get_package_details(registry: State<'_, Registry>, package: Package) -> AppResult<PackageDetails> {
|
||||
logged("Paketdetails", registry.get(package.manager)?.get_details(&package).await)
|
||||
}
|
||||
|
||||
/// Listet die Quellen eines Managers.
|
||||
#[tauri::command]
|
||||
pub async fn list_sources(registry: State<'_, Registry>, manager: ManagerId) -> AppResult<Vec<Source>> {
|
||||
logged("Quellenliste", registry.get(manager)?.list_sources().await)
|
||||
}
|
||||
|
||||
async fn run_powershell(script: &str, timeout: Duration) -> AppResult<()> {
|
||||
let shell = which::which("powershell")
|
||||
.map_err(|_| AppError::ManagerMissing("Windows PowerShell".to_owned()))?;
|
||||
let out = process::run(&shell, &["-NoLogo", "-NoProfile", "-NonInteractive", "-Command", script], timeout).await?;
|
||||
if out.code == Some(0) {
|
||||
Ok(())
|
||||
} else {
|
||||
let detail = out.stderr.lines().find(|l| !l.trim().is_empty()).unwrap_or("unbekannter Fehler");
|
||||
Err(AppError::Command(format!("Die Installation ist fehlgeschlagen: {detail}")))
|
||||
}
|
||||
}
|
||||
|
||||
/// Installiert das PowerShell-Modul `Microsoft.WinGet.Client` für den aktuellen Benutzer.
|
||||
#[tauri::command]
|
||||
pub async fn install_winget_module(registry: State<'_, Registry>) -> AppResult<Vec<ManagerInfo>> {
|
||||
let script = "$ProgressPreference='SilentlyContinue'; $ErrorActionPreference='Stop'; \
|
||||
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Scope CurrentUser -Force | Out-Null; \
|
||||
Install-Module -Name Microsoft.WinGet.Client -Scope CurrentUser -Repository PSGallery -Force";
|
||||
logged("Modulinstallation", run_powershell(script, Duration::from_secs(300)).await)?;
|
||||
Ok(registry.detect_all().await)
|
||||
}
|
||||
|
||||
/// Registriert bzw. installiert den „App-Installer“ (enthält WinGet).
|
||||
#[tauri::command]
|
||||
pub async fn install_app_installer(registry: State<'_, Registry>) -> AppResult<Vec<ManagerInfo>> {
|
||||
let script = "$ProgressPreference='SilentlyContinue'; $ErrorActionPreference='Stop'; \
|
||||
Add-AppxPackage -RegisterByFamilyName -MainPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe";
|
||||
logged("Installation des App-Installers", run_powershell(script, Duration::from_secs(300)).await)?;
|
||||
Ok(registry.detect_all().await)
|
||||
}
|
||||
Reference in new issue
Block a user