diff --git a/.gitignore b/.gitignore index 7a9733e..0a9944c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ Cargo.lock .idea jtd-codegen +minecraft-data diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index acac9a5..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "minecraft-data"] - path = minecraft-data - url = git@github.com:PrismarineJS/minecraft-data.git diff --git a/Cargo.toml b/Cargo.toml index c246a4a..9c9edfa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minecraft-data-rs" -version = "0.8.0" +version = "0.8.1" authors = ["trivernis "] edition = "2021" readme = "README.md" @@ -8,7 +8,9 @@ license = "MIT" description = "A wrapper for minecraft-data" repository = "https://github.com/Trivernis/minecraft-data-rs" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[package.metadata] +minecraft_data_repo = "https://github.com/PrismarineJS/minecraft-data.git" +minecraft_data_commit = "46b78398b6f351958e02fbd266424f0ee0ab138b" [dependencies] thiserror = "1.0.38" @@ -19,7 +21,14 @@ include_dir = { version = "0.7.3", optional = true } itertools = { version = "0.10.5", optional = true } lazy_static = { version = "1.4.0", optional = true } +[build-dependencies] +git2 = {version = "0.18.2", optional = true} +dirs = {version = "5.0.1", optional = true} +cargo_toml = {version = "0.19.1", optional = true} +serde = { version = "1.0.151", features = ["derive"], optional = true } + [features] default = ["include-data", "api"] -include-data = ["include_dir", "itertools", "lazy_static"] +include-data = ["include_dir", "itertools", "lazy_static", "git2", "dirs", "cargo_toml", "serde/derive"] api = ["include-data"] + diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..8861d15 --- /dev/null +++ b/build.rs @@ -0,0 +1,73 @@ +#[cfg(not(feature = "include-data"))] +fn main() {} + +#[cfg(feature = "include-data")] +fn main() { + data_repo::init_repo(); +} + +#[cfg(feature = "include-data")] +mod data_repo { + use std::{env, fs, path::PathBuf}; + + use cargo_toml::Manifest; + use git2::{Oid, Repository}; + use serde::Deserialize; + + #[derive(Clone, Debug, Deserialize)] + struct Metadata { + minecraft_data_repo: String, + minecraft_data_commit: String, + } + + pub fn init_repo() { + println!("cargo:rerun-if-env-changed=MINECRAFT_DATA_REPO_PATH"); + println!("cargo:rerun-if-changed=Cargo.toml"); + + let manifest = Manifest::::from_path_with_metadata(PathBuf::from("Cargo.toml")) + .expect("Failed to read manifest (Cargo.toml)"); + let metadata = manifest + .package + .expect("missing package info in Cargo.toml") + .metadata + .expect("missing package.metadata in Cargo.toml"); + + let repo_path = env::var("MINECRAFT_DATA_REPO_PATH") + .map(PathBuf::from) + .ok() + .or_else(|| dirs::cache_dir().map(|p| p.join("minecraft-data"))) + .unwrap_or_else(|| PathBuf::from("minecraft-data")); + + println!( + "cargo:rustc-env=MINECRAFT_DATA_PATH_INTERNAL={}", + repo_path.to_string_lossy() + ); + + let version_oid = Oid::from_str(&metadata.minecraft_data_commit).expect("invalid oid"); + + let repo = if repo_path.exists() { + let repo = Repository::open(&repo_path).expect("failed to open git repo"); + let head_oid = repo + .head() + .expect("no head found in repo") + .peel_to_commit() + .expect("head is not a commit") + .as_object() + .id(); + if head_oid != version_oid { + fs::remove_dir_all(&repo_path).expect("could not delete repository"); + Repository::clone(&metadata.minecraft_data_repo, repo_path) + .expect("failed to clone repo") + } else { + repo + } + } else { + Repository::clone(&metadata.minecraft_data_repo, repo_path) + .expect("failed to clone repo") + }; + + repo.set_head_detached(version_oid) + .expect("failed set head"); + repo.checkout_head(None).expect("failed checkout index") + } +} diff --git a/minecraft-data b/minecraft-data deleted file mode 160000 index 46b7839..0000000 --- a/minecraft-data +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 46b78398b6f351958e02fbd266424f0ee0ab138b diff --git a/src/data/mod.rs b/src/data/mod.rs index fb44ee6..a49c7f8 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -6,7 +6,7 @@ use crate::models::version::Version; use crate::{DataError, DataResult}; use include_dir::Dir; -pub static MINECRAFT_DATA: Dir = include_dir::include_dir!("minecraft-data/data"); +pub static MINECRAFT_DATA: Dir = include_dir::include_dir!("$MINECRAFT_DATA_PATH_INTERNAL/data"); pub static BIOMES_FILE: &str = "biomes"; pub static BLOCK_LOOT_FILE: &str = "blockLoot"; @@ -69,11 +69,7 @@ pub fn get_path(version: &Version, filename: &str) -> DataResult { .pc .get(&version.minecraft_version) // fallback to major version - .or_else(|| - PATHS - .pc - .get(&version.major_version) - ) + .or_else(|| PATHS.pc.get(&version.major_version)) .ok_or_else(|| DataError::NotFoundError(version.minecraft_version.clone()))? .get(filename) .cloned()