From 47dae951feeac12c086dc3ae4d8412cc3f630571 Mon Sep 17 00:00:00 2001 From: TheAlan404 Date: Fri, 9 Aug 2024 15:07:55 +0000 Subject: [PATCH] thingies --- Cargo.lock | 25 ++++++++++++++-- Cargo.toml | 1 + src/api/app/actions/update/mod.rs | 0 src/api/models/addon/addon_type.rs | 15 ++++++++++ src/api/models/modpack_source.rs | 6 ++-- src/api/models/mrpack/mrpack_file.rs | 2 +- src/api/models/source.rs | 10 +++---- src/api/utils/mod.rs | 1 + src/api/utils/update_writer.rs | 45 ++++++++++++++++++++++++++++ src/commands/export/mod.rs | 21 +++++++++++++ src/commands/export/mrpack.rs | 16 ++++++++++ src/commands/export/packwiz.rs | 16 ++++++++++ src/commands/mod.rs | 1 + src/commands/sources/list.rs | 28 +++++++++++++++-- src/commands/update.rs | 4 +-- src/main.rs | 24 +++++++++++++-- 16 files changed, 198 insertions(+), 17 deletions(-) create mode 100644 src/api/app/actions/update/mod.rs create mode 100644 src/api/utils/update_writer.rs create mode 100644 src/commands/export/mod.rs create mode 100644 src/commands/export/mrpack.rs create mode 100644 src/commands/export/packwiz.rs diff --git a/Cargo.lock b/Cargo.lock index 8f86c6d..9997071 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1246,6 +1246,7 @@ dependencies = [ "tokio-tungstenite", "tokio-util", "toml 0.8.8", + "toml_edit 0.22.12", "walkdir", "zip", ] @@ -2230,7 +2231,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.21.0", ] [[package]] @@ -2252,7 +2253,18 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.5.34", +] + +[[package]] +name = "toml_edit" +version = "0.22.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow 0.6.18", ] [[package]] @@ -2686,6 +2698,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/Cargo.toml b/Cargo.toml index 562c76c..aab587b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,3 +71,4 @@ ratatui = "0.27.0" tokio-tungstenite = "0.23.1" log = "0.4.22" env_logger = "0.11.3" +toml_edit = "0.22" diff --git a/src/api/app/actions/update/mod.rs b/src/api/app/actions/update/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/api/models/addon/addon_type.rs b/src/api/models/addon/addon_type.rs index c7cc735..c602704 100644 --- a/src/api/models/addon/addon_type.rs +++ b/src/api/models/addon/addon_type.rs @@ -57,3 +57,18 @@ pub enum AddonType { filename: String, }, } + +impl ToString for AddonType { + fn to_string(&self) -> String { + match self { + AddonType::Url { url } => format!("Url [{url}]"), + AddonType::Modrinth { id, version } => format!("Modrinth/{id} [{version}]"), + AddonType::Curseforge { id, version } => format!("Curseforge/{id} [{version}]"), + AddonType::Spigot { id, version } => format!("Spigot/{id} [{version}]"), + AddonType::Hangar { id, version } => format!("Hangar/{id} [{version}]"), + AddonType::GithubRelease { repo, version, filename } => format!("Github/{repo} [{version}; {filename}]"), + AddonType::Jenkins { url, job, build, artifact } => format!("Jenkins/{job} [{build}; {artifact}]"), + AddonType::MavenArtifact { url, group, artifact, version, filename } => format!("Maven/{group}.{artifact} [{version}; {filename}]"), + } + } +} diff --git a/src/api/models/modpack_source.rs b/src/api/models/modpack_source.rs index 532e3c1..3820eca 100644 --- a/src/api/models/modpack_source.rs +++ b/src/api/models/modpack_source.rs @@ -11,6 +11,8 @@ use crate::api::utils::accessor::Accessor; pub enum ModpackSource { Local { path: String, + #[serde(default)] + can_update: bool, }, Remote { @@ -25,7 +27,7 @@ impl FromStr for ModpackSource { if s.starts_with("http") { Ok(ModpackSource::Remote { url: s.into() }) } else { - Ok(ModpackSource::Local { path: s.into() }) + Ok(ModpackSource::Local { path: s.into(), can_update: false }) } } } @@ -33,7 +35,7 @@ impl FromStr for ModpackSource { impl ModpackSource { pub fn accessor(&self, base: &Path) -> Result { let str = match self { - Self::Local { path } => &base.join(path) + Self::Local { path, .. } => &base.join(path) .canonicalize() .with_context(|| format!("Resolving path: {:?}", base.join(path)))? .to_string_lossy() diff --git a/src/api/models/mrpack/mrpack_file.rs b/src/api/models/mrpack/mrpack_file.rs index d19ae00..e891b7f 100644 --- a/src/api/models/mrpack/mrpack_file.rs +++ b/src/api/models/mrpack/mrpack_file.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use serde::{Deserialize, Serialize}; -use crate::api::{models::Environment, utils::hashing::HashFormat}; +use crate::api::utils::hashing::HashFormat; #[derive(Debug, Deserialize, Serialize, Clone)] #[serde(rename_all = "camelCase")] diff --git a/src/api/models/source.rs b/src/api/models/source.rs index 1d86585..4d1136a 100644 --- a/src/api/models/source.rs +++ b/src/api/models/source.rs @@ -26,7 +26,7 @@ pub enum SourceType { Modpack { #[serde(flatten)] - modpack: ModpackSource, + modpack_source: ModpackSource, modpack_type: ModpackType, }, } @@ -39,8 +39,8 @@ impl FromStr for SourceType { Ok(match ty { "file" | "f" => SourceType::File { path: val.into() }, - "packwiz" | "pw" => SourceType::Modpack { modpack: ModpackSource::from_str(val)?, modpack_type: ModpackType::Packwiz }, - "mrpack" => SourceType::Modpack { modpack: ModpackSource::from_str(val)?, modpack_type: ModpackType::MRPack }, + "packwiz" | "pw" => SourceType::Modpack { modpack_source: ModpackSource::from_str(val)?, modpack_type: ModpackType::Packwiz }, + "mrpack" => SourceType::Modpack { modpack_source: ModpackSource::from_str(val)?, modpack_type: ModpackType::MRPack }, _ => bail!("Unknown source identifier type: {ty}"), }) } @@ -61,7 +61,7 @@ impl Source { .with_context(|| format!("Resolving path: {:?}", relative_to.join(path)))?)), SourceType::Folder { path } => Ok(Accessor::Local(relative_to.join(path).canonicalize() .with_context(|| format!("Resolving path: {:?}", relative_to.join(path)))?)), - SourceType::Modpack { modpack, .. } => modpack.accessor(relative_to) + SourceType::Modpack { modpack_source: modpack, .. } => modpack.accessor(relative_to) .with_context(|| "Getting Modpack Accessor"), } } @@ -84,7 +84,7 @@ impl Source { SourceType::Folder { .. } => Ok(vec![]), - SourceType::Modpack { modpack, modpack_type } => { + SourceType::Modpack { modpack_source: modpack, modpack_type } => { let accessor = modpack.accessor(relative_to)?; match modpack_type { ModpackType::MRPack => resolve_mrpack_addons(app, accessor).await, diff --git a/src/api/utils/mod.rs b/src/api/utils/mod.rs index fda8ff7..b51ec05 100644 --- a/src/api/utils/mod.rs +++ b/src/api/utils/mod.rs @@ -10,3 +10,4 @@ pub mod zip; pub mod toml; pub mod fs; pub mod logger; +pub mod update_writer; diff --git a/src/api/utils/update_writer.rs b/src/api/utils/update_writer.rs new file mode 100644 index 0000000..1b150e7 --- /dev/null +++ b/src/api/utils/update_writer.rs @@ -0,0 +1,45 @@ +use std::path::{Path, PathBuf}; + +use anyhow::{anyhow, Result}; +use toml_edit::DocumentMut; +use zip::ZipArchive; + +use crate::api::{app::App, models::{mrpack::MRPackIndex, packwiz::{PackwizPack, PackwizPackIndex}, ModpackSource, ModpackType, Source, SourceType}}; + +use super::toml::read_toml; + +/// An `Accessor` allows for filesystem, remote or zip file access. +pub enum UpdateWriter { + File(PathBuf, DocumentMut), + MRPack(PathBuf, ZipArchive, MRPackIndex), + Packwiz(PathBuf, PackwizPack, PackwizPackIndex), +} + +impl UpdateWriter { + pub fn from(source: &Source, relative_to: &Path) -> Result { + todo!(); + + /* match &source.source_type { + SourceType::File { path } => Ok(Self::File(path, read_toml(relative_to.join(path).to_path_buf())?)), + SourceType::Folder { path } => unimplemented!(), + SourceType::Modpack { + modpack_source: ModpackSource::Local { path, can_update: true }, + modpack_type + } => match modpack_type { + ModpackType::MRPack => Ok(Self::MRPack( + relative_to.join(path).to_path_buf(), + ZipArchive::new(std::fs::File::open(relative_to.join(path))?)?, + todo!() + )), + ModpackType::Packwiz => Ok(Self::Packwiz( + relative_to.join(path), + todo!(), + todo!(), + )), + ModpackType::Unsup => unimplemented!(), + }, + _ => Err(anyhow!("Can't make an UpdateWriter")), + } */ + } + +} diff --git a/src/commands/export/mod.rs b/src/commands/export/mod.rs new file mode 100644 index 0000000..3ba221a --- /dev/null +++ b/src/commands/export/mod.rs @@ -0,0 +1,21 @@ +use std::sync::Arc; + +use anyhow::Result; + +use crate::api::app::App; + +pub mod mrpack; +pub mod packwiz; + +#[derive(clap::Subcommand)] +pub enum Commands { + MRPack(mrpack::Args), + Packwiz(packwiz::Args), +} + +pub async fn run(app: Arc, args: Commands) -> Result<()> { + match args { + Commands::MRPack(args) => mrpack::run(app, args).await, + Commands::Packwiz(args) => packwiz::run(app, args).await, + } +} diff --git a/src/commands/export/mrpack.rs b/src/commands/export/mrpack.rs new file mode 100644 index 0000000..5985024 --- /dev/null +++ b/src/commands/export/mrpack.rs @@ -0,0 +1,16 @@ +use std::sync::Arc; + +use anyhow::Result; + +use crate::api::app::App; + +#[derive(clap::Args)] +pub struct Args { + filename: Option, +} + +pub async fn run(app: Arc, args: Args) -> Result<()> { + + + Ok(()) +} diff --git a/src/commands/export/packwiz.rs b/src/commands/export/packwiz.rs new file mode 100644 index 0000000..8856f5c --- /dev/null +++ b/src/commands/export/packwiz.rs @@ -0,0 +1,16 @@ +use std::sync::Arc; + +use anyhow::Result; + +use crate::api::app::App; + +#[derive(clap::Args)] +pub struct Args { + +} + +pub async fn run(app: Arc, args: Args) -> Result<()> { + + + Ok(()) +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 9428467..d495b74 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -7,3 +7,4 @@ pub mod migrate; pub mod websocket; pub mod run; pub mod update; +pub mod export; diff --git a/src/commands/sources/list.rs b/src/commands/sources/list.rs index e20a3be..394c729 100644 --- a/src/commands/sources/list.rs +++ b/src/commands/sources/list.rs @@ -3,12 +3,28 @@ use std::sync::Arc; use anyhow::Result; use console::style; -use crate::api::{app::App, models::{ModpackSource, SourceType}}; +use crate::api::{app::App, models::SourceType}; #[derive(clap::Args)] -pub struct Args {} +pub struct Args { + #[arg(short = 'a', long)] + pub with_addons: bool, +} pub async fn run(app: Arc, args: Args) -> Result<()> { + if let Some((base, network)) = &*app.network.read().await { + println!("{} {}", style("Network:").bold(), network.name); + println!(" -> {:?}", style(base.parent().unwrap()).dim()); + println!(); + }; + + if let Some((base, server)) = &*app.server.read().await { + println!("{} {}", style("Server:").bold(), server.name); + println!(" -> {:?}", style(base.parent().unwrap()).dim()); + }; + + println!(); + let sources = app.collect_sources().await?; for (idx, (base, source)) in sources.iter().enumerate() { @@ -24,7 +40,13 @@ pub async fn run(app: Arc, args: Args) -> Result<()> { } ); - println!(" -> {}", style(source.accessor(base)?.to_string()).dim()) + println!(" -> {}", style(source.accessor(base)?.to_string()).dim()); + + if args.with_addons { + for (idx, addon) in source.resolve_addons(&app, base).await?.iter().enumerate() { + println!(" {}. {} {}", style(idx).bold(), addon.addon_type.to_string(), style(addon.target.as_str()).dim()); + } + } } Ok(()) diff --git a/src/commands/update.rs b/src/commands/update.rs index 6bab344..79ff8cc 100644 --- a/src/commands/update.rs +++ b/src/commands/update.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use anyhow::Result; -use crate::api::{app::App, tools::git::version_check}; +use crate::api::{app::App, tools::git}; #[derive(clap::Args)] pub struct Args { @@ -10,7 +10,7 @@ pub struct Args { } pub async fn run(app: Arc, args: Args) -> Result<()> { - println!("{:#?}", version_check()); + println!("{:#?}", git::version_check()); Ok(()) } diff --git a/src/main.rs b/src/main.rs index 72fdc33..99fc386 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ -use std::sync::Arc; +use std::{path::Path, sync::Arc}; use anyhow::Result; -use api::{app::App, models::{server::{Server, SERVER_TOML}, Source, SourceType}, utils::logger::init_logger}; +use api::{app::App, models::{packwiz::{PackwizPack, PACK_TOML}, server::{Server, SERVER_TOML}, ModpackSource, ModpackType, Source, SourceType}, utils::{logger::init_logger, toml::try_find_toml_upwards}}; use clap::Parser; mod api; @@ -32,6 +32,8 @@ enum Commands { Java(commands::java::Commands), #[command(alias = "md", subcommand)] Markdown(commands::markdown::Commands), + #[command(subcommand)] + Export(commands::export::Commands), Migrate(commands::migrate::Args), #[command(alias = "ws")] WebSocket(commands::websocket::Args), @@ -61,6 +63,23 @@ async fn main() -> Result<()> { } } + if let Ok(Some((base, _))) = try_find_toml_upwards::(PACK_TOML) { + let mut wg = app.server.write().await; + // if no server.toml etc and is inside a packwiz folder + if wg.is_none() { + let (_, server) = wg.get_or_insert_with(|| ( + base.into(), + Server::default() + )); + server.sources.push(Source { + source_type: SourceType::Modpack { + modpack_source: ModpackSource::Local { path: String::from(PACK_TOML), can_update: false }, + modpack_type: ModpackType::Packwiz, + } + }); + } + } + match args.command { Commands::Init(args) => commands::init::run(app, args).await, Commands::Sources(args) => commands::sources::run(app, args).await, @@ -71,5 +90,6 @@ async fn main() -> Result<()> { Commands::Migrate(args) => commands::migrate::run(app, args).await, Commands::WebSocket(args) => commands::websocket::run(app, args).await, Commands::Update(args) => commands::update::run(app, args).await, + Commands::Export(args) => commands::export::run(app, args).await, } }