legacympt-rs/mpt/src/commands/init.rs
LordMZTE 5ead609763
Some checks failed
continuous-integration/drone/push Build is failing
0.1.3
2022-03-05 01:49:37 +01:00

237 lines
6.8 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::ToKebabCase;
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()
.wrap_err("Failed to generate json data")?;
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(())
}