support custom manifest
This commit is contained in:
@@ -26,6 +26,8 @@ pub struct EssentialsRepo {
|
|||||||
pub struct InstallTask {
|
pub struct InstallTask {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub version: Option<String>,
|
pub version: Option<String>,
|
||||||
|
pub use_manifest: bool,
|
||||||
|
pub manifest_url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AppSettings {
|
impl Default for AppSettings {
|
||||||
@@ -165,8 +167,14 @@ async fn get_updates(app: AppHandle) -> Vec<Software> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn install_software(id: String, version: Option<String>, state: State<'_, AppState>) -> Result<(), String> {
|
async fn install_software(
|
||||||
state.install_tx.send(InstallTask { id, version }).await.map_err(|e| e.to_string())
|
id: String,
|
||||||
|
version: Option<String>,
|
||||||
|
use_manifest: bool,
|
||||||
|
manifest_url: Option<String>,
|
||||||
|
state: State<'_, AppState>
|
||||||
|
) -> Result<(), String> {
|
||||||
|
state.install_tx.send(InstallTask { id, version, use_manifest, manifest_url }).await.map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -196,6 +204,8 @@ pub fn run() {
|
|||||||
while let Some(task) = rx.recv().await {
|
while let Some(task) = rx.recv().await {
|
||||||
let id = task.id;
|
let id = task.id;
|
||||||
let version = task.version;
|
let version = task.version;
|
||||||
|
let use_manifest = task.use_manifest;
|
||||||
|
let manifest_url = task.manifest_url;
|
||||||
|
|
||||||
let log_id = format!("install-{}", id);
|
let log_id = format!("install-{}", id);
|
||||||
let _ = handle.emit("install-status", InstallProgress {
|
let _ = handle.emit("install-status", InstallProgress {
|
||||||
@@ -204,31 +214,44 @@ pub fn run() {
|
|||||||
progress: 0.0,
|
progress: 0.0,
|
||||||
});
|
});
|
||||||
|
|
||||||
let display_cmd = match &version {
|
let mut args = vec!["install".to_string()];
|
||||||
Some(v) => format!("Winget Install: {} (v{})", id, v),
|
let display_cmd: String;
|
||||||
None => format!("Winget Install: {}", id),
|
|
||||||
};
|
|
||||||
emit_log(&handle, &log_id, &display_cmd, "Starting...", "info");
|
|
||||||
|
|
||||||
let id_for_cmd = id.clone();
|
if use_manifest && manifest_url.is_some() {
|
||||||
let h = handle.clone();
|
let url = manifest_url.unwrap();
|
||||||
|
args.push("--manifest".to_string());
|
||||||
|
args.push(url.clone());
|
||||||
|
display_cmd = format!("Winget Install (Manifest): {} from {}", id, url);
|
||||||
|
} else {
|
||||||
|
args.push("--id".to_string());
|
||||||
|
args.push(id.clone());
|
||||||
|
args.push("-e".to_string());
|
||||||
|
|
||||||
let mut args = vec![
|
if let Some(v) = &version {
|
||||||
"install".to_string(),
|
if !v.is_empty() {
|
||||||
"--id".to_string(), id_for_cmd.clone(),
|
args.push("--version".to_string());
|
||||||
"-e".to_string(),
|
args.push(v.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
display_cmd = match &version {
|
||||||
|
Some(v) if !v.is_empty() => format!("Winget Install: {} (v{})", id, v),
|
||||||
|
_ => format!("Winget Install: {}", id),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 共同的静默与协议参数
|
||||||
|
args.extend([
|
||||||
"--silent".to_string(),
|
"--silent".to_string(),
|
||||||
"--accept-package-agreements".to_string(),
|
"--accept-package-agreements".to_string(),
|
||||||
"--accept-source-agreements".to_string(),
|
"--accept-source-agreements".to_string(),
|
||||||
"--disable-interactivity".to_string(),
|
"--disable-interactivity".to_string(),
|
||||||
];
|
]);
|
||||||
|
|
||||||
if let Some(v) = version {
|
emit_log(&handle, &log_id, &display_cmd, "Starting...", "info");
|
||||||
if !v.is_empty() {
|
|
||||||
args.push("--version".to_string());
|
let id_for_progress = id.clone();
|
||||||
args.push(v);
|
let h = handle.clone();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let child = Command::new("winget")
|
let child = Command::new("winget")
|
||||||
.args(&args)
|
.args(&args)
|
||||||
@@ -253,7 +276,7 @@ pub fn run() {
|
|||||||
if let Some(caps) = perc_re.captures(clean_line) {
|
if let Some(caps) = perc_re.captures(clean_line) {
|
||||||
if let Ok(p_val) = caps[1].parse::<f32>() {
|
if let Ok(p_val) = caps[1].parse::<f32>() {
|
||||||
let _ = h.emit("install-status", InstallProgress {
|
let _ = h.emit("install-status", InstallProgress {
|
||||||
id: id_for_cmd.clone(),
|
id: id_for_progress.clone(),
|
||||||
status: "installing".to_string(),
|
status: "installing".to_string(),
|
||||||
progress: p_val / 100.0,
|
progress: p_val / 100.0,
|
||||||
});
|
});
|
||||||
@@ -265,7 +288,7 @@ pub fn run() {
|
|||||||
let total = caps[2].parse::<f32>().unwrap_or(1.0);
|
let total = caps[2].parse::<f32>().unwrap_or(1.0);
|
||||||
if total > 0.0 {
|
if total > 0.0 {
|
||||||
let _ = h.emit("install-status", InstallProgress {
|
let _ = h.emit("install-status", InstallProgress {
|
||||||
id: id_for_cmd.clone(),
|
id: id_for_progress.clone(),
|
||||||
status: "installing".to_string(),
|
status: "installing".to_string(),
|
||||||
progress: (current / total).min(1.0),
|
progress: (current / total).min(1.0),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,10 +16,14 @@ pub struct Software {
|
|||||||
pub status: String, // "idle", "pending", "installing", "success", "error"
|
pub status: String, // "idle", "pending", "installing", "success", "error"
|
||||||
#[serde(default = "default_progress")]
|
#[serde(default = "default_progress")]
|
||||||
pub progress: f32,
|
pub progress: f32,
|
||||||
|
#[serde(default = "default_false")]
|
||||||
|
pub use_manifest: bool,
|
||||||
|
pub manifest_url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_status() -> String { "idle".to_string() }
|
fn default_status() -> String { "idle".to_string() }
|
||||||
fn default_progress() -> f32 { 0.0 }
|
fn default_progress() -> f32 { 0.0 }
|
||||||
|
fn default_false() -> bool { false }
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(rename_all = "PascalCase")]
|
#[serde(rename_all = "PascalCase")]
|
||||||
@@ -276,5 +280,7 @@ fn map_package(p: WingetPackage) -> Software {
|
|||||||
icon_url: p.icon_url,
|
icon_url: p.icon_url,
|
||||||
status: "idle".to_string(),
|
status: "idle".to_string(),
|
||||||
progress: 0.0,
|
progress: 0.0,
|
||||||
|
use_manifest: false,
|
||||||
|
manifest_url: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,10 +119,13 @@ const props = defineProps<{
|
|||||||
name: string;
|
name: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
version?: string;
|
version?: string;
|
||||||
|
recommended_version?: string;
|
||||||
available_version?: string;
|
available_version?: string;
|
||||||
icon_url?: string;
|
icon_url?: string;
|
||||||
status: string;
|
status: string;
|
||||||
progress: number;
|
progress: number;
|
||||||
|
use_manifest?: boolean;
|
||||||
|
manifest_url?: string;
|
||||||
},
|
},
|
||||||
actionLabel?: string,
|
actionLabel?: string,
|
||||||
selectable?: boolean,
|
selectable?: boolean,
|
||||||
@@ -139,7 +142,7 @@ const displayProgress = computed(() => {
|
|||||||
const isInstalled = computed(() => {
|
const isInstalled = computed(() => {
|
||||||
return props.software.status === 'installed' ||
|
return props.software.status === 'installed' ||
|
||||||
(props.software.status === 'idle' && props.actionLabel === '更新') ||
|
(props.software.status === 'idle' && props.actionLabel === '更新') ||
|
||||||
(props.software.status === 'idle' && !props.actionLabel && props.software.installed_version);
|
(props.software.status === 'idle' && !props.actionLabel && props.software.version);
|
||||||
});
|
});
|
||||||
|
|
||||||
const isVersionLower = (current: string | undefined | null, target: string | undefined | null) => {
|
const isVersionLower = (current: string | undefined | null, target: string | undefined | null) => {
|
||||||
|
|||||||
@@ -194,7 +194,12 @@ export const useSoftwareStore = defineStore('software', {
|
|||||||
const software = this.findSoftware(id)
|
const software = this.findSoftware(id)
|
||||||
if (software) {
|
if (software) {
|
||||||
software.status = 'pending';
|
software.status = 'pending';
|
||||||
await invoke('install_software', { id, version: software.version })
|
await invoke('install_software', {
|
||||||
|
id,
|
||||||
|
version: software.version,
|
||||||
|
use_manifest: software.use_manifest,
|
||||||
|
manifest_url: software.manifest_url
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
findSoftware(id: string) {
|
findSoftware(id: string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user