Files
gui-video-clipper/src-tauri/src/services/dependency_manager.rs

132 lines
4.0 KiB
Rust
Raw Normal View History

use crate::models::DependencyStatus;
use std::process::Command;
pub fn check_tool_exists(name: &str) -> Option<String> {
let output = Command::new("which").arg(name).output().ok()?;
if output.status.success() {
let version_output = Command::new(name).arg("--version").output().ok()?;
let version = String::from_utf8_lossy(&version_output.stdout)
.lines()
.next()
.unwrap_or("")
.trim()
.to_string();
Some(version)
} else {
None
}
}
pub fn check_js_runtime() -> Option<String> {
check_tool_exists("deno").or_else(|| check_tool_exists("node"))
}
pub fn check_pot_plugin() -> bool {
let output = Command::new("yt-dlp")
.args(["-v", "--simulate", "https://www.youtube.com/watch?v=dQw4w9WgXcQ"])
.output();
match output {
Ok(out) => {
let stderr = String::from_utf8_lossy(&out.stderr);
stderr.contains("GetPOT")
}
Err(_) => false,
}
}
pub fn get_all_dependency_statuses() -> Vec<DependencyStatus> {
let ffmpeg = check_tool_exists("ffmpeg");
let ytdlp = check_tool_exists("yt-dlp");
let js_runtime = check_js_runtime();
let pot_plugin = if ytdlp.is_some() {
check_pot_plugin()
} else {
false
};
vec![
DependencyStatus {
name: "ffmpeg".to_string(),
installed: ffmpeg.is_some(),
version: ffmpeg,
install_command: "brew install ffmpeg".to_string(),
},
DependencyStatus {
name: "yt-dlp".to_string(),
installed: ytdlp.is_some(),
version: ytdlp,
install_command: "brew install yt-dlp".to_string(),
},
DependencyStatus {
name: "JavaScript runtime (deno/node)".to_string(),
installed: js_runtime.is_some(),
version: js_runtime,
install_command: "brew install deno".to_string(),
},
DependencyStatus {
name: "bgutil-ytdlp-pot-provider".to_string(),
installed: pot_plugin,
version: None,
install_command: "python3 -m pip install -U bgutil-ytdlp-pot-provider".to_string(),
},
]
}
pub fn get_install_args(dep_name: &str) -> Result<Vec<String>, String> {
match dep_name {
"ffmpeg" => Ok(vec![
"brew".into(), "install".into(), "ffmpeg".into(),
]),
"yt-dlp" => Ok(vec![
"brew".into(), "install".into(), "yt-dlp".into(),
]),
"JavaScript runtime (deno/node)" => Ok(vec![
"brew".into(), "install".into(), "deno".into(),
]),
"bgutil-ytdlp-pot-provider" => Ok(vec![
"python3".into(), "-m".into(), "pip".into(), "install".into(), "-U".into(), "bgutil-ytdlp-pot-provider".into(),
]),
_ => Err(format!("Unknown dependency: {dep_name}")),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_install_args_ffmpeg() {
let args = get_install_args("ffmpeg").unwrap();
assert_eq!(args, vec!["brew", "install", "ffmpeg"]);
}
#[test]
fn test_get_install_args_ytdlp() {
let args = get_install_args("yt-dlp").unwrap();
assert_eq!(args, vec!["brew", "install", "yt-dlp"]);
}
#[test]
fn test_get_install_args_pot_provider() {
let args = get_install_args("bgutil-ytdlp-pot-provider").unwrap();
assert_eq!(args, vec!["python3", "-m", "pip", "install", "-U", "bgutil-ytdlp-pot-provider"]);
}
#[test]
fn test_get_install_args_unknown() {
assert!(get_install_args("unknown-tool").is_err());
}
#[test]
fn test_dependency_statuses_has_four_entries() {
let statuses = get_all_dependency_statuses();
assert_eq!(statuses.len(), 4);
assert_eq!(statuses[0].name, "ffmpeg");
assert_eq!(statuses[1].name, "yt-dlp");
assert_eq!(statuses[2].name, "JavaScript runtime (deno/node)");
assert_eq!(statuses[3].name, "bgutil-ytdlp-pot-provider");
}
}