started v2
This commit is contained in:
Generated
+8
@@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
Generated
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/v2.iml" filepath="$PROJECT_DIR$/.idea/v2.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
Generated
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="EMPTY_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+255
@@ -19,6 +19,15 @@ dependencies = [
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.6.0"
|
||||
@@ -288,12 +297,24 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "lzma-sys"
|
||||
version = "0.1.20"
|
||||
@@ -305,6 +326,21 @@ dependencies = [
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||
dependencies = [
|
||||
"regex-automata 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.1"
|
||||
@@ -314,6 +350,16 @@ dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
||||
dependencies = [
|
||||
"overload",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.16.0"
|
||||
@@ -324,12 +370,24 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "option-ext"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||
|
||||
[[package]]
|
||||
name = "pack_sync"
|
||||
version = "0.1.0"
|
||||
@@ -338,6 +396,9 @@ dependencies = [
|
||||
"num_cpus",
|
||||
"serde",
|
||||
"serde_yaml",
|
||||
"toml",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"walkdir",
|
||||
"zip",
|
||||
"zip_archive",
|
||||
@@ -366,6 +427,12 @@ dependencies = [
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.27"
|
||||
@@ -425,6 +492,50 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata 0.4.6",
|
||||
"regex-syntax 0.8.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||
dependencies = [
|
||||
"regex-syntax 0.6.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax 0.8.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.15"
|
||||
@@ -460,6 +571,15 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.25"
|
||||
@@ -495,6 +615,21 @@ dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
|
||||
|
||||
[[package]]
|
||||
name = "subprocess"
|
||||
version = "0.2.9"
|
||||
@@ -553,6 +688,16 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.27"
|
||||
@@ -570,6 +715,101 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af06656561d28735e9c1cd63dfd57132c8155426aa6af24f36a00a351f88c48e"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18769cd1cec395d70860ceb4d932812a0b4d06b1a4bb336745a4d21b9496e992"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"nu-ansi-term",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.16.0"
|
||||
@@ -588,6 +828,12 @@ version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
@@ -707,6 +953,15 @@ version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xattr"
|
||||
version = "1.0.1"
|
||||
|
||||
+11
@@ -3,6 +3,14 @@ name = "pack_sync"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[[bin]]
|
||||
name = "pack_sync_cli"
|
||||
path = "src/cli.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "pack_sync_server"
|
||||
path = "src/server.rs"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
@@ -10,6 +18,9 @@ dirs = "5.0.1"
|
||||
num_cpus = "1.16.0"
|
||||
serde = { version = "1.0.188", features = ["derive"] }
|
||||
serde_yaml = "0.9.25"
|
||||
toml = "0.8.11"
|
||||
tracing = "0.1.40"
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||
walkdir = "2.3.3"
|
||||
zip = "0.6.6"
|
||||
zip_archive = "1.2.2"
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
# pack deployer
|
||||
|
||||
- a simple utility to automatically archive and move your resourcepacks into a folder.
|
||||
# Pack Sync
|
||||
### A simple utility for resoucepack developers who like to stay organised.
|
||||
|
||||
## use cases
|
||||
### Use Case:
|
||||
- You have a folder full of all your projects working on minecraft resource packs
|
||||
- You want to be able to automatically archive these files and move them to your resourcepacks folders for testing
|
||||
- You make modular packs with different themes that need to be kept organised
|
||||
|
||||
this may be useful if you regularly create resourcepacks and want to organise your projects in different folders.
|
||||
the utility recursively scans directories in the project folder and organises packs into a folder
|
||||
### How pack sync can help
|
||||
The pack sync client is a command line utility that allows you to automatically
|
||||
archive and load all of your resourcepacks into correct folders.
|
||||
|
||||
|
||||
### Usage:
|
||||
|
||||
- start by creating a config.toml file
|
||||
```toml
|
||||
repository = "."
|
||||
resourcepacks = "_resourcepacks"
|
||||
ignore_folder_prefix = "_"
|
||||
|
||||
[versions.1-8-9]
|
||||
resourcepacks = "mc_instances/1.8.9/resourcepacks"
|
||||
|
||||
[versions.1-20-1]
|
||||
resourcepacks = "mc_instances/1.20.4/resourcepacks"
|
||||
```
|
||||
+354
@@ -0,0 +1,354 @@
|
||||
|
||||
|
||||
use num_cpus;
|
||||
use std::{
|
||||
fs::{self, OpenOptions},
|
||||
io::{self, Error, ErrorKind, Write},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::slice::SliceIndex;
|
||||
use tracing::{event, info, span, Level, warn, error};
|
||||
use tracing_subscriber::{
|
||||
filter::{EnvFilter, LevelFilter},
|
||||
fmt::{self, fmt},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use toml;
|
||||
|
||||
use walkdir::WalkDir;
|
||||
use zip::write::{FileOptions, ZipWriter};
|
||||
use zip::CompressionMethod;
|
||||
use zip_archive::{get_dir_list, Archiver};
|
||||
|
||||
|
||||
fn main() {
|
||||
tracing_subscriber::registry()
|
||||
.with(
|
||||
fmt::layer()
|
||||
.pretty()
|
||||
.with_target(false)
|
||||
.with_thread_ids(false)
|
||||
.with_thread_names(false)
|
||||
.with_file(false)
|
||||
.with_line_number(false),
|
||||
)
|
||||
.with(
|
||||
EnvFilter::builder()
|
||||
.with_default_directive(LevelFilter::DEBUG.into())
|
||||
.from_env_lossy(),
|
||||
)
|
||||
.init();
|
||||
|
||||
let config = Config::load().expect("failed to load config");
|
||||
let pack_repo = PathBuf::from(&config.repository);
|
||||
match clear_resourcepacks(&config) {
|
||||
Ok(_) => {},
|
||||
Err(e) => return,
|
||||
};
|
||||
search_dir(&pack_repo, &config).unwrap();
|
||||
}
|
||||
|
||||
fn clear_resourcepacks(conf: &Config) -> io::Result<()> {
|
||||
let span = span!(Level::INFO, "clear_packs");
|
||||
let _guard = span.enter();
|
||||
|
||||
info!("Clearing existing resourcepacks folder");
|
||||
match fs::remove_dir_all(&conf.resourcepacks) {
|
||||
Ok(_) => {}
|
||||
Err(e) => warn!("No existing packs folder detected. Creating new folder."),
|
||||
};
|
||||
match fs::create_dir(&conf.resourcepacks) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
error!("{}", e);
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
info!("Successfully reset resourcepacks folder");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn search_dir(path: &PathBuf, config: &Config) -> io::Result<()> {
|
||||
let span = span!(Level::INFO, "Searching for packs");
|
||||
let _guard = span.enter();
|
||||
|
||||
// info!("Searching for packs in {}", path.display());
|
||||
// check if file is a valid pack
|
||||
|
||||
if path.clone().join("pack.toml").exists() {
|
||||
println!("Found pack {}", path.display());
|
||||
Pack::load(&path).unwrap().archive(&path, config).unwrap();
|
||||
return Ok(());
|
||||
} else {
|
||||
println!("1c| {}", path.display());
|
||||
|
||||
for entry in WalkDir::new(path.clone())
|
||||
.into_iter()
|
||||
.filter_map(|e| e.ok())
|
||||
.filter(|e| e.file_type().is_dir() && e.file_name() != path)
|
||||
.filter(|e| !e.file_name().to_str().unwrap().to_string().contains("/_"))
|
||||
{
|
||||
println!("PATH {}", entry.path().join(entry.file_name()).to_str().unwrap());
|
||||
// search_dir(&entry.path().join(entry.file_name()).to_path_buf(), config).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
struct Pack {
|
||||
release: bool,
|
||||
name: String,
|
||||
version: String,
|
||||
description: String,
|
||||
packs: HashMap<String, PackComponent>,
|
||||
}
|
||||
|
||||
impl Pack {
|
||||
fn load(path: &PathBuf) -> io::Result<Pack> {
|
||||
let span = span!(Level::INFO, "Loading Pack Config file");
|
||||
let _guard = span.enter();
|
||||
|
||||
let contents = fs::read_to_string(path.join("pack.toml"))?;
|
||||
let pack = toml::from_str::<Pack>(&contents).map_err(|e| Error::new(ErrorKind::Other, e))?;
|
||||
|
||||
Ok(pack)
|
||||
}
|
||||
|
||||
fn archive(&self, path: &PathBuf, config: &Config) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let span = span!(Level::INFO, "Archiving Pack");
|
||||
let _guard = span.enter();
|
||||
|
||||
let resourcepacks = if config.versions.contains_key(&self.version) {
|
||||
match config.versions.get(&self.version).unwrap().resourcepacks.clone() {
|
||||
Some(folder) => folder,
|
||||
None => config.resourcepacks.clone()
|
||||
}
|
||||
} else {
|
||||
config.resourcepacks.clone()
|
||||
};
|
||||
let zip_file = fs::File::create(format!("{}/{}.zip", resourcepacks, self.name))?;
|
||||
let mut zip_writer = ZipWriter::new(zip_file);
|
||||
|
||||
let options = FileOptions::default()
|
||||
.compression_method(CompressionMethod::Deflated)
|
||||
.unix_permissions(0o755);
|
||||
|
||||
for entry in WalkDir::new(path.clone())
|
||||
.into_iter()
|
||||
.filter_map(|e| e.ok())
|
||||
{
|
||||
let file_path = entry.path();
|
||||
if file_path.is_file() {
|
||||
let mut file = fs::File::open(file_path)?;
|
||||
let relpath = file_path.strip_prefix(path.clone())?;
|
||||
let mut zip_path = PathBuf::new();
|
||||
zip_path.push(relpath);
|
||||
|
||||
zip_writer.start_file(zip_path.to_string_lossy().into_owned(), options)?;
|
||||
std::io::copy(&mut file, &mut zip_writer)?;
|
||||
}
|
||||
}
|
||||
zip_writer.finish()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
struct PackComponent {
|
||||
prefix: String,
|
||||
release: bool,
|
||||
}
|
||||
|
||||
//
|
||||
// fn scan_directory(path: PathBuf, config: &Config) -> io::Result<()> {
|
||||
// let mut pack_mcmeta = path.clone();
|
||||
// pack_mcmeta.push("pack.mcmeta");
|
||||
// if pack_mcmeta.exists() {
|
||||
// // if pack metadata exists, put the pack into a zip folder.
|
||||
// get_archive(path, config).map_err(|_| Error::new(ErrorKind::Other, "failed to archive zip"))?;
|
||||
// return Ok(());
|
||||
// } else {
|
||||
// // recursively scans subdirectories for other packs
|
||||
// for entry in fs::read_dir(path)? {
|
||||
// let entry = entry?;
|
||||
//
|
||||
// if entry
|
||||
// .path()
|
||||
// .file_name()
|
||||
// .unwrap()
|
||||
// .to_os_string()
|
||||
// .into_string()
|
||||
// .map_err(|_| Error::new(ErrorKind::Other, "failed to convert os_str to string"))?
|
||||
// .starts_with("_")
|
||||
// {
|
||||
// println!("found _");
|
||||
// continue;
|
||||
// }
|
||||
// if let Some(zip_str) = entry.path().extension() {
|
||||
// if zip_str == "zip" {
|
||||
// fs::copy(
|
||||
// entry.path(),
|
||||
// format!(
|
||||
// "{}/{}",
|
||||
// config.resourcepacks,
|
||||
// entry
|
||||
// .path()
|
||||
// .file_name()
|
||||
// .unwrap()
|
||||
// .to_os_string()
|
||||
// .into_string()
|
||||
// .map_err(|_| Error::new(
|
||||
// ErrorKind::Other,
|
||||
// "failed to convert os_str to string"
|
||||
// ))?
|
||||
// ),
|
||||
// )?;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if let Ok(file_type) = entry.file_type() {
|
||||
// if file_type.is_dir() {
|
||||
// scan_directory(entry.path(), &config)?;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Ok(())
|
||||
// }
|
||||
//
|
||||
// fn get_archive(path: PathBuf, config: &Config) -> Result<(), Box<dyn std::error::Error>> {
|
||||
// println!("CREATING ARCHIVE: {}", &path.display());
|
||||
// if let Some(f) = path.file_stem() {
|
||||
// let mut filename = f
|
||||
// .to_os_string()
|
||||
// .into_string()
|
||||
// .map_err(|_| Error::new(ErrorKind::Other, "failed to convert os_str to string"))?;
|
||||
// filename.push_str("_0");
|
||||
// loop {
|
||||
// if !Path::new(&format!("{}/{}.zip", config.resourcepacks, filename.to_string())).exists() {
|
||||
// // checks if zip file already exists
|
||||
// let zip_file = fs::File::create(format!("{}/{}.zip", config.resourcepacks, filename))?;
|
||||
// let mut zip_writer = ZipWriter::new(zip_file);
|
||||
//
|
||||
// let options = FileOptions::default()
|
||||
// .compression_method(CompressionMethod::Deflated)
|
||||
// .unix_permissions(0o755);
|
||||
//
|
||||
// for entry in WalkDir::new(path.clone())
|
||||
// .into_iter()
|
||||
// .filter_map(|e| e.ok())
|
||||
// {
|
||||
// let file_path = entry.path();
|
||||
// if file_path.is_file() {
|
||||
// let mut file = fs::File::open(file_path)?;
|
||||
// let relpath = file_path.strip_prefix(path.clone())?;
|
||||
// let mut zip_path = PathBuf::new();
|
||||
// zip_path.push(relpath);
|
||||
//
|
||||
// zip_writer.start_file(zip_path.to_string_lossy().into_owned(), options)?;
|
||||
// std::io::copy(&mut file, &mut zip_writer)?;
|
||||
// }
|
||||
// }
|
||||
// zip_writer.finish()?;
|
||||
// break;
|
||||
// } else {
|
||||
// // 10 increments the last digit of the filename by 1
|
||||
// // TODO: add support for more than one digit
|
||||
// let i: u32 = filename.pop().unwrap().to_digit(10).unwrap();
|
||||
// filename.push(char::from_digit(i + 1, 10).unwrap());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct VersionConfig {
|
||||
pub pack_repo: Option<String>,
|
||||
pub resourcepacks: Option<String>,
|
||||
pub ignore_folder_prefix: Option<String>,
|
||||
}
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Config {
|
||||
pub repository: String,
|
||||
pub resourcepacks: String,
|
||||
pub ignore_folder_prefix: String,
|
||||
pub versions: HashMap<String, VersionConfig>
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn default() -> Config {
|
||||
Config {
|
||||
repository: ".".to_string(),
|
||||
resourcepacks: "_resourcepacks".to_string(),
|
||||
ignore_folder_prefix: "_".to_string(),
|
||||
versions: HashMap::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load() -> Result<Config, Error> {
|
||||
let span = span!(Level::INFO, "Loading Configuration File");
|
||||
let _guard = span.enter();
|
||||
|
||||
let mut conf_path = Config::path().ok_or(Error::new(ErrorKind::Other, "error getting config path"))?;
|
||||
|
||||
if conf_path.exists() {
|
||||
let config: Config = toml::from_str(fs::read_to_string(&conf_path)?.as_str())
|
||||
.map_err(|_| Error::new(ErrorKind::Other, "failed to deserialise"))?;
|
||||
info!(
|
||||
"Loaded Config File: \n\trepo: {}\n\tpacks folder: {}\n\tignore with prefix: {}",
|
||||
config.repository, config.resourcepacks, config.ignore_folder_prefix
|
||||
);
|
||||
Ok(config)
|
||||
} else {
|
||||
warn!(
|
||||
"No config file detected. Creating config file with default values at:\n\t{}",
|
||||
conf_path.display()
|
||||
);
|
||||
create_config_file(&conf_path)?;
|
||||
Ok(Config::default())
|
||||
}
|
||||
}
|
||||
#[cfg(debug_assertions)]
|
||||
fn path() -> Option<PathBuf> {
|
||||
Some(PathBuf::from(".").join("config.toml"))
|
||||
}
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn path() -> Option<PathBuf> {
|
||||
dirs::config_dir()?.join("pack_sync").join("config.toml")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
fn create_config_file(path: &PathBuf) -> Result<(), Error> {
|
||||
println!("{}", path.display());
|
||||
|
||||
fs::create_dir_all(path.parent().unwrap())?;
|
||||
fs::File::create(path)?;
|
||||
|
||||
let yaml = serde_yaml::to_string(&Config::default())
|
||||
.map_err(|_| Error::new(ErrorKind::Other, "failed to serialise"))?;
|
||||
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(path)?
|
||||
.write_all(yaml.as_bytes())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
-106
@@ -1,106 +0,0 @@
|
||||
use std::{fs, io::{self, Error, ErrorKind}, path::{Path, PathBuf}};
|
||||
use zip::write::{FileOptions, ZipWriter};
|
||||
use zip::CompressionMethod;
|
||||
use walkdir::WalkDir;
|
||||
use zip_archive::{Archiver, get_dir_list};
|
||||
use num_cpus;
|
||||
|
||||
pub mod utils;
|
||||
|
||||
const PACK_REPO: &str = "./";
|
||||
const RESOURCEPACKS: &str = "./_resourcepacks";
|
||||
|
||||
const IGNORE_FOLDERS_PREFIX: &str = "_";
|
||||
|
||||
fn main() {
|
||||
let conf = utils::load_config().unwrap();
|
||||
let pack_repo = PathBuf::from(PACK_REPO);
|
||||
clear_resourcepacks().unwrap();
|
||||
scan_directory(pack_repo).unwrap();
|
||||
}
|
||||
|
||||
fn clear_resourcepacks() -> io::Result<()> {
|
||||
println!("[removing existing packs]");
|
||||
fs::remove_dir_all(RESOURCEPACKS)?;
|
||||
fs::create_dir(RESOURCEPACKS)?;
|
||||
println!(" => cleared resourcepacks folder");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn scan_directory(path: PathBuf) -> io::Result<()> {
|
||||
let mut pack_mcmeta = path.clone();
|
||||
pack_mcmeta.push("pack.mcmeta");
|
||||
if pack_mcmeta.exists() {
|
||||
// if pack metadata exists, put the pack into a zip folder.
|
||||
get_archive(path).map_err(|_| Error::new(ErrorKind::Other, "failed to archive zip"))?;
|
||||
return Ok(())
|
||||
} else {
|
||||
// recursively scans subdirectories for other packs
|
||||
for entry in fs::read_dir(path)? {
|
||||
let entry = entry?;
|
||||
|
||||
if entry.path()
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_os_string()
|
||||
.into_string()
|
||||
.map_err(|_| Error::new(ErrorKind::Other, "failed to convert os_str to string"))?
|
||||
.starts_with("_") {
|
||||
println!("found _");
|
||||
continue;
|
||||
}
|
||||
if let Some(zip_str) = entry.path().extension() {
|
||||
if zip_str == "zip" {
|
||||
fs::copy(entry.path(), format!("{}/{}", RESOURCEPACKS, entry.path().file_name().unwrap().to_os_string().into_string().map_err(|_| Error::new(ErrorKind::Other, "failed to convert os_str to string"))?))?;
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(file_type) = entry.file_type() {
|
||||
if file_type.is_dir() {
|
||||
scan_directory(entry.path())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_archive(path: PathBuf) -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("CREATING ARCHIVE: {}", &path.display());
|
||||
if let Some(f) = path.file_stem() {
|
||||
let mut filename = f.to_os_string().into_string().map_err(|_| Error::new(ErrorKind::Other, "failed to convert os_str to string"))?;
|
||||
filename.push_str("_0");
|
||||
loop {
|
||||
if !Path::new(&format!("{}/{}.zip", RESOURCEPACKS, filename.to_string())).exists() { // checks if zip file already exists
|
||||
let zip_file = fs::File::create(format!("{}/{}.zip", RESOURCEPACKS, filename))?;
|
||||
let mut zip_writer = ZipWriter::new(zip_file);
|
||||
|
||||
let options = FileOptions::default()
|
||||
.compression_method(CompressionMethod::Deflated)
|
||||
.unix_permissions(0o755);
|
||||
|
||||
for entry in WalkDir::new(path.clone()).into_iter().filter_map(|e| e.ok()) {
|
||||
let fpath = entry.path();
|
||||
if fpath.is_file() {
|
||||
let mut file = fs::File::open(fpath)?;
|
||||
let relpath = fpath.strip_prefix(path.clone())?;
|
||||
let mut zip_path = PathBuf::new();
|
||||
zip_path.push(relpath);
|
||||
|
||||
zip_writer.start_file(zip_path.to_string_lossy().into_owned(), options)?;
|
||||
std::io::copy(&mut file, &mut zip_writer)?;
|
||||
}
|
||||
}
|
||||
zip_writer.finish()?;
|
||||
break;
|
||||
|
||||
} else {
|
||||
// 10 increments the last digit of the filename by 1
|
||||
// TODO: add support for more than one digit
|
||||
let i: u32 = filename.pop().unwrap().to_digit(10).unwrap();
|
||||
filename.push(char::from_digit(i+1, 10).unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
println!("hello world");
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
use std::{fs::{self, OpenOptions}, io::{self, Error, ErrorKind, Write}, path::{Path, PathBuf}};
|
||||
use crate::IGNORE_FOLDERS_PREFIX;
|
||||
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Config {
|
||||
pack_repo: String,
|
||||
resourcepacks: String,
|
||||
ignore_folder_prefix: String,
|
||||
}
|
||||
|
||||
fn config_path() -> Option<PathBuf> {
|
||||
dirs::config_dir()
|
||||
}
|
||||
|
||||
fn create_config_dir(path: &PathBuf) -> Result<(), Error> {
|
||||
fs::create_dir_all(path)?;
|
||||
create_config_file(&path.join("config.yml"))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_config(path: &PathBuf, config: Config) -> Result<(), Error> {
|
||||
fs::File::create(path)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_config_file(path: &PathBuf) -> Result<(), Error> {
|
||||
fs::File::create(path)?;
|
||||
|
||||
let conf_file = Config {
|
||||
pack_repo: ".".to_string(),
|
||||
resourcepacks: "./_resourcepacks".to_string(),
|
||||
ignore_folder_prefix: "_".to_string(),
|
||||
};
|
||||
let yaml = serde_yaml::to_string(&conf_file).map_err(|_| Error::new(ErrorKind::Other, "failed to serialise"))?;
|
||||
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(path)?;
|
||||
|
||||
file.write_all(yaml.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn load_config() -> Result<Config, Error> {
|
||||
let mut conf_path = config_path().ok_or(Error::new(ErrorKind::Other, "error getting config path"))?;
|
||||
if !conf_path.exists() {
|
||||
return Err(Error::new(ErrorKind::Other, "No config directory found"));
|
||||
};
|
||||
|
||||
conf_path.push("fqntqpacks");
|
||||
if !conf_path.exists() {
|
||||
create_config_dir(&conf_path)?;
|
||||
};
|
||||
|
||||
conf_path.push("config.yml");
|
||||
if !conf_path.exists() {
|
||||
create_config_file(&conf_path)?;
|
||||
};
|
||||
|
||||
let config: Config = serde_yaml::from_reader(fs::File::open(&conf_path)?)
|
||||
.map_err(|_| Error::new(ErrorKind::Other, "failed to deserialise"))?;
|
||||
|
||||
println!(
|
||||
"-----------------------------------------------------------------
|
||||
WARNING: no previous config file detected, created config file at
|
||||
{}
|
||||
-----------------------------------------------------------------", conf_path.display());
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
Reference in New Issue
Block a user