Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions scripts/download-bin.mjs
Original file line number Diff line number Diff line change
@@ -1,118 +1,116 @@
// scripts/download.js
import https from 'https'
import fs, { copyFile, mkdirSync } from 'fs'
import os from 'os'
import path from 'path'
import unzipper from 'unzipper'
import tar from 'tar'
import { copySync } from 'cpx'

Check warning on line 8 in scripts/download-bin.mjs

View workflow job for this annotation

GitHub Actions / coverage-check

1-8 lines are not covered with tests

function download(url, dest) {
return new Promise((resolve, reject) => {
console.log(`Downloading ${url} to ${dest}`)
const file = fs.createWriteStream(dest)
https
.get(url, (response) => {
console.log(`Response status code: ${response.statusCode}`)
if (
response.statusCode >= 300 &&
response.statusCode < 400 &&
response.headers.location
) {
// Handle redirect
const redirectURL = response.headers.location
console.log(`Redirecting to ${redirectURL}`)
download(redirectURL, dest).then(resolve, reject) // Recursive call
return
} else if (response.statusCode !== 200) {
reject(`Failed to get '${url}' (${response.statusCode})`)
return
}
response.pipe(file)
file.on('finish', () => {
file.close(resolve)
})
})
.on('error', (err) => {
fs.unlink(dest, () => reject(err.message))
})
})
}

Check warning on line 40 in scripts/download-bin.mjs

View workflow job for this annotation

GitHub Actions / coverage-check

10-40 lines are not covered with tests

async function decompress(filePath, targetDir) {
console.log(`Decompressing ${filePath} to ${targetDir}`)
if (filePath.endsWith('.zip')) {
await fs
.createReadStream(filePath)
.pipe(unzipper.Extract({ path: targetDir }))
.promise()
} else if (filePath.endsWith('.tar.gz')) {
await tar.x({
file: filePath,
cwd: targetDir,
})
} else {
throw new Error(`Unsupported archive format: ${filePath}`)
}
}

Check warning on line 57 in scripts/download-bin.mjs

View workflow job for this annotation

GitHub Actions / coverage-check

42-57 lines are not covered with tests

function getPlatformArch() {
const platform = os.platform() // 'darwin', 'linux', 'win32'
const arch = os.arch() // 'x64', 'arm64', etc.

Check warning on line 61 in scripts/download-bin.mjs

View workflow job for this annotation

GitHub Actions / coverage-check

59-61 lines are not covered with tests

let bunPlatform, uvPlatform

Check warning on line 63 in scripts/download-bin.mjs

View workflow job for this annotation

GitHub Actions / coverage-check

63 line is not covered with tests

if (platform === 'darwin') {
bunPlatform = arch === 'arm64' ? 'darwin-aarch64' : 'darwin-x86'
uvPlatform =
arch === 'arm64' ? 'aarch64-apple-darwin' : 'x86_64-apple-darwin'
} else if (platform === 'linux') {
bunPlatform = arch === 'arm64' ? 'linux-aarch64' : 'linux-x64'
uvPlatform =
arch === 'arm64'
? 'aarch64-unknown-linux-gnu'
: 'x86_64-unknown-linux-gnu'
} else if (platform === 'win32') {
bunPlatform = 'windows-x64' // Bun has limited Windows support
uvPlatform = 'x86_64-pc-windows-msvc'
} else {
throw new Error(`Unsupported platform: ${platform}`)
}

Check warning on line 80 in scripts/download-bin.mjs

View workflow job for this annotation

GitHub Actions / coverage-check

65-80 lines are not covered with tests

return { bunPlatform, uvPlatform }
}

Check warning on line 83 in scripts/download-bin.mjs

View workflow job for this annotation

GitHub Actions / coverage-check

82-83 lines are not covered with tests

async function main() {
if (process.env.SKIP_BINARIES) {
console.log('Skipping binaries download.')
process.exit(0)
}
console.log('Starting main function')
const platform = os.platform()
const { bunPlatform, uvPlatform } = getPlatformArch()
console.log(`bunPlatform: ${bunPlatform}, uvPlatform: ${uvPlatform}`)

Check warning on line 93 in scripts/download-bin.mjs

View workflow job for this annotation

GitHub Actions / coverage-check

85-93 lines are not covered with tests

const binDir = 'src-tauri/resources/bin'
const tempBinDir = 'scripts/dist'
const bunPath = `${tempBinDir}/bun-${bunPlatform}.zip`
let uvPath = `${tempBinDir}/uv-${uvPlatform}.tar.gz`
if (platform === 'win32') {
uvPath = `${tempBinDir}/uv-${uvPlatform}.zip`
}
try {
mkdirSync('scripts/dist')
} catch (err) {
// Expect EEXIST error if the directory already exists
}

Check warning on line 106 in scripts/download-bin.mjs

View workflow job for this annotation

GitHub Actions / coverage-check

95-106 lines are not covered with tests

// Adjust these URLs based on latest releases
const bunVersion = '1.2.10' // Example Bun version
const bunUrl = `https://github.com/oven-sh/bun/releases/download/bun-v${bunVersion}/bun-${bunPlatform}.zip`
const bunUrl = `https://github.com/oven-sh/bun/releases/latest/download/bun-${bunPlatform}.zip`

Check warning on line 109 in scripts/download-bin.mjs

View workflow job for this annotation

GitHub Actions / coverage-check

108-109 lines are not covered with tests

const uvVersion = '0.6.17' // Example UV version
let uvUrl = `https://github.com/astral-sh/uv/releases/download/${uvVersion}/uv-${uvPlatform}.tar.gz`
let uvUrl = `https://github.com/astral-sh/uv/releases/latest/download/uv-${uvPlatform}.tar.gz`
if (platform === 'win32') {
uvUrl = `https://github.com/astral-sh/uv/releases/download/${uvVersion}/uv-${uvPlatform}.zip`
uvUrl = `https://github.com/astral-sh/uv/releases/latest/download/uv-${uvPlatform}.zip`
}

console.log(`Downloading Bun for ${bunPlatform}...`)
Expand Down
21 changes: 16 additions & 5 deletions src-tauri/src/core/mcp/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -627,17 +627,28 @@ async fn schedule_mcp_start_task<R: Runtime>(
}
} else {
let mut cmd = Command::new(config_params.command.clone());
let bun_x_path = format!("{}/bun", bin_path.display());
if config_params.command.clone() == "npx" && can_override_npx(bun_x_path.clone()) {
let bun_x_path = if cfg!(windows) {
bin_path.join("bun.exe")
} else {
bin_path.join("bun")
};
if config_params.command.clone() == "npx"
&& can_override_npx(bun_x_path.display().to_string())
{
let mut cache_dir = app_path.clone();
cache_dir.push(".npx");
cmd = Command::new(bun_x_path);
cmd = Command::new(bun_x_path.display().to_string());
cmd.arg("x");
cmd.env("BUN_INSTALL", cache_dir.to_str().unwrap().to_string());
}

let uv_path = format!("{}/uv", bin_path.display());
if config_params.command.clone() == "uvx" && can_override_uvx(uv_path.clone()) {
let uv_path = if cfg!(windows) {
bin_path.join("uv.exe")
} else {
bin_path.join("uv")
};
if config_params.command.clone() == "uvx" && can_override_uvx(uv_path.display().to_string())
{
let mut cache_dir = app_path.clone();
cache_dir.push(".uvx");
cmd = Command::new(uv_path);
Expand Down
40 changes: 40 additions & 0 deletions src-tauri/src/core/mcp/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::core::state::SharedMcpServers;
use std::collections::HashMap;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use std::sync::Arc;
use tauri::test::mock_app;
use tokio::sync::Mutex;
Expand Down Expand Up @@ -37,3 +38,42 @@ async fn test_run_mcp_commands() {
// Clean up the mock config file
std::fs::remove_file(&config_path).expect("Failed to remove config file");
}

#[test]
fn test_bin_path_construction_with_join() {
// Test that PathBuf::join properly constructs paths
let bin_path = PathBuf::from("/usr/local/bin");
let bun_path = bin_path.join("bun");

assert_eq!(bun_path.to_string_lossy(), "/usr/local/bin/bun");

// Test conversion to String via display()
let bun_path_str = bun_path.display().to_string();
assert_eq!(bun_path_str, "/usr/local/bin/bun");
}

#[test]
fn test_uv_path_construction_with_join() {
// Test that PathBuf::join properly constructs paths for uv
let bin_path = PathBuf::from("/usr/local/bin");
let uv_path = bin_path.join("uv");

assert_eq!(uv_path.to_string_lossy(), "/usr/local/bin/uv");

// Test conversion to String via display()
let uv_path_str = uv_path.display().to_string();
assert_eq!(uv_path_str, "/usr/local/bin/uv");
}

#[cfg(target_os = "windows")]
#[test]
fn test_bin_path_construction_windows() {
// Test Windows-style paths
let bin_path = PathBuf::from(r"C:\Program Files\bin");
let bun_path = bin_path.join("bun");

assert_eq!(bun_path.to_string_lossy(), r"C:\Program Files\bin\bun");

let bun_path_str = bun_path.display().to_string();
assert_eq!(bun_path_str, r"C:\Program Files\bin\bun");
}
1 change: 0 additions & 1 deletion src-tauri/src/core/threads/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
pub mod commands;
mod constants;
pub mod helpers;
pub mod models;
pub mod utils;

#[cfg(test)]
Expand Down
103 changes: 0 additions & 103 deletions src-tauri/src/core/threads/models.rs

This file was deleted.

Loading