236 lines
6.7 KiB
Rust
236 lines
6.7 KiB
Rust
use crate::{config::Locations, forge};
|
|
use addonscript::{
|
|
manifest::{
|
|
installer::Installer,
|
|
link::Link,
|
|
Contributor,
|
|
File,
|
|
Manifest,
|
|
ManifestType,
|
|
Meta,
|
|
Relation,
|
|
RelationType,
|
|
Repository,
|
|
RepositoryType,
|
|
Version,
|
|
},
|
|
util::default_file_opts,
|
|
};
|
|
use crossterm::{
|
|
execute,
|
|
style::{
|
|
Attribute,
|
|
Color,
|
|
Print,
|
|
PrintStyledContent,
|
|
ResetColor,
|
|
SetAttribute,
|
|
SetForegroundColor,
|
|
Stylize,
|
|
},
|
|
ExecutableCommand,
|
|
};
|
|
use heck::KebabCase;
|
|
use miette::{IntoDiagnostic, WrapErr};
|
|
use reqwest::Client;
|
|
use std::path::Path;
|
|
use url::Url;
|
|
|
|
use crate::config::Config;
|
|
|
|
const DEFAULT_CONFIG: &[u8] = include_bytes!("../../assets/modpacktoolsconfig.toml");
|
|
const DEFAULT_GITIGNORE: &str = "\
|
|
build/
|
|
.mpt/
|
|
";
|
|
|
|
pub async fn run(
|
|
modpack_name: String,
|
|
author_name: String,
|
|
mcversion: String,
|
|
) -> miette::Result<()> {
|
|
let mut stdout = std::io::stdout();
|
|
|
|
execute!(
|
|
stdout,
|
|
SetForegroundColor(Color::Green),
|
|
Print("Creating modpack "),
|
|
SetForegroundColor(Color::Cyan),
|
|
SetAttribute(Attribute::Bold),
|
|
Print(&modpack_name),
|
|
ResetColor,
|
|
SetForegroundColor(Color::Green),
|
|
Print(" on minecraft version "),
|
|
SetForegroundColor(Color::Cyan),
|
|
SetAttribute(Attribute::Bold),
|
|
Print(&mcversion),
|
|
ResetColor,
|
|
Print('\n'),
|
|
)
|
|
.into_diagnostic()?;
|
|
|
|
let config_path = Path::new("modpacktoolsconfig.toml");
|
|
if !config_path.exists() {
|
|
tokio::fs::write(config_path, DEFAULT_CONFIG)
|
|
.await
|
|
.into_diagnostic()?;
|
|
|
|
stdout
|
|
.execute(PrintStyledContent(
|
|
"Created config!\n"
|
|
.with(Color::Green)
|
|
.attribute(Attribute::Bold),
|
|
))
|
|
.into_diagnostic()?;
|
|
} else {
|
|
stdout
|
|
.execute(PrintStyledContent(
|
|
"Config already exists, skipping...\n"
|
|
.with(Color::Red)
|
|
.attribute(Attribute::Italic),
|
|
))
|
|
.into_diagnostic()?;
|
|
}
|
|
|
|
let config = tokio::fs::read(config_path).await.into_diagnostic()?;
|
|
let Config {
|
|
locations: Locations { src, .. },
|
|
..
|
|
} = toml::from_slice::<Config>(&config)
|
|
.into_diagnostic()
|
|
.wrap_err("failed to deserialize config")?;
|
|
|
|
let path = Path::new(&src);
|
|
|
|
if path.join("modpack.json").exists() || path.join("modpack.json5").exists() {
|
|
stdout
|
|
.execute(PrintStyledContent(
|
|
"Manifest already exists, skipping...\n"
|
|
.with(Color::Red)
|
|
.attribute(Attribute::Italic),
|
|
))
|
|
.into_diagnostic()?;
|
|
} else {
|
|
let mut relations = vec![];
|
|
stdout
|
|
.execute(PrintStyledContent(
|
|
"Trying to find newest forge version...\n".with(Color::Magenta),
|
|
))
|
|
.into_diagnostic()?;
|
|
|
|
if let Some(ver) = forge::newest_forge_version(&Client::new(), &mcversion).await? {
|
|
execute!(
|
|
stdout,
|
|
SetForegroundColor(Color::Green),
|
|
Print("Found newest forge version "),
|
|
SetForegroundColor(Color::Cyan),
|
|
SetAttribute(Attribute::Bold),
|
|
Print(&ver),
|
|
ResetColor,
|
|
Print('\n'),
|
|
)
|
|
.into_diagnostic()?;
|
|
|
|
relations.push(Relation {
|
|
id: "forge".into(),
|
|
file: None,
|
|
relation_type: RelationType::Modloader,
|
|
options: default_file_opts(),
|
|
versions: Some(format!(
|
|
"[{mcver}-{forgever}-{mcver}]",
|
|
mcver = mcversion,
|
|
forgever = ver,
|
|
)),
|
|
meta: None,
|
|
})
|
|
} else {
|
|
execute!(
|
|
stdout,
|
|
SetForegroundColor(Color::Red),
|
|
Print("Couldn't find forge version for minecraft "),
|
|
SetAttribute(Attribute::Bold),
|
|
SetForegroundColor(Color::Cyan),
|
|
Print(&mcversion),
|
|
ResetColor,
|
|
SetForegroundColor(Color::Red),
|
|
Print(" skipping forge...\n"),
|
|
ResetColor,
|
|
)
|
|
.into_diagnostic()?;
|
|
}
|
|
|
|
// also create overrides
|
|
tokio::fs::create_dir_all(path.join("overrides"))
|
|
.await
|
|
.into_diagnostic()?;
|
|
|
|
let data = serde_json::to_vec_pretty(&Manifest {
|
|
id: modpack_name.to_kebab_case(),
|
|
manifest_type: ManifestType::Modpack,
|
|
versions: vec![Version {
|
|
version: "1.0".into(),
|
|
mcversion: vec![mcversion],
|
|
files: vec![File::Link {
|
|
id: Some("overrides".into()),
|
|
link: Link::File("overrides".into()),
|
|
installer: Installer::Override,
|
|
options: Some(default_file_opts()),
|
|
}],
|
|
relations,
|
|
}],
|
|
repositories: vec![Repository {
|
|
id: "curseforge".into(),
|
|
repo_type: RepositoryType::Curseforge,
|
|
url: Url::parse("https://cursemaven.com").unwrap(), // unwrap is ok on fixed value
|
|
}],
|
|
meta: Meta {
|
|
name: modpack_name,
|
|
contributors: vec![Contributor {
|
|
roles: vec!["Owner".to_owned()],
|
|
name: author_name,
|
|
}],
|
|
description: None,
|
|
icon_url: None,
|
|
website_url: None,
|
|
},
|
|
})
|
|
.into_diagnostic()?;
|
|
|
|
tokio::fs::write(path.join("modpack.json5"), data)
|
|
.await
|
|
.into_diagnostic()?;
|
|
|
|
stdout
|
|
.execute(PrintStyledContent(
|
|
"Created manifest!\n"
|
|
.with(Color::Green)
|
|
.attribute(Attribute::Bold),
|
|
))
|
|
.into_diagnostic()?;
|
|
}
|
|
|
|
if Path::new(".gitignore").exists() {
|
|
stdout
|
|
.execute(PrintStyledContent(
|
|
".gitignore exists, skipping...\n"
|
|
.with(Color::Red)
|
|
.attribute(Attribute::Italic),
|
|
))
|
|
.into_diagnostic()?;
|
|
} else {
|
|
tokio::fs::write(".gitignore", DEFAULT_GITIGNORE)
|
|
.await
|
|
.into_diagnostic()?;
|
|
|
|
stdout
|
|
.execute(PrintStyledContent(
|
|
"Created .gitignore!\n"
|
|
.with(Color::Green)
|
|
.attribute(Attribute::Bold),
|
|
))
|
|
.into_diagnostic()?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|