use crate::index::{self, Index};
use crate::instance::Instance;
use crate::local_storage::{self, PersistedEntity};
use crate::server::backup::BACKUP_FOLDER;
use color_eyre::owo_colors::OwoColorize;
use semver::Version;
use serde::{Deserialize, Serialize};
use std::fs::{self, File};
use std::io::{self, Write};
use std::path::PathBuf;
use zip::write::SimpleFileOptions;
use zip::ZipWriter;
mod settings;
pub use settings::*;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Pack {
pub name: String,
pub version: Version,
pub authors: Vec<String>,
pub instance: Instance,
pub settings: Settings,
}
impl PersistedEntity for Pack {
const FILE_PATH: &'static str = "pack.yml";
}
impl Pack {
pub const MOD_DIR: &'static str = "mods";
pub const RESOURCEPACK_DIR: &'static str = "resourcepacks";
pub const SHADERPACK_DIR: &'static str = "shaders";
pub const DATAPACK_DIR: &'static str = "datapacks";
pub const CONFIG_DIR: &'static str = "config";
pub fn setup_directories() -> io::Result<()> {
for subdir in [
Self::MOD_DIR,
Self::RESOURCEPACK_DIR,
Self::SHADERPACK_DIR,
Self::DATAPACK_DIR,
Self::CONFIG_DIR,
] {
fs::create_dir_all(subdir)?;
let _ = File::create(format!("{subdir}/.gitkeep"))?;
}
fs::create_dir_all(BACKUP_FOLDER)?;
fs::write(format!("{BACKUP_FOLDER}/.gitignore"), "*\n")?;
Ok(())
}
pub fn export(&self) -> local_storage::Result<()> {
let files: Vec<index::file::File> = crate::component::Component::load_all()?
.into_iter()
.map(Into::into)
.collect();
let index = Index::from_pack_and_files(self, &files);
let json = serde_json::to_string_pretty(&index)?;
let path = format!("{}.mrpack", self.name);
tracing::info!(message = "Writing index", target = ?path.yellow().bold());
let file = File::create(&path).map_err(|source| local_storage::Error::Io {
source,
faulty_path: Some(PathBuf::from(path.clone())),
})?;
let mut mrpack = ZipWriter::new(file);
let options =
SimpleFileOptions::default().compression_method(zip::CompressionMethod::Deflated);
mrpack.start_file("modrinth.index.json", options)?;
mrpack
.write_all(json.as_bytes())
.map_err(|source| local_storage::Error::Io {
source,
faulty_path: Some(PathBuf::from(path)),
})?;
mrpack.finish()?;
Ok(())
}
}