use std::path::Path;
use super::discovery::NpmProject;
use super::pm_version_check;
use super::{PackageManager, PackageManagerResolver, pm_bun, pm_npm, pm_pnpm, pm_yarn};
use crate::model::{CheckResult, CommandResult, DependencyKind, UpdateResult};
pub async fn update_project(
project: &NpmProject,
_root: &Path,
outdated: &[CheckResult],
) -> Vec<UpdateResult> {
let (tool_versions, package_deps): (Vec<_>, Vec<_>) = outdated
.iter()
.partition(|r| r.kind() == DependencyKind::Tool);
let mut results = Vec::new();
if !package_deps.is_empty() {
let result = match project.package_manager {
PackageManager::Npm => pm_npm::Npm.update_packages(&project.path).await,
PackageManager::Pnpm => pm_pnpm::Pnpm.update_packages(&project.path).await,
PackageManager::Yarn => pm_yarn::Yarn.update_packages(&project.path).await,
PackageManager::Bun => pm_bun::Bun.update_packages(&project.path).await,
};
match result {
Ok(_) => {
results.extend(package_deps.iter().map(|r| {
UpdateResult::updated(r, r.latest_version().unwrap_or("").to_string())
}))
}
Err(e) => results.extend(
package_deps
.iter()
.map(|r| UpdateResult::error(r, e.to_string())),
),
}
}
for r in &tool_versions {
let new_version = r.latest_version().unwrap_or("");
if new_version.is_empty() {
results.push(UpdateResult::error(r, "No latest version available".into()));
continue;
}
match pm_version_check::update_pm_version(
&project.path,
project.package_manager.command(),
new_version,
) {
Ok(()) => results.push(UpdateResult::updated(r, new_version.to_string())),
Err(e) => results.push(UpdateResult::error(r, e.to_string())),
}
}
results
}