Fix modpacks, compile to zip

This commit is contained in:
Danielle Hutzley 2021-12-14 17:23:33 -08:00
parent 3b85095f28
commit 5dabfb4ea0
6 changed files with 36 additions and 19 deletions

10
Cargo.lock generated
View File

@ -1181,6 +1181,7 @@ dependencies = [
"tokio",
"uuid",
"zip",
"zip-extensions",
]
[[package]]
@ -1527,3 +1528,12 @@ dependencies = [
"thiserror",
"time",
]
[[package]]
name = "zip-extensions"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a64c3c977bc3434ce2d4bcea8ad3c644672de0f2c402b72b9171ca80a8885d14"
dependencies = [
"zip",
]

View File

@ -20,6 +20,7 @@ chrono = { version = "0.4", features = ["serde"] }
uuid = { version = "0.8", features = ["serde", "v4"] }
bytes = "1"
zip = "0.5"
zip-extensions = "0.6"
sha1 = { version = "0.6.0", features = ["std"]}
path-clean = "0.1.0"
fs_extra = "1.2.0"

View File

@ -100,7 +100,7 @@ impl<'a> TryFrom<&'a pack::Modpack> for Manifest<'a> {
pub struct ManifestFile<'a> {
#[serde(borrow)]
pub path: &'a Path,
pub hashes: ManifestHashes<'a>,
pub hashes: Option<ManifestHashes<'a>>,
#[serde(default)]
pub env: ManifestEnvs,
#[serde(borrow)]
@ -113,7 +113,7 @@ impl TryFrom<ManifestFile<'_>> for pack::ModpackFile {
fn try_from(file: ManifestFile<'_>) -> Result<Self, Self::Error> {
Ok(Self {
path: PathBuf::from(file.path),
hashes: pack::ModpackFileHashes::from(file.hashes),
hashes: file.hashes.map(pack::ModpackFileHashes::from),
env: pack::ModpackEnv::try_from(file.env)?,
downloads: file.downloads.into_iter().map(ToOwned::to_owned).collect(),
})
@ -124,7 +124,7 @@ impl<'a> From<&'a pack::ModpackFile> for ManifestFile<'a> {
fn from(file: &'a pack::ModpackFile) -> Self {
Self {
path: file.path.as_path(),
hashes: (&file.hashes).into(),
hashes: file.hashes.as_ref().map(ManifestHashes::from),
env: file.env.into(),
downloads: file
.downloads

View File

@ -7,6 +7,7 @@ use std::{convert::TryFrom, env, io, path::Path};
use tokio::{fs, try_join};
use uuid::Uuid;
use zip::ZipArchive;
use zip_extensions::ZipWriterExtensions;
use self::{
manifest::Manifest,
@ -18,6 +19,7 @@ pub mod modrinth_api;
pub mod pack;
pub const COMPILED_PATH: &'static str = "compiled/";
pub const COMPILED_ZIP: &'static str = "compiled.mrpack";
pub const MANIFEST_PATH: &'static str = "modrinth.index.json";
pub const OVERRIDES_PATH: &'static str = "overrides/";
pub const PACK_JSON5_PATH: &'static str = "modpack.json5";
@ -141,7 +143,8 @@ pub fn to_pack_json5(pack: &Modpack) -> ModpackResult<String> {
lazy_static::lazy_static! {
static ref PACK_GITIGNORE: String = format!(r#"
{0}
"#, COMPILED_PATH);
{1}
"#, COMPILED_PATH, COMPILED_ZIP);
}
pub async fn create_modpack(
@ -166,6 +169,7 @@ pub async fn compile_modpack(dir: &Path) -> ModpackResult<()> {
let result_dir = dir.join(COMPILED_PATH);
let pack: Modpack = json5::from_str(&fs::read_to_string(dir.join(PACK_JSON5_PATH)).await?)?;
fs::create_dir(&result_dir).await;
if dir.join(OVERRIDES_PATH).exists() {
fs_extra::dir::copy(
dir.join(OVERRIDES_PATH),
@ -174,15 +178,15 @@ pub async fn compile_modpack(dir: &Path) -> ModpackResult<()> {
)?;
}
let manifest = Manifest::try_from(&pack)?;
fs::write(
result_dir.join(MANIFEST_PATH),
serde_json::to_string(&manifest)?,
)
.await?;
try_join!(
fs::create_dir(&result_dir),
fs::write(
result_dir.join(MANIFEST_PATH),
serde_json::to_string(&manifest)?
),
)?;
let result_zip = fs::File::create(dir.join(COMPILED_ZIP)).await?.into_std().await;
let mut zip = zip::ZipWriter::new(&result_zip);
zip.create_from_directory(&result_dir)?;
Ok(())
}

View File

@ -60,7 +60,7 @@ struct ModrinthV1ProjectVersionFile<'a> {
impl From<ModrinthV1ProjectVersionFile<'_>> for ModpackFile {
fn from(file: ModrinthV1ProjectVersionFile<'_>) -> Self {
Self {
hashes: ModpackFileHashes::from(file.hashes),
hashes: Some(ModpackFileHashes::from(file.hashes)),
downloads: {
let mut downloads: HashSet<String> = HashSet::new();
downloads.insert(String::from(file.url));

View File

@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
use std::{
collections::HashSet,
hash::Hash,
path::{Path, PathBuf},
path::{Path, PathBuf}, iter::FromIterator,
};
use tokio::fs;
@ -115,15 +115,15 @@ impl Modpack {
.collect::<Vec<String>>(),
);
if (whitelisted_domains.iter().find(String::from(source.host_str().unwrap())).is_none()) {
if (whitelisted_domains.iter().find(|it| it == &source.host_str().unwrap()).is_none()) {
return Err(ModpackError::SourceWhitelistError(String::from(source.host_str().unwrap())));
}
let file = ModpackFile {
path: dest,
path: PathBuf::from(dest),
hashes,
env: env.unwrap_or(ModpackEnv::Both),
downloads: HashSet::from([String::from(source)])
downloads: HashSet::from_iter([String::from(source)].into_iter().cloned())
};
self.files.insert(file);
@ -148,7 +148,9 @@ pub struct ModpackFile {
impl Hash for ModpackFile {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.hashes.sha1.hash(state);
if let Some(ref hashes) = self.hashes {
hashes.sha1.hash(state);
}
self.path.hash(state);
}
}
@ -171,7 +173,7 @@ impl ModpackFile {
.map(|it| it.as_str())
.collect::<Vec<&str>>()
.as_slice(),
Some(&self.hashes.sha1),
self.hashes.as_ref().map(|it| it.sha1.as_str()),
)
.await?;
fs::create_dir_all(output.parent().unwrap()).await?;