initial commit
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Ife1391ed23a1e7f388b1b5eca90b9ea76a6a6964
This commit is contained in:
commit
ef28bdaeb4
63 changed files with 17292 additions and 0 deletions
140
src/cli/commands/update.rs
Normal file
140
src/cli/commands/update.rs
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
use std::{collections::HashMap, path::Path};
|
||||
|
||||
use indicatif::{ProgressBar, ProgressStyle};
|
||||
|
||||
use crate::{
|
||||
cli::UpdateArgs,
|
||||
error::PakkerError,
|
||||
model::{Config, LockFile},
|
||||
platform::create_platform,
|
||||
ui_utils::prompt_select,
|
||||
};
|
||||
|
||||
pub async fn execute(
|
||||
args: UpdateArgs,
|
||||
lockfile_path: &Path,
|
||||
config_path: &Path,
|
||||
) -> Result<(), PakkerError> {
|
||||
// Load expects directory path, so get parent directory
|
||||
let lockfile_dir = lockfile_path.parent().unwrap_or(Path::new("."));
|
||||
let config_dir = config_path.parent().unwrap_or(Path::new("."));
|
||||
|
||||
let mut lockfile = LockFile::load(lockfile_dir)?;
|
||||
let _config = Config::load(config_dir)?;
|
||||
|
||||
// Create platforms
|
||||
let mut platforms = HashMap::new();
|
||||
if let Ok(platform) = create_platform("modrinth", None) {
|
||||
platforms.insert("modrinth".to_string(), platform);
|
||||
}
|
||||
if let Ok(platform) =
|
||||
create_platform("curseforge", std::env::var("CURSEFORGE_API_KEY").ok())
|
||||
{
|
||||
platforms.insert("curseforge".to_string(), platform);
|
||||
}
|
||||
|
||||
let project_indices: Vec<_> = if args.inputs.is_empty() {
|
||||
(0..lockfile.projects.len()).collect()
|
||||
} else {
|
||||
let mut indices = Vec::new();
|
||||
for input in &args.inputs {
|
||||
if let Some((idx, _)) = lockfile
|
||||
.projects
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, p)| p.matches_input(input))
|
||||
{
|
||||
indices.push(idx);
|
||||
} else {
|
||||
return Err(PakkerError::ProjectNotFound(input.clone()));
|
||||
}
|
||||
}
|
||||
indices
|
||||
};
|
||||
|
||||
// Create progress bar
|
||||
let pb = ProgressBar::new(project_indices.len() as u64);
|
||||
pb.set_style(
|
||||
ProgressStyle::default_bar()
|
||||
.template("{spinner:.green} [{bar:40.cyan/blue}] {pos}/{len} {msg}")
|
||||
.unwrap()
|
||||
.progress_chars("#>-"),
|
||||
);
|
||||
|
||||
for idx in project_indices {
|
||||
let old_project = &lockfile.projects[idx];
|
||||
pb.set_message(format!("Updating {}...", old_project.get_name()));
|
||||
|
||||
let slug = old_project
|
||||
.slug
|
||||
.values()
|
||||
.next()
|
||||
.ok_or_else(|| PakkerError::InvalidProject("No slug found".into()))?;
|
||||
|
||||
// Find updated project from one of the platforms
|
||||
let mut updated_project = None;
|
||||
for platform in platforms.values() {
|
||||
if let Ok(project) = platform
|
||||
.request_project_with_files(
|
||||
slug,
|
||||
&lockfile.mc_versions,
|
||||
&lockfile.loaders.keys().cloned().collect::<Vec<_>>(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
updated_project = Some(project);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mut updated_project) = updated_project
|
||||
&& !updated_project.files.is_empty()
|
||||
&& let Some(old_file) = lockfile.projects[idx].files.first()
|
||||
{
|
||||
let new_file = updated_project.files.first().unwrap();
|
||||
|
||||
if new_file.id == old_file.id {
|
||||
pb.println(format!(
|
||||
" {} - Already up to date",
|
||||
old_project.get_name()
|
||||
));
|
||||
} else {
|
||||
// Interactive version selection if not using --yes flag
|
||||
if !args.yes && updated_project.files.len() > 1 {
|
||||
pb.suspend(|| {
|
||||
let choices: Vec<String> = updated_project
|
||||
.files
|
||||
.iter()
|
||||
.map(|f| format!("{} ({})", f.file_name, f.id))
|
||||
.collect();
|
||||
|
||||
let choice_refs: Vec<&str> =
|
||||
choices.iter().map(std::string::String::as_str).collect();
|
||||
|
||||
if let Ok(selected_idx) = prompt_select(
|
||||
&format!("Select version for {}:", old_project.get_name()),
|
||||
&choice_refs,
|
||||
) {
|
||||
// Move selected file to front
|
||||
if selected_idx > 0 {
|
||||
updated_project.files.swap(0, selected_idx);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let selected_file = updated_project.files.first().unwrap();
|
||||
pb.println(format!(
|
||||
" {} -> {}",
|
||||
old_file.file_name, selected_file.file_name
|
||||
));
|
||||
lockfile.projects[idx] = updated_project;
|
||||
}
|
||||
}
|
||||
pb.inc(1);
|
||||
}
|
||||
|
||||
pb.finish_with_message("Update complete");
|
||||
lockfile.save(lockfile_dir)?;
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue