change quickjs to upstream one

This commit is contained in:
Julian Freeman
2025-12-02 13:30:16 -04:00
parent 4daba48b1f
commit aacf765666
4 changed files with 119 additions and 56 deletions

View File

@@ -5,11 +5,14 @@ use tauri::AppHandle;
use anyhow::{Result, anyhow};
#[cfg(target_family = "unix")]
use std::os::unix::fs::PermissionsExt;
use zip::ZipArchive;
use std::io::Cursor;
use crate::storage::{self};
const YT_DLP_REPO_URL: &str = "https://github.com/yt-dlp/yt-dlp/releases/latest/download";
const QJS_REPO_URL: &str = "https://github.com/quickjs-ng/quickjs/releases/latest/download";
// Bellard's QuickJS binary releases URL
const QJS_REPO_URL: &str = "https://bellard.org/quickjs/binary_releases";
pub fn get_ytdlp_binary_name() -> &'static str {
if cfg!(target_os = "windows") {
@@ -30,16 +33,10 @@ pub fn get_qjs_binary_name() -> &'static str {
}
}
// Source name inside the zip archive or direct download
// Updated based on actual release assets:
// Windows: qjs-windows-x86_64.exe (direct executable)
// macOS: qjs-darwin (direct executable)
// Note: The logic now needs to support direct download, not just zip.
fn get_qjs_download_filename() -> &'static str {
// Source name inside the zip archive (standard QuickJS naming)
fn get_qjs_source_name_in_zip() -> &'static str {
if cfg!(target_os = "windows") {
"qjs-windows-x86_64.exe"
} else if cfg!(target_os = "macos") {
"qjs-darwin"
"qjs.exe"
} else {
"qjs"
}
@@ -143,28 +140,80 @@ pub fn get_ytdlp_version(app: &AppHandle) -> Result<String> {
// --- QuickJS Logic ---
pub async fn download_qjs(app: &AppHandle) -> Result<PathBuf> {
// Determine asset name based on OS/Arch
// Updated to match actual GitHub Release assets (direct executables, not zips)
let asset_name = get_qjs_download_filename();
#[derive(serde::Deserialize)]
struct LatestInfo {
version: String,
}
let url = format!("{}/{}", QJS_REPO_URL, asset_name);
let response = reqwest::get(&url).await?;
pub async fn download_qjs(app: &AppHandle) -> Result<PathBuf> {
// 1. Fetch LATEST.json to get version info (though filenames seem predictable-ish, version helps)
// Actually, looking at the file list, Bellard uses date-based versions.
// Format: quickjs-win-x86_64-YYYY-MM-DD.zip
// We need to find the correct filename dynamically or parse LATEST.json if it gave filenames.
// The LATEST.json content was {"version":"2024-01-13"} (example from prompt context).
// So we can construct the filename: quickjs-{platform}-{version}.zip
let latest_url = format!("{}/LATEST.json", QJS_REPO_URL);
let latest_resp = reqwest::get(&latest_url).await?;
if !latest_resp.status().is_success() {
return Err(anyhow!("Failed to fetch QuickJS version info"));
}
let latest_info: LatestInfo = latest_resp.json().await?;
let version = latest_info.version;
// Construct filename based on OS/Arch
let filename = if cfg!(target_os = "windows") {
format!("quickjs-win-x86_64-{}.zip", version)
} else if cfg!(target_os = "macos") {
// NOTE: Cosmo builds are universal/portable for Linux/Mac usually?
// Based on prompt instruction: "macos download quickjs-cosmo marked file"
// Bellard lists: quickjs-cosmo-YYYY-MM-DD.zip
format!("quickjs-cosmo-{}.zip", version)
} else {
return Err(anyhow!("Unsupported OS for QuickJS auto-download"));
};
let download_url = format!("{}/{}", QJS_REPO_URL, filename);
let response = reqwest::get(&download_url).await?;
if !response.status().is_success() {
return Err(anyhow!("Failed to download QuickJS: Status {}", response.status()));
}
let bytes = response.bytes().await?;
// Direct write, no zip extraction needed
let cursor = Cursor::new(bytes);
let mut archive = ZipArchive::new(cursor)?;
let bin_dir = get_bin_dir(app)?;
let final_path = get_qjs_path(app)?;
// Extract logic: The zip from Bellard usually contains a folder or just binaries.
// We need to find the `qjs` binary.
// Windows zip usually has `qjs.exe`
// Cosmo zip usually has `qjs`? Let's search for it.
if let Some(parent) = final_path.parent() {
fs::create_dir_all(parent)?;
let source_name = get_qjs_source_name_in_zip();
let target_name = get_qjs_binary_name(); // quickjs.exe or quickjs
let mut found = false;
for i in 0..archive.len() {
let mut file = archive.by_index(i)?;
// Filenames in zip might be like "quickjs-win-x86_64-2024-01-13/qjs.exe"
let name = file.name();
let filename_only = name.split('/').last().unwrap_or("");
if filename_only == source_name {
let mut out_file = fs::File::create(bin_dir.join(target_name))?;
std::io::copy(&mut file, &mut out_file)?;
found = true;
break;
}
}
fs::write(&final_path, bytes)?;
if !found {
return Err(anyhow!("Could not find {} in downloaded archive", source_name));
}
let final_path = get_qjs_path(app)?;
#[cfg(target_family = "unix")]
{
@@ -187,11 +236,6 @@ pub fn get_qjs_version(app: &AppHandle) -> Result<String> {
if !path.exists() {
return Ok("Not installed".to_string());
}
// Try to get version if possible, otherwise just say Installed
// Running with -h usually works and prints version in first line often
// But let's stick to simple existence check for stability unless we need exact version.
// Or we can check file creation time.
Ok("Installed".to_string())
}
@@ -218,12 +262,11 @@ mod tests {
if cfg!(target_os = "windows") {
assert_eq!(get_ytdlp_binary_name(), "yt-dlp.exe");
assert_eq!(get_qjs_binary_name(), "quickjs.exe");
// Check download filename
assert_eq!(get_qjs_download_filename(), "qjs-windows-x86_64.exe");
assert_eq!(get_qjs_source_name_in_zip(), "qjs.exe");
} else if cfg!(target_os = "macos") {
assert_eq!(get_ytdlp_binary_name(), "yt-dlp_macos");
assert_eq!(get_qjs_binary_name(), "quickjs");
assert_eq!(get_qjs_download_filename(), "qjs-darwin");
assert_eq!(get_qjs_source_name_in_zip(), "qjs");
}
}
}
}