initial commit
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Ife1391ed23a1e7f388b1b5eca90b9ea76a6a6964
This commit is contained in:
commit
ef28bdaeb4
63 changed files with 17292 additions and 0 deletions
603
src/cli.rs
Normal file
603
src/cli.rs
Normal file
|
|
@ -0,0 +1,603 @@
|
|||
pub mod commands;
|
||||
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
|
||||
use crate::model::{
|
||||
enums::{ProjectSide, ProjectType, UpdateStrategy},
|
||||
fork::RefType,
|
||||
};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(name = "pakker")]
|
||||
#[clap(about = "A multiplatform modpack manager for Minecraft", long_about = None)]
|
||||
pub struct Cli {
|
||||
/// Enable verbose output (-v for info, -vv for debug, -vvv for trace)
|
||||
#[clap(short, long, action = clap::ArgAction::Count)]
|
||||
pub verbose: u8,
|
||||
|
||||
#[clap(subcommand)]
|
||||
pub command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum Commands {
|
||||
/// Initialize a new modpack project
|
||||
Init(InitArgs),
|
||||
|
||||
/// Import an existing modpack
|
||||
Import(ImportArgs),
|
||||
|
||||
/// Add projects to the modpack
|
||||
Add(AddArgs),
|
||||
|
||||
/// Add projects with explicit platform specification (non-interactive)
|
||||
#[clap(name = "add-prj", alias = "prj")]
|
||||
AddPrj(AddPrjArgs),
|
||||
|
||||
/// Remove projects from the modpack
|
||||
Rm(RmArgs),
|
||||
|
||||
/// Update projects
|
||||
Update(UpdateArgs),
|
||||
|
||||
/// List projects in the modpack
|
||||
Ls(LsArgs),
|
||||
|
||||
/// Set project properties
|
||||
Set(SetArgs),
|
||||
|
||||
/// Link projects together
|
||||
Link(LinkArgs),
|
||||
|
||||
/// Unlink projects
|
||||
Unlink(UnlinkArgs),
|
||||
|
||||
/// Show differences between local and remote
|
||||
Diff(DiffArgs),
|
||||
|
||||
/// Fetch project files
|
||||
Fetch(FetchArgs),
|
||||
|
||||
/// Sync projects (fetch + update)
|
||||
Sync(SyncArgs),
|
||||
|
||||
/// Export modpack
|
||||
Export(ExportArgs),
|
||||
|
||||
/// Manage remote repositories
|
||||
Remote(RemoteArgs),
|
||||
|
||||
/// Update modpack from remote Git repository
|
||||
RemoteUpdate(RemoteUpdateArgs),
|
||||
|
||||
/// Check for available updates
|
||||
Status(StatusArgs),
|
||||
|
||||
/// Inspect project details
|
||||
Inspect(InspectArgs),
|
||||
|
||||
/// Manage API credentials
|
||||
Credentials(CredentialsArgs),
|
||||
|
||||
/// Configure modpack properties
|
||||
Cfg(CfgArgs),
|
||||
|
||||
/// Manage fork configuration
|
||||
Fork(ForkArgs),
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct InitArgs {
|
||||
/// Modpack name
|
||||
#[clap(short, long)]
|
||||
pub name: Option<String>,
|
||||
|
||||
/// Modpack version
|
||||
#[clap(short = 'V', long)]
|
||||
pub version: Option<String>,
|
||||
|
||||
/// Target platform
|
||||
#[clap(short, long, default_value = "multiplatform")]
|
||||
pub target: String,
|
||||
|
||||
/// Minecraft version
|
||||
#[clap(short, long, default_value = "1.20.1")]
|
||||
pub mc_version: String,
|
||||
|
||||
/// Mod loader
|
||||
#[clap(short, long, default_value = "fabric")]
|
||||
pub loader: String,
|
||||
|
||||
/// Mod loader version
|
||||
#[clap(short = 'v', long, default_value = "latest")]
|
||||
pub loader_version: String,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct ImportArgs {
|
||||
/// Path to modpack file
|
||||
pub file: String,
|
||||
|
||||
/// Skip confirmation prompts
|
||||
#[clap(short, long)]
|
||||
pub yes: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct AddArgs {
|
||||
/// Project identifiers to add
|
||||
#[clap(required = true)]
|
||||
pub inputs: Vec<String>,
|
||||
|
||||
/// Project type (mod, resourcepack, shader, datapack, world)
|
||||
#[clap(short = 't', long = "type")]
|
||||
pub project_type: Option<ProjectType>,
|
||||
|
||||
/// Skip resolving dependencies
|
||||
#[clap(short = 'D', long)]
|
||||
pub no_deps: bool,
|
||||
|
||||
/// Update if already exists
|
||||
#[clap(short, long)]
|
||||
pub update: bool,
|
||||
|
||||
/// Skip confirmation prompts
|
||||
#[clap(short, long)]
|
||||
pub yes: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct AddPrjArgs {
|
||||
/// `CurseForge` project slug or ID (optional file ID: `slug#file_id`)
|
||||
#[clap(long = "cf", alias = "curseforge")]
|
||||
pub curseforge: Option<String>,
|
||||
|
||||
/// Modrinth project slug or ID (optional file ID: `slug#file_id`)
|
||||
#[clap(long = "mr", alias = "modrinth")]
|
||||
pub modrinth: Option<String>,
|
||||
|
||||
/// GitHub repository (format: owner/repo or owner/repo#tag)
|
||||
#[clap(long = "gh", alias = "github")]
|
||||
pub github: Option<String>,
|
||||
|
||||
/// Project type (mod, resourcepack, shader, datapack, world)
|
||||
#[clap(short = 't', long = "type")]
|
||||
pub project_type: Option<ProjectType>,
|
||||
|
||||
/// Project side (client, server, both)
|
||||
#[clap(long)]
|
||||
pub side: Option<ProjectSide>,
|
||||
|
||||
/// Update strategy (latest, none)
|
||||
#[clap(long)]
|
||||
pub strategy: Option<UpdateStrategy>,
|
||||
|
||||
/// Redistributable flag
|
||||
#[clap(long)]
|
||||
pub redistributable: Option<bool>,
|
||||
|
||||
/// Subpath for project file placement
|
||||
#[clap(long)]
|
||||
pub subpath: Option<String>,
|
||||
|
||||
/// Project aliases (can be specified multiple times)
|
||||
#[clap(long = "alias")]
|
||||
pub aliases: Vec<String>,
|
||||
|
||||
/// Export flag (whether to include in exports)
|
||||
#[clap(long)]
|
||||
pub export: Option<bool>,
|
||||
|
||||
/// Skip resolving dependencies
|
||||
#[clap(short = 'D', long = "no-deps")]
|
||||
pub no_deps: bool,
|
||||
|
||||
/// Skip confirmation prompts
|
||||
#[clap(short, long)]
|
||||
pub yes: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct RmArgs {
|
||||
/// Project identifiers to remove
|
||||
#[clap(required = true)]
|
||||
pub inputs: Vec<String>,
|
||||
|
||||
/// Skip confirmation prompt
|
||||
#[clap(short, long)]
|
||||
pub yes: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct UpdateArgs {
|
||||
/// Projects to update (empty = all)
|
||||
#[arg(value_name = "PROJECT")]
|
||||
pub inputs: Vec<String>,
|
||||
|
||||
/// Skip confirmation prompts
|
||||
#[arg(short, long)]
|
||||
pub yes: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct LsArgs {
|
||||
/// Show detailed information
|
||||
#[clap(short, long)]
|
||||
pub detailed: bool,
|
||||
|
||||
/// Add update information for projects
|
||||
#[clap(short = 'c', long = "check-updates")]
|
||||
pub check_updates: bool,
|
||||
|
||||
/// Maximum length for project names
|
||||
#[clap(long = "name-max-length")]
|
||||
pub name_max_length: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct SetArgs {
|
||||
/// Project identifier (optional for lockfile properties)
|
||||
pub input: Option<String>,
|
||||
|
||||
/// Project type
|
||||
#[clap(long)]
|
||||
pub r#type: Option<String>,
|
||||
|
||||
/// Project side (client/server/both)
|
||||
#[clap(long)]
|
||||
pub side: Option<String>,
|
||||
|
||||
/// Update strategy (latest/none)
|
||||
#[clap(long)]
|
||||
pub strategy: Option<String>,
|
||||
|
||||
/// Redistributable flag
|
||||
#[clap(long)]
|
||||
pub redistributable: Option<bool>,
|
||||
|
||||
/// Change the target of the pack (curseforge, modrinth, multiplatform)
|
||||
#[clap(short = 't', long)]
|
||||
pub target: Option<String>,
|
||||
|
||||
/// Change the minecraft versions (comma-separated)
|
||||
#[clap(short = 'v', long)]
|
||||
pub mc_versions: Option<String>,
|
||||
|
||||
/// Change the mod loaders (format: name=version,name=version)
|
||||
#[clap(short = 'l', long)]
|
||||
pub loaders: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct LinkArgs {
|
||||
/// Source project
|
||||
pub from: String,
|
||||
|
||||
/// Target project
|
||||
pub to: String,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct UnlinkArgs {
|
||||
/// Source project
|
||||
pub from: String,
|
||||
|
||||
/// Target project
|
||||
pub to: String,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct DiffArgs {
|
||||
/// Path to old lockfile
|
||||
pub old_lockfile: String,
|
||||
|
||||
/// Path to current lockfile (optional, defaults to pakku-lock.json)
|
||||
pub current_lockfile: Option<String>,
|
||||
|
||||
/// Export markdown diff
|
||||
#[clap(long)]
|
||||
pub markdown_diff: Option<String>,
|
||||
|
||||
/// Export markdown (formatted)
|
||||
#[clap(long)]
|
||||
pub markdown: Option<String>,
|
||||
|
||||
/// Verbose output (show file changes)
|
||||
#[clap(short, long)]
|
||||
pub verbose: bool,
|
||||
|
||||
/// Header size for markdown (0-5)
|
||||
#[clap(short = 'H', long, default_value = "2")]
|
||||
pub header_size: usize,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct FetchArgs {
|
||||
/// Timeout for waiting on conflicting operations (seconds)
|
||||
#[clap(short, long)]
|
||||
pub timeout: Option<u64>,
|
||||
|
||||
/// Number of retry attempts for failed downloads
|
||||
#[clap(short = 'r', long, default_value = "2")]
|
||||
pub retry: u32,
|
||||
|
||||
/// Move unknown files to shelf instead of deleting
|
||||
#[clap(long)]
|
||||
pub shelve: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct SyncArgs {
|
||||
/// Sync additions only
|
||||
#[clap(short = 'A', long)]
|
||||
pub additions: bool,
|
||||
|
||||
/// Sync removals only
|
||||
#[clap(short = 'R', long)]
|
||||
pub removals: bool,
|
||||
|
||||
/// Sync updates only
|
||||
#[clap(short = 'U', long)]
|
||||
pub updates: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct ExportArgs {
|
||||
/// Export profile (curseforge, modrinth, serverpack)
|
||||
/// If not specified, all profiles will be exported
|
||||
#[clap(short, long)]
|
||||
pub profile: Option<String>,
|
||||
|
||||
/// Output directory
|
||||
#[clap(short, long)]
|
||||
pub output: Option<String>,
|
||||
|
||||
/// Use Pakker-compatible output layout (build/<profile>/...)
|
||||
/// Default is Pakker layout (exports/...)
|
||||
#[clap(long)]
|
||||
pub pakker_layout: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct RemoteArgs {
|
||||
/// Git URL to install from (if empty, shows status)
|
||||
pub url: Option<String>,
|
||||
|
||||
/// Branch to checkout (instead of remote's HEAD)
|
||||
#[clap(short, long)]
|
||||
pub branch: Option<String>,
|
||||
|
||||
/// Install server pack
|
||||
#[clap(short = 'S', long)]
|
||||
pub server_pack: bool,
|
||||
|
||||
/// Retry count for downloads
|
||||
#[clap(short, long, default_value = "2")]
|
||||
pub retry: u32,
|
||||
|
||||
/// Remove remote from modpack
|
||||
#[clap(long = "rm", long = "remove")]
|
||||
pub remove: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct RemoteUpdateArgs {
|
||||
/// Branch to checkout instead of remote's HEAD
|
||||
#[clap(short, long)]
|
||||
pub branch: Option<String>,
|
||||
|
||||
/// Install server pack instead of full modpack
|
||||
#[clap(short, long)]
|
||||
pub server_pack: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct StatusArgs {
|
||||
/// Check updates in parallel
|
||||
#[clap(short, long)]
|
||||
pub parallel: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct InspectArgs {
|
||||
/// Project identifiers to inspect
|
||||
#[clap(required = true)]
|
||||
pub projects: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct CredentialsArgs {
|
||||
/// Delete stored credentials (defaults to deleting both file and keyring)
|
||||
#[clap(short, long)]
|
||||
pub delete: bool,
|
||||
|
||||
/// Delete credentials file (~/.pakku/credentials)
|
||||
#[clap(long)]
|
||||
pub delete_file: bool,
|
||||
|
||||
/// Delete credentials from keyring (service: pakker)
|
||||
#[clap(long)]
|
||||
pub delete_keyring: bool,
|
||||
|
||||
#[clap(subcommand)]
|
||||
pub subcommand: Option<CredentialsSubcommand>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum CredentialsSubcommand {
|
||||
/// Set API credentials
|
||||
Set(CredentialsSetArgs),
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct CredentialsSetArgs {
|
||||
/// `CurseForge` API key
|
||||
#[clap(long)]
|
||||
pub cf_api_key: Option<String>,
|
||||
|
||||
/// Modrinth API token
|
||||
#[clap(long)]
|
||||
pub modrinth_token: Option<String>,
|
||||
|
||||
/// GitHub access token
|
||||
#[clap(long)]
|
||||
pub gh_access_token: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct CfgArgs {
|
||||
/// Modpack name
|
||||
#[clap(long)]
|
||||
pub name: Option<String>,
|
||||
|
||||
/// Modpack version
|
||||
#[clap(long)]
|
||||
pub version: Option<String>,
|
||||
|
||||
/// Modpack description
|
||||
#[clap(long)]
|
||||
pub description: Option<String>,
|
||||
|
||||
/// Modpack author
|
||||
#[clap(long)]
|
||||
pub author: Option<String>,
|
||||
|
||||
/// Path for mods
|
||||
#[clap(long)]
|
||||
pub mods_path: Option<String>,
|
||||
|
||||
/// Path for resource packs
|
||||
#[clap(long)]
|
||||
pub resource_packs_path: Option<String>,
|
||||
|
||||
/// Path for data packs
|
||||
#[clap(long)]
|
||||
pub data_packs_path: Option<String>,
|
||||
|
||||
/// Path for worlds
|
||||
#[clap(long)]
|
||||
pub worlds_path: Option<String>,
|
||||
|
||||
/// Path for shaders
|
||||
#[clap(long)]
|
||||
pub shaders_path: Option<String>,
|
||||
|
||||
#[clap(subcommand)]
|
||||
pub subcommand: Option<CfgSubcommand>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum CfgSubcommand {
|
||||
/// Configure per-project settings
|
||||
Prj(CfgPrjArgs),
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct CfgPrjArgs {
|
||||
/// Project identifier
|
||||
pub project: String,
|
||||
|
||||
/// Project type
|
||||
#[clap(long)]
|
||||
pub r#type: Option<String>,
|
||||
|
||||
/// Project side (client/server/both)
|
||||
#[clap(long)]
|
||||
pub side: Option<String>,
|
||||
|
||||
/// Update strategy (latest/none)
|
||||
#[clap(long)]
|
||||
pub update_strategy: Option<String>,
|
||||
|
||||
/// Redistributable flag
|
||||
#[clap(long)]
|
||||
pub redistributable: Option<bool>,
|
||||
|
||||
/// Subpath for project
|
||||
#[clap(long)]
|
||||
pub subpath: Option<String>,
|
||||
|
||||
/// Add alias
|
||||
#[clap(long)]
|
||||
pub add_alias: Option<String>,
|
||||
|
||||
/// Remove alias
|
||||
#[clap(long)]
|
||||
pub remove_alias: Option<String>,
|
||||
|
||||
/// Export flag
|
||||
#[clap(long)]
|
||||
pub export: Option<bool>,
|
||||
}
|
||||
|
||||
/// Fork subcommand arguments
|
||||
#[derive(Debug, Args)]
|
||||
#[command(args_conflicts_with_subcommands = true)]
|
||||
pub struct ForkArgs {
|
||||
#[clap(subcommand)]
|
||||
pub subcommand: ForkSubcommand,
|
||||
}
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum ForkSubcommand {
|
||||
/// Initialize fork from parent repository
|
||||
Init {
|
||||
/// Git URL of parent repository
|
||||
#[clap(long, conflicts_with = "from_path")]
|
||||
git_url: Option<String>,
|
||||
|
||||
/// Use current repository as parent
|
||||
#[clap(long, conflicts_with = "from_path")]
|
||||
from_current: bool,
|
||||
|
||||
/// Use an already-cloned repository as parent (path to worktree or .git)
|
||||
#[clap(long, value_parser, conflicts_with_all = &["git_url", "from_current"])]
|
||||
from_path: Option<String>,
|
||||
|
||||
/// Branch/tag/commit to track
|
||||
#[clap(long)]
|
||||
ref_name: Option<String>,
|
||||
|
||||
/// Type of ref (branch/tag/commit)
|
||||
#[clap(long, value_enum)]
|
||||
ref_type: Option<RefType>,
|
||||
|
||||
/// Remote name
|
||||
#[clap(long, default_value = "origin")]
|
||||
remote: Option<String>,
|
||||
},
|
||||
|
||||
/// Update fork configuration
|
||||
Set {
|
||||
/// New git URL (optional)
|
||||
#[clap(long)]
|
||||
git_url: Option<String>,
|
||||
|
||||
/// Branch/tag/commit to track
|
||||
#[clap(long)]
|
||||
ref_name: String,
|
||||
|
||||
/// Type of ref (branch/tag/commit)
|
||||
#[clap(long, value_enum)]
|
||||
ref_type: Option<RefType>,
|
||||
|
||||
/// Remote name
|
||||
#[clap(long)]
|
||||
remote: Option<String>,
|
||||
},
|
||||
|
||||
/// Show fork configuration
|
||||
Show,
|
||||
|
||||
/// Remove fork configuration
|
||||
Unset,
|
||||
|
||||
/// Sync with parent repository
|
||||
Sync,
|
||||
|
||||
/// Promote projects to parent (legacy)
|
||||
Promote {
|
||||
/// Project identifiers to promote
|
||||
projects: Vec<String>,
|
||||
},
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue