1#![warn(clippy::pedantic)]
2#![allow(clippy::missing_errors_doc, clippy::missing_panics_doc)]
3
4pub mod config;
5pub mod modrinth;
6
7use crate::config::Modpack;
8
9#[must_use]
13pub fn modpack_is_dirty(modpack: &Modpack) -> bool {
14 let git_repo = match gix::open(&modpack.directory) {
15 Ok(git_repo) => git_repo,
16 Err(_error) => return false,
17 };
18
19 git_repo.is_dirty().unwrap_or(false)
20}
21
22#[derive(Debug)]
24pub enum PackrinthError {
25 PathIsFile {
26 path: String,
27 },
28 FailedToCreateDir {
29 dir_to_create: String,
30 error_message: String,
31 },
32 FailedToReadToString {
33 path_to_read: String,
34 error_message: String,
35 },
36 FailedToParseConfigJson {
37 config_path: String,
38 error_message: String,
39 },
40 FailedToParseModrinthResponseJson {
41 modrinth_endpoint: String,
42 error_message: String,
43 },
44 FailedToSerialize {
45 error_message: String,
46 },
47 ProjectIsNotAdded {
48 project: String,
49 },
50 OverrideDoesNotExist {
51 project: String,
52 branch: String,
53 },
54 NoOverridesForProject {
55 project: String,
56 },
57 NoExclusionsForProject {
58 project: String,
59 },
60 NoInclusionsForProject {
61 project: String,
62 },
63 ProjectAlreadyHasExclusions {
64 project: String,
65 },
66 ProjectAlreadyHasInclusions {
67 project: String,
68 },
69 FailedToWriteFile {
70 path_to_write_to: String,
71 error_message: String,
72 },
73 FailedToInitializeFileType {
74 file_to_create: String,
75 error_message: String,
76 },
77 DirectoryExpected {
78 path_that_should_have_been_dir: String,
79 },
80 FailedToStartZipFile {
81 file_to_start: String,
82 error_message: String,
83 },
84 FailedToWriteToZip {
85 to_write: String,
86 error_message: String,
87 },
88 FailedToGetWalkDirEntry {
89 error_message: String,
90 },
91 FailedToStripPath {
92 path: String,
93 },
94 FailedToCopyIntoBuffer,
95 FailedToAddZipDir {
96 zip_dir_path: String,
97 },
98 FailedToFinishZip,
99 BranchDoesNotExist {
100 branch: String,
101 error_message: String,
102 },
103 AttemptedToAddOtherModpack,
104 NoModrinthFilesFoundForProject {
105 project: String,
106 },
107 RequestFailed {
108 url: String,
109 error_message: String,
110 },
111 FailedToGetCurrentDirectory {
112 error_message: String,
113 },
114 InvalidPackFormat {
115 used_pack_format: u16,
116 },
117 NoBranchSpecified,
118 NoInclusionsSpecified,
119 NoExclusionsSpecified,
120 RepoIsDirtyWhileUpdating,
121 FailedToInitGitRepoWhileInitModpack {
122 error_message: String,
123 },
124 ModpackAlreadyExists {
125 directory: String,
126 },
127 MainModLoaderProvidedButNoVersion,
128}
129
130impl PackrinthError {
131 #[must_use]
134 pub fn message_and_tip(&self) -> (String, String) {
135 let file_an_issue: String =
136 "file an issue at https://github.com/Thijzert123/packrinth/issues".to_string();
137 match self {
138 PackrinthError::PathIsFile { path } => (format!("path {path} is a file"), "remove the file or change the target directory".to_string()),
139 PackrinthError::FailedToCreateDir{ dir_to_create, error_message } => (format!("failed to create directory {dir_to_create}: {error_message}"), "check if you have sufficient permissions and if the path already exists".to_string()),
140 PackrinthError::FailedToReadToString { path_to_read, error_message } => (format!("failed to read file {path_to_read}: {error_message}"), "check if you have sufficient permissions and if the file exists".to_string()),
141 PackrinthError::FailedToParseConfigJson { config_path, error_message } => (format!("config file {config_path} is invalid: {error_message}"), "fix it according to JSON standards".to_string()),
142 PackrinthError::FailedToParseModrinthResponseJson { modrinth_endpoint, error_message } => (format!("modrinth response from endpoint {modrinth_endpoint} is invalid: {error_message}"), file_an_issue),
143 PackrinthError::FailedToSerialize{ error_message } => (format!("failed to serialize to a JSON: {error_message}"), file_an_issue),
144 PackrinthError::ProjectIsNotAdded { project } => (format!("project {project} is not added to this modpack"), "add it with subcommand: project add".to_string()),
145 PackrinthError::OverrideDoesNotExist { project, branch } => (format!("{project} does not have an override for branch {branch}"), "add one with subcommand: project override add".to_string()),
146 PackrinthError::NoOverridesForProject { project } => (format!("project {project} doesn't have any overrides"), "add one with subcommand: project override add".to_string()),
147 PackrinthError::NoExclusionsForProject { project } => (format!("project {project} doesn't have any exclusions"), "add exclusions with subcommand: project exclude add".to_string()),
148 PackrinthError::NoInclusionsForProject { project } => (format!("project {project} doesn't have any inclusions"), "add inclusions with subcommand: project include add".to_string()),
149 PackrinthError::ProjectAlreadyHasExclusions { project } => (format!("project {project} already has exclusions"), "you can't have both inclusions and exclusions for one project".to_string()),
150 PackrinthError::ProjectAlreadyHasInclusions { project } => (format!("project {project} already has inclusions"), "you can't have both inclusions and exclusions for one project".to_string()),
151 PackrinthError::FailedToWriteFile { path_to_write_to, error_message } => (format!("failed to write to file {path_to_write_to}: {error_message}"), "check if you have sufficient permissions and if the file exists".to_string()),
152 PackrinthError::FailedToInitializeFileType { file_to_create, error_message } => (format!("failed to create file {file_to_create}: {error_message}"), "check if you have sufficient permissions and if the path already exists".to_string()),
153 PackrinthError::DirectoryExpected { path_that_should_have_been_dir } => (format!("expected a directory at {path_that_should_have_been_dir}"), "remove the path if possible".to_string()),
154 PackrinthError::FailedToStartZipFile { file_to_start, error_message } => (format!("failed to start zip file at {file_to_start}: {error_message}"), file_an_issue),
155 PackrinthError::FailedToWriteToZip { to_write, error_message } => (format!("failed to write {to_write} to zip: {error_message}"), file_an_issue),
156 PackrinthError::FailedToGetWalkDirEntry { error_message } => (format!("failed to get entry from WalkDir: {error_message}"), file_an_issue),
157 PackrinthError::FailedToStripPath { path } => (format!("failed to strip path {path}"), file_an_issue),
158 PackrinthError::FailedToCopyIntoBuffer => ("failed to copy data into buffer for zip".to_string(), file_an_issue),
159 PackrinthError::FailedToAddZipDir { zip_dir_path } => (format!("failed to add zip directory {zip_dir_path}"), file_an_issue),
160 PackrinthError::FailedToFinishZip => ("failed to finish zip".to_string(), file_an_issue),
161 PackrinthError::BranchDoesNotExist { branch, error_message } => (format!("branch {branch} doesn't exist: {error_message}"), "add a branch with subcommand: branch add".to_string()),
162 PackrinthError::AttemptedToAddOtherModpack => ("one of the projects is another modpack".to_string(), "remove the modpack project with subcommand: project remove <MODPACK_PROJECT>".to_string()),
163 PackrinthError::NoModrinthFilesFoundForProject { project } => (format!("no files found for project {project}"), "check if the project id is spelled correctly or try to remove or add project inclusions, exclusions or overrides".to_string()),
164 PackrinthError::RequestFailed { url, error_message } => (format!("request to {url} failed: {error_message}"), format!("check your internet connection or {file_an_issue}")),
165 PackrinthError::FailedToGetCurrentDirectory { error_message } => (format!("couldn't get the current directory: {error_message}"), "the current directory may not exist or you have insufficient permissions to access the current directory".to_string()),
166 PackrinthError::InvalidPackFormat { used_pack_format } => (format!("pack format {used_pack_format} is not supported by this Packrinth version"), format!("please use a configuration with pack format {}", config::CURRENT_PACK_FORMAT)),
167 PackrinthError::NoBranchSpecified => ("no branch specified".to_string(), "specify a branch or remove all with the --all flag".to_string()),
168 PackrinthError::NoInclusionsSpecified => ("no inclusions specified".to_string(), "specify inclusions or remove all with the --all flag".to_string()),
169 PackrinthError::NoExclusionsSpecified => ("no exclusions specified".to_string(), "specify exclusions or remove all with the --all flag".to_string()),
170 PackrinthError::RepoIsDirtyWhileUpdating => ("git repository has uncommitted changes".to_string(), "pass the --allow-dirty flag to force updating".to_string()),
171 PackrinthError::FailedToInitGitRepoWhileInitModpack { error_message } => (format!("failed to initialize Git repository: {error_message}"), "the modpack itself was initialized successfully, so you can try to initialize a Git repository yourself".to_string()),
172 PackrinthError::ModpackAlreadyExists { directory } => (format!("a modpack instance already exists in {directory}"), "to force initializing a new repository, pass the --force flag".to_string()),
173 PackrinthError::MainModLoaderProvidedButNoVersion => ("a main mod loader was specified for a branch, but no version was provided".to_string(), "add the loader_version to branch.json".to_string()),
174 }
175 }
176}