feat: use humansize crate and which crate for program lookup
Co-authored-by: aider (openai/andrew/openrouter/qwen/qwen3-coder) <aider@aider.chat>
This commit is contained in:
@@ -1,15 +1,10 @@
|
||||
use anyhow::{Context, Result, anyhow};
|
||||
use log::*;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use std::path::PathBuf;
|
||||
use std::process::{Child, Command, Stdio};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
use once_cell::sync::Lazy;
|
||||
use which::which;
|
||||
|
||||
use crate::compression_engine::CompressionEngine;
|
||||
|
||||
@@ -69,11 +64,11 @@ impl CompressionEngineProgram {
|
||||
compress: Vec<&str>,
|
||||
decompress: Vec<&str>,
|
||||
) -> CompressionEngineProgram {
|
||||
let program_path = get_program_path(program);
|
||||
let program_path = which(program);
|
||||
let supported = program_path.is_ok();
|
||||
|
||||
CompressionEngineProgram {
|
||||
program: program_path.unwrap_or(program.to_string()),
|
||||
program: program_path.map_or_else(|_| program.to_string(), |p| p.to_string_lossy().to_string()),
|
||||
compress: compress.iter().map(|s| s.to_string()).collect(),
|
||||
decompress: decompress.iter().map(|s| s.to_string()).collect(),
|
||||
supported,
|
||||
@@ -81,54 +76,6 @@ impl CompressionEngineProgram {
|
||||
}
|
||||
}
|
||||
|
||||
// Cache for program lookup results to avoid redundant filesystem operations
|
||||
static PROGRAM_CACHE: Lazy<Mutex<HashMap<String, Option<String>>>> =
|
||||
Lazy::new(|| Mutex::new(HashMap::new()));
|
||||
|
||||
fn get_program_path(program: &str) -> Result<String> {
|
||||
// Check cache first
|
||||
{
|
||||
let cache = PROGRAM_CACHE.lock().unwrap();
|
||||
if let Some(result) = cache.get(program) {
|
||||
return match result {
|
||||
Some(path) => Ok(path.clone()),
|
||||
None => Err(anyhow!("Unable to find binary {} in PATH", program)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
debug!("COMPRESSION: Looking for executable: {}", program);
|
||||
let result = if let Ok(path) = env::var("PATH") {
|
||||
let mut found_path = None;
|
||||
for p in path.split(':') {
|
||||
let p_str = format!("{}/{}", p, program);
|
||||
if let Ok(stat) = fs::metadata(&p_str) {
|
||||
let permissions = stat.permissions();
|
||||
if stat.is_file() && permissions.mode() & 0o111 != 0 {
|
||||
found_path = Some(p_str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
found_path
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Store result in cache
|
||||
let mut cache = PROGRAM_CACHE.lock().unwrap();
|
||||
match &result {
|
||||
Some(path) => {
|
||||
cache.insert(program.to_string(), Some(path.clone()));
|
||||
Ok(path.clone())
|
||||
}
|
||||
None => {
|
||||
cache.insert(program.to_string(), None);
|
||||
Err(anyhow!("Unable to find binary {} in PATH", program))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CompressionEngine for CompressionEngineProgram {
|
||||
fn is_supported(&self) -> bool {
|
||||
self.supported
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
use crate::plugins::ProgramWriter;
|
||||
use anyhow::{Context, Result, anyhow};
|
||||
use log::*;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
use once_cell::sync::Lazy;
|
||||
use which::which;
|
||||
|
||||
use crate::meta_plugin::MetaPlugin;
|
||||
|
||||
@@ -25,11 +20,11 @@ pub struct MetaPluginProgram {
|
||||
|
||||
impl MetaPluginProgram {
|
||||
pub fn new(program: &str, args: Vec<&str>, meta_name: String, split_whitespace: bool) -> MetaPluginProgram {
|
||||
let program_path = get_program_path(program);
|
||||
let program_path = which(program);
|
||||
let supported = program_path.is_ok();
|
||||
|
||||
MetaPluginProgram {
|
||||
program: program_path.unwrap_or(program.to_string()),
|
||||
program: program_path.map_or_else(|_| program.to_string(), |p| p.to_string_lossy().to_string()),
|
||||
args: args.iter().map(|s| s.to_string()).collect(),
|
||||
supported,
|
||||
meta_name,
|
||||
@@ -134,51 +129,3 @@ impl MetaPlugin for MetaPluginProgram {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Cache for program lookup results to avoid redundant filesystem operations
|
||||
static PROGRAM_CACHE: Lazy<Mutex<HashMap<String, Option<String>>>> =
|
||||
Lazy::new(|| Mutex::new(HashMap::new()));
|
||||
|
||||
fn get_program_path(program: &str) -> Result<String> {
|
||||
// Check cache first
|
||||
{
|
||||
let cache = PROGRAM_CACHE.lock().unwrap();
|
||||
if let Some(result) = cache.get(program) {
|
||||
return match result {
|
||||
Some(path) => Ok(path.clone()),
|
||||
None => Err(anyhow!("Unable to find binary {} in PATH", program)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
debug!("META: Looking for executable: {}", program);
|
||||
let result = if let Ok(path) = env::var("PATH") {
|
||||
let mut found_path = None;
|
||||
for p in path.split(':') {
|
||||
let p_str = format!("{}/{}", p, program);
|
||||
if let Ok(stat) = fs::metadata(&p_str) {
|
||||
let permissions = stat.permissions();
|
||||
if stat.is_file() && permissions.mode() & 0o111 != 0 {
|
||||
found_path = Some(p_str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
found_path
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Store result in cache
|
||||
let mut cache = PROGRAM_CACHE.lock().unwrap();
|
||||
match &result {
|
||||
Some(path) => {
|
||||
cache.insert(program.to_string(), Some(path.clone()));
|
||||
Ok(path.clone())
|
||||
}
|
||||
None => {
|
||||
cache.insert(program.to_string(), None);
|
||||
Err(anyhow!("Unable to find binary {} in PATH", program))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,34 +29,9 @@ pub fn get_meta_from_env() -> HashMap<String, String> {
|
||||
meta_env
|
||||
}
|
||||
|
||||
pub fn format_size_human_readable(size: u64) -> String {
|
||||
const UNITS: &[&str] = &["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei"];
|
||||
const THRESHOLD: u64 = 1024;
|
||||
|
||||
if size == 0 {
|
||||
return "0".to_string();
|
||||
}
|
||||
|
||||
let mut size_f = size as f64;
|
||||
let mut unit_index = 0;
|
||||
|
||||
while size_f >= THRESHOLD as f64 && unit_index < UNITS.len() - 1 {
|
||||
size_f /= THRESHOLD as f64;
|
||||
unit_index += 1;
|
||||
}
|
||||
|
||||
if unit_index == 0 {
|
||||
format!("{}", size)
|
||||
} else if size_f.fract() == 0.0 {
|
||||
format!("{}{}", size_f as u64, UNITS[unit_index])
|
||||
} else {
|
||||
format!("{:.1}{}", size_f, UNITS[unit_index])
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format_size(size: u64, human_readable: bool) -> String {
|
||||
match human_readable {
|
||||
true => format_size_human_readable(size),
|
||||
true => humansize::format_size(size, humansize::DECIMAL),
|
||||
false => size.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user