mirror of
https://github.com/WarrenHood/MCModpackManager.git
synced 2025-04-30 00:24:58 +01:00
Compare commits
No commits in common. "24a34e49b5f6c98de664d82c5949af00d2e8fdc7" and "4d7f6ed14ef726b494b9fefe0cfb37bf586f5d3d" have entirely different histories.
24a34e49b5
...
4d7f6ed14e
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -2064,7 +2064,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mcmpmgr"
|
name = "mcmpmgr"
|
||||||
version = "0.2.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
|
@ -2170,7 +2170,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mmm"
|
name = "mmm"
|
||||||
version = "0.2.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"iced",
|
"iced",
|
||||||
|
|
|
@ -3,8 +3,7 @@ resolver = "2"
|
||||||
members = ["mcmpmgr", "mmm"]
|
members = ["mcmpmgr", "mmm"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
authors = ["Warren Hood <nullbyte001@gmail.com>"]
|
version = "0.1.0"
|
||||||
version = "0.2.0"
|
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[workspace.metadata.crane]
|
[workspace.metadata.crane]
|
||||||
|
|
3
TODO.md
3
TODO.md
|
@ -7,7 +7,7 @@ This is a rather unorganised list of TODOs just so I can somewhat keep track of
|
||||||
### Important
|
### Important
|
||||||
|
|
||||||
- [X] Canonicalize relative path args with `profile` commands
|
- [X] Canonicalize relative path args with `profile` commands
|
||||||
- [X] Add a "merge" apply policy that can merge contents of certain file types.
|
- [ ] Add a "merge" apply policy that can merge contents of certain file types.
|
||||||
Eg. toml, json, and anything else that is reasonable (key-value type things... with nesting)
|
Eg. toml, json, and anything else that is reasonable (key-value type things... with nesting)
|
||||||
This should also be able to merge folders, while recursively applying "merge" logic to individual files.
|
This should also be able to merge folders, while recursively applying "merge" logic to individual files.
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@ This is a rather unorganised list of TODOs just so I can somewhat keep track of
|
||||||
merge (with conflict overrides on a file content level) should result in an install dir with A and B, where a.json and b.json are in A, and a.json is the result of merging a.json into the installed a.json (overwriting any existing key's values with the modpack's values), and the original files in folder B untouched (x.json and y.json)
|
merge (with conflict overrides on a file content level) should result in an install dir with A and B, where a.json and b.json are in A, and a.json is the result of merging a.json into the installed a.json (overwriting any existing key's values with the modpack's values), and the original files in folder B untouched (x.json and y.json)
|
||||||
|
|
||||||
merge (retaining original/modified values) merge should result in an install dir with A and B, where a.json and b.json are in A, and a.json is the result of merging a.json into the installed a.json (retaining the existing values from the file in the install dir), and the original files in folder B untouched (x.json and y.json)
|
merge (retaining original/modified values) merge should result in an install dir with A and B, where a.json and b.json are in A, and a.json is the result of merging a.json into the installed a.json (retaining the existing values from the file in the install dir), and the original files in folder B untouched (x.json and y.json)
|
||||||
- [ ] Test the merge apply policies when I am not half asleep.
|
|
||||||
|
|
||||||
### Nice to haves
|
### Nice to haves
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
[package]
|
[package]
|
||||||
name = "mcmpmgr"
|
name = "mcmpmgr"
|
||||||
authors.workspace = true
|
authors = ["Warren Hood <nullbyte001@gmail.com>"]
|
||||||
version.workspace = true
|
version = "0.1.0"
|
||||||
edition.workspace = true
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { version = "1.0.86", features = ["backtrace"] }
|
anyhow = { version = "1.0.86", features = ["backtrace"] }
|
||||||
|
|
|
@ -139,8 +139,8 @@ enum FileCommands {
|
||||||
/// Side to copy the file/folder to
|
/// Side to copy the file/folder to
|
||||||
#[arg(long, default_value_t = DownloadSide::Server)]
|
#[arg(long, default_value_t = DownloadSide::Server)]
|
||||||
side: DownloadSide,
|
side: DownloadSide,
|
||||||
/// File apply policy - whether to always apply the file or just apply it once (if the file doesn't exist), or merge (mergeretain or mergeoverwrite)
|
/// File apply policy - whether to always apply the file or just apply it once (if the file doesn't exist)
|
||||||
#[arg(long, default_value_t = FileApplyPolicy::MergeOverwrite)]
|
#[arg(long, default_value_t = FileApplyPolicy::Always)]
|
||||||
apply_policy: FileApplyPolicy,
|
apply_policy: FileApplyPolicy,
|
||||||
},
|
},
|
||||||
/// Show metadata about a file in the pack
|
/// Show metadata about a file in the pack
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
file_merge,
|
|
||||||
file_meta::{get_normalized_relative_path, FileApplyPolicy, FileMeta},
|
file_meta::{get_normalized_relative_path, FileApplyPolicy, FileMeta},
|
||||||
mod_meta::{ModMeta, ModProvider},
|
mod_meta::{ModMeta, ModProvider},
|
||||||
providers::DownloadSide,
|
providers::DownloadSide,
|
||||||
};
|
};
|
||||||
use anyhow::{Context, Result};
|
use anyhow::Result;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeMap, BTreeSet},
|
collections::{BTreeMap, BTreeSet},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
str::FromStr,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const MODPACK_FILENAME: &str = "modpack.toml";
|
const MODPACK_FILENAME: &str = "modpack.toml";
|
||||||
|
@ -189,8 +187,6 @@ impl ModpackMeta {
|
||||||
///
|
///
|
||||||
/// Files/Folders, when applied, will ensure that the exact contents of that file or folder match in the instance folder
|
/// Files/Folders, when applied, will ensure that the exact contents of that file or folder match in the instance folder
|
||||||
/// Ie. If a folder is being applied, any files in that folder not in the modpack will be removed
|
/// Ie. If a folder is being applied, any files in that folder not in the modpack will be removed
|
||||||
///
|
|
||||||
/// Both merge policies will recursively copy files/folders from the src into the destination, while performing merges instead of file copies.
|
|
||||||
pub fn install_files(
|
pub fn install_files(
|
||||||
&self,
|
&self,
|
||||||
pack_dir: &Path,
|
pack_dir: &Path,
|
||||||
|
@ -229,83 +225,36 @@ impl ModpackMeta {
|
||||||
if source_path.is_dir() {
|
if source_path.is_dir() {
|
||||||
// Sync a folder
|
// Sync a folder
|
||||||
if target_path.exists() {
|
if target_path.exists() {
|
||||||
if file_meta.apply_policy == FileApplyPolicy::Always
|
println!(
|
||||||
|| file_meta.apply_policy == FileApplyPolicy::Once
|
"Syncing and overwriting existing directory {} -> {}",
|
||||||
{
|
source_path.display(),
|
||||||
println!(
|
target_path.display(),
|
||||||
"Syncing and overwriting existing directory {} -> {}",
|
);
|
||||||
source_path.display(),
|
std::fs::remove_dir_all(&target_path)?;
|
||||||
target_path.display(),
|
|
||||||
);
|
|
||||||
std::fs::remove_dir_all(&target_path)?;
|
|
||||||
} else {
|
|
||||||
println!(
|
|
||||||
"Merging existing directory {} -> {} (policy={})",
|
|
||||||
source_path.display(),
|
|
||||||
target_path.display(),
|
|
||||||
file_meta.apply_policy
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.copy_files(&source_path, &target_path, file_meta.apply_policy.clone())?;
|
self.copy_files(&source_path, &target_path)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_files(&self, src: &Path, dst: &Path, apply_policy: FileApplyPolicy) -> Result<()> {
|
fn copy_files(&self, src: &Path, dst: &Path) -> Result<()> {
|
||||||
if src.is_dir() {
|
if src.is_dir() {
|
||||||
std::fs::create_dir_all(dst)?;
|
std::fs::create_dir_all(dst)?;
|
||||||
for entry in std::fs::read_dir(src)? {
|
for entry in std::fs::read_dir(src)? {
|
||||||
let entry = entry?;
|
let entry = entry?;
|
||||||
let src_path = entry.path();
|
let src_path = entry.path();
|
||||||
let dst_path = dst.join(entry.file_name());
|
let dst_path = dst.join(entry.file_name());
|
||||||
self.copy_files(&src_path, &dst_path, apply_policy.clone())?;
|
self.copy_files(&src_path, &dst_path)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let parent_dir = dst.parent();
|
let parent_dir = dst.parent();
|
||||||
if let Some(parent_dir) = parent_dir {
|
if let Some(parent_dir) = parent_dir {
|
||||||
std::fs::create_dir_all(parent_dir)?;
|
std::fs::create_dir_all(parent_dir)?;
|
||||||
}
|
}
|
||||||
if apply_policy == FileApplyPolicy::Always || apply_policy == FileApplyPolicy::Once {
|
println!("Syncing file {} -> {}", src.display(), dst.display());
|
||||||
println!("Syncing file {} -> {}", src.display(), dst.display());
|
std::fs::copy(src, dst)?;
|
||||||
std::fs::copy(src, dst)?;
|
|
||||||
} else {
|
|
||||||
// Merging files
|
|
||||||
let src_val = std::fs::read_to_string(src)?;
|
|
||||||
let dst_val = if dst.exists() {
|
|
||||||
Some(std::fs::read_to_string(dst)?)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
if let Some(dst_val) = dst_val {
|
|
||||||
let file_ext = if let Some(ext) = dst.extension() {
|
|
||||||
ext
|
|
||||||
} else {
|
|
||||||
anyhow::bail!("Cannot merge file '{dst:#?}' with unknown file type")
|
|
||||||
}
|
|
||||||
.to_string_lossy();
|
|
||||||
|
|
||||||
let file_type = file_merge::FileType::from_str(&file_ext)
|
|
||||||
.with_context(|| format!("Couldn't merge file {src:?} -> {dst:?}"))?;
|
|
||||||
|
|
||||||
let merged_contents = file_merge::merge_files(
|
|
||||||
&src_val,
|
|
||||||
&dst_val,
|
|
||||||
apply_policy == FileApplyPolicy::MergeOverwrite,
|
|
||||||
file_type,
|
|
||||||
)
|
|
||||||
.with_context(|| format!("Failed to merge file {src:?} -> {dst:?}"))?;
|
|
||||||
|
|
||||||
std::fs::write(dst, merged_contents).with_context(|| {
|
|
||||||
format!("Failed to write merged contents of {src:?} -> {dst:?}")
|
|
||||||
})?;
|
|
||||||
} else {
|
|
||||||
println!("Syncing file {} -> {}", src.display(), dst.display());
|
|
||||||
std::fs::copy(src, dst)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
[package]
|
[package]
|
||||||
name = "mmm"
|
name = "mmm"
|
||||||
authors.workspace = true
|
version = "0.1.0"
|
||||||
version.workspace = true
|
edition = "2021"
|
||||||
edition.workspace = true
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { version = "1.0.86", features = ["backtrace"] }
|
anyhow = { version = "1.0.86", features = ["backtrace"] }
|
||||||
iced = { version = "0.12.1", features = ["tokio"] }
|
iced = { version = "0.12.1", features = ["tokio"] }
|
||||||
mcmpmgr = { path = "../mcmpmgr" }
|
mcmpmgr = { version = "0.1.0", path = "../mcmpmgr" }
|
||||||
rfd = "0.14.1"
|
rfd = "0.14.1"
|
||||||
|
|
Loading…
Reference in a new issue