use crate::{
cli::UpdateCommand,
ops::forc_dep_check,
utils::{dependency, helpers::read_manifest},
};
use anyhow::{anyhow, Result};
use dirs::home_dir;
use std::{path::PathBuf, str};
use sway_utils::{
constants::{self},
find_manifest_dir,
};
pub async fn update(command: UpdateCommand) -> Result<()> {
if command.check {
return forc_dep_check::check(command.path, command.target_dependency).await;
}
let UpdateCommand {
path,
target_dependency,
check: _,
} = command;
let this_dir = if let Some(path) = path {
PathBuf::from(path)
} else {
std::env::current_dir()?
};
let manifest_dir = match find_manifest_dir(&this_dir) {
Some(dir) => dir,
None => {
return Err(anyhow!(
"No manifest file found in this directory or any parent directories of it: {:?}",
this_dir
))
}
};
let mut manifest = read_manifest(&manifest_dir).unwrap();
let dependencies = dependency::get_detailed_dependencies(&mut manifest);
match target_dependency {
Some(target_dep) => match dependencies.get(&target_dep) {
Some(dep) => Ok(update_dependency(&target_dep, dep).await?),
None => return Err(anyhow!("dependency {} not found", target_dep)),
},
None => {
for (dependency_name, dep) in dependencies {
update_dependency(&dependency_name, dep).await?;
}
Ok(())
}
}
}
async fn update_dependency(
dependency_name: &str,
dep: &dependency::DependencyDetails,
) -> Result<()> {
let home_dir = match home_dir() {
None => return Err(anyhow!("Couldn't find home directory (`~/`)")),
Some(p) => p.to_str().unwrap().to_owned(),
};
if let Some(git) = &dep.git {
match &dep.version {
Some(version) => println!("Ignoring update for {} at version {}: Forc update not implemented for dependencies with specified tag. To update to another tag, change the tag in `Forc.toml` and run the build command.", dependency_name, version),
None => {
let target_directory = match &dep.branch {
Some(b) => PathBuf::from(format!("{}/{}/{}/{}", home_dir, constants::FORC_DEPENDENCIES_DIRECTORY, dependency_name, &b)),
None => PathBuf::from(format!("{}/{}/{}/default", home_dir, constants::FORC_DEPENDENCIES_DIRECTORY, dependency_name)),
};
let current = dependency::get_current_dependency_version(&target_directory)?;
let latest_hash = dependency::get_latest_commit_sha(git, &dep.branch).await?;
if current.hash == latest_hash {
println!("{} is up-to-date", dependency_name);
} else {
dependency::replace_dep_version(&target_directory, git, dep)?;
println!("{}: {} -> {}", dependency_name, current.hash, latest_hash);
}
}
}
}
Ok(())
}