treewide: migrate to multi-crate layout

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I11a2103f3530f07409177404577b90136a6a6964
This commit is contained in:
raf 2026-05-03 00:33:21 +03:00
commit d445b1814a
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
68 changed files with 247 additions and 72 deletions

46
Cargo.lock generated
View file

@ -2886,6 +2886,16 @@ dependencies = [
[[package]]
name = "pakker"
version = "1.0.2"
dependencies = [
"git2",
"pakker-cli",
"tempfile",
"tokio",
]
[[package]]
name = "pakker-cli"
version = "1.0.2"
dependencies = [
"anyhow",
"async-trait",
@ -2902,6 +2912,42 @@ dependencies = [
"libc",
"log",
"md-5",
"pakker-core",
"rand 0.10.1",
"regex",
"reqwest",
"semver",
"serde",
"serde_json",
"sha1",
"sha2 0.11.0",
"strsim",
"tempfile",
"textwrap",
"thiserror 2.0.18",
"tokio",
"walkdir",
"yansi",
"zip",
]
[[package]]
name = "pakker-core"
version = "1.0.2"
dependencies = [
"anyhow",
"async-trait",
"comfy-table",
"dialoguer",
"futures",
"git2",
"glob",
"indicatif",
"keyring",
"keyring-core",
"libc",
"log",
"md-5",
"mockito",
"rand 0.10.1",
"regex",

View file

@ -1,53 +1,52 @@
[package]
name = "pakker"
version = "1.0.2"
edition = "2024"
authors = [ "NotAShelf <raf@notashelf.dev>" ]
description = "A fast, reliable multiplatform modpack manager for Minecraft"
keywords = [ "minecraft", "modpack", "modrinth", "curseforge", "package-manager" ]
[workspace]
members = [ "crates/*", "pakker" ]
resolver = "3"
[workspace.package]
categories = [ "command-line-utilities", "games" ]
edition = "2024"
keywords = [ "minecraft", "modpack", "modrinth", "curseforge", "package-manager" ]
rust-version = "1.94.0"
readme = true
version = "1.0.2"
[workspace.dependencies]
pakker-cli = { path = "./crates/pakker-cli" }
pakker-core = { path = "./crates/pakker-core" }
[dependencies]
anyhow = "1.0.102"
async-trait = "0.1.89"
clap = { version = "4.6.1", features = [ "derive" ] }
comfy-table = "7.2.2"
dialoguer = "0.12.0"
env_logger = "0.11.10"
futures = "0.3.32"
git2 = "0.20.4"
glob = "0.3.3"
indicatif = "0.18.4"
anyhow = "1.0.102"
async-trait = "0.1.89"
clap = { version = "4.6.1", features = [ "derive" ] }
comfy-table = "7.2.2"
dialoguer = "0.12.0"
env_logger = "0.11.10"
futures = "0.3.32"
git2 = "0.20.4"
glob = "0.3.3"
indicatif = "0.18.4"
keyring = "4.0.0"
keyring-core = "1.0.0"
libc = "0.2.186"
log = "0.4.29"
md-5 = "0.11.0"
rand = "0.10.1"
regex = "1.12.3"
reqwest = { version = "0.13.3", features = [ "json" ] }
semver = "1.0.28"
serde = { version = "1.0.228", features = [ "derive" ] }
serde_json = "1.0.149"
sha1 = "0.11.0"
sha2 = "0.11.0"
strsim = "0.11.1"
tempfile = "3.27.0"
textwrap = "0.16.2"
thiserror = "2.0.18"
tokio = { version = "1.52.1", features = [ "full" ] }
walkdir = "2.5.0"
yansi = "1.0.1"
zip = "8.6.0"
libc = "0.2.186"
log = "0.4.29"
md-5 = "0.11.0"
mockito = "1.7.2"
rand = "0.10.1"
regex = "1.12.3"
reqwest = { version = "0.13.3", features = [ "json" ] }
semver = "1.0.28"
serde = { version = "1.0.228", features = [ "derive" ] }
serde_json = "1.0.149"
sha1 = "0.11.0"
sha2 = "0.11.0"
strsim = "0.11.1"
tempfile = "3.27.0"
textwrap = "0.16.2"
thiserror = "2.0.18"
tokio = { version = "1.52.1", features = [ "full" ] }
walkdir = "2.5.0"
yansi = "1.0.1"
zip = "8.6.0"
[dev-dependencies]
mockito = "1.7.2"
tempfile = "3.27.0"
[lints.clippy]
[workspace.lints.clippy]
cargo = { level = "warn", priority = -1 }
complexity = { level = "warn", priority = -1 }
nursery = { level = "warn", priority = -1 }

View file

@ -0,0 +1,47 @@
[package]
name = "pakker-cli"
version.workspace = true
edition.workspace = true
description = "CLI library for Pakker"
keywords.workspace = true
categories.workspace = true
rust-version.workspace = true
readme = "../../docs/README.md"
[dependencies]
pakker-core.workspace = true
anyhow.workspace = true
async-trait.workspace = true
clap.workspace = true
comfy-table.workspace = true
dialoguer.workspace = true
env_logger.workspace = true
futures.workspace = true
git2.workspace = true
glob.workspace = true
indicatif.workspace = true
keyring.workspace = true
keyring-core.workspace = true
libc.workspace = true
log.workspace = true
md-5.workspace = true
rand.workspace = true
regex.workspace = true
reqwest.workspace = true
semver.workspace = true
serde.workspace = true
serde_json.workspace = true
sha1.workspace = true
sha2.workspace = true
strsim.workspace = true
tempfile.workspace = true
textwrap.workspace = true
thiserror.workspace = true
tokio.workspace = true
walkdir.workspace = true
yansi.workspace = true
zip.workspace = true
[lints]
workspace = true

View file

@ -7,28 +7,20 @@
reason = "license and repository not yet configured"
)]
mod cli;
mod error;
mod export;
mod fetch;
mod git;
mod http;
mod ipc;
mod model;
mod platform;
mod rate_limiter;
mod resolver;
mod ui_utils;
mod utils;
use std::{env, path::PathBuf};
use clap::Parser;
pub mod cli;
pub use pakker_core::{
error, export, fetch, git, http, ipc, model, platform, rate_limiter, resolver,
ui_utils, utils,
};
use cli::{Cli, Commands};
use error::PakkerError;
/// Search for pakker-lock.json in current directory and parent directories
/// Returns the directory containing pakker-lock.json, or None if not found
fn find_working_directory() -> Option<PathBuf> {
let mut current_dir = env::current_dir().ok()?;
@ -38,24 +30,20 @@ fn find_working_directory() -> Option<PathBuf> {
return Some(current_dir);
}
// Try parent directory
if !current_dir.pop() {
// Reached filesystem root
return None;
}
}
}
#[tokio::main]
async fn main() -> Result<(), PakkerError> {
pub async fn run() -> Result<(), PakkerError> {
let cli = Cli::parse();
// Initialize logging based on verbosity level
let log_level = match cli.verbose {
0 => "warn", // Default: only warnings and errors
1 => "info", // -v: info level
2 => "debug", // -vv: debug level
_ => "trace", // -vvv+: trace level (most verbose)
0 => "warn",
1 => "info",
2 => "debug",
_ => "trace",
};
env_logger::Builder::from_env(
@ -65,17 +53,14 @@ async fn main() -> Result<(), PakkerError> {
.format_module_path(false)
.init();
// Initialize the platform keyring store so credential commands work.
if let Err(e) = keyring::use_native_store(false) {
log::warn!("Failed to initialize platform keyring store: {e}");
}
// Search for pakker-lock.json in current directory and parent directories
let working_dir =
find_working_directory().unwrap_or_else(|| PathBuf::from("."));
let lockfile_path = working_dir.join("pakker-lock.json");
let config_path = working_dir.join("pakker.json");
let global_yes = cli.yes;
match cli.command {

View file

@ -0,0 +1,47 @@
[package]
name = "pakker-core"
version.workspace = true
edition.workspace = true
description = "Core library for Pakker"
keywords.workspace = true
categories.workspace = true
rust-version.workspace = true
readme = "../../docs/README.md"
[dependencies]
anyhow.workspace = true
async-trait.workspace = true
comfy-table.workspace = true
dialoguer.workspace = true
futures.workspace = true
git2.workspace = true
glob.workspace = true
indicatif.workspace = true
keyring.workspace = true
keyring-core.workspace = true
libc.workspace = true
log.workspace = true
md-5.workspace = true
rand.workspace = true
regex.workspace = true
reqwest.workspace = true
semver.workspace = true
serde.workspace = true
serde_json.workspace = true
sha1.workspace = true
sha2.workspace = true
strsim.workspace = true
tempfile.workspace = true
textwrap.workspace = true
thiserror.workspace = true
tokio.workspace = true
walkdir.workspace = true
yansi.workspace = true
zip.workspace = true
[dev-dependencies]
mockito.workspace = true
tempfile.workspace = true
[lints]
workspace = true

View file

@ -10,10 +10,11 @@ pub enum ErrorSeverity {
/// Fatal error - operation cannot continue
#[default]
Error,
/// Warning - operation can continue but may have issues
Warning,
/// Info - informational message
#[expect(dead_code, reason = "reserved for future use")]
Info,
}

View file

@ -0,0 +1,21 @@
#![expect(
clippy::multiple_crate_versions,
reason = "transitive dependency version conflicts from upstream crates"
)]
#![expect(
clippy::cargo_common_metadata,
reason = "license and repository not yet configured"
)]
pub mod error;
pub mod export;
pub mod fetch;
pub mod git;
pub mod http;
pub mod ipc;
pub mod model;
pub mod platform;
pub mod rate_limiter;
pub mod resolver;
pub mod ui_utils;
pub mod utils;

21
pakker/Cargo.toml Normal file
View file

@ -0,0 +1,21 @@
[package]
name = "pakker"
version.workspace = true
edition.workspace = true
description = "A fast, reliable multiplatform modpack manager for Minecraft"
keywords.workspace = true
categories.workspace = true
rust-version.workspace = true
readme = "../docs/README.md"
[dependencies]
pakker-cli.workspace = true
tokio.workspace = true
[dev-dependencies]
git2.workspace = true
tempfile.workspace = true
[lints]
workspace = true

6
pakker/src/main.rs Normal file
View file

@ -0,0 +1,6 @@
use pakker_cli::error::PakkerError;
#[tokio::main]
async fn main() -> Result<(), PakkerError> {
pakker_cli::run().await
}

View file

@ -4,7 +4,9 @@ use git2::{Repository, Signature};
pub fn pakker_bin_path() -> PathBuf {
let manifest = env!("CARGO_MANIFEST_DIR");
PathBuf::from(manifest).join("target/debug/pakker")
PathBuf::from(manifest)
.join("..")
.join("target/debug/pakker")
}
pub fn init_bare_repo(path: &PathBuf) -> Result<Repository, git2::Error> {