add import command
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
LordMZTE 2021-09-02 16:35:48 +02:00
parent ca789aa472
commit 72ded8924d
7 changed files with 149 additions and 9 deletions

View file

@ -261,7 +261,7 @@ fn sort_file(
.with_context(|| format!("File references unknown repository {}", &repository))?;
match repo.repo_type {
RepositoryType::Maven => {
let url = util::mvn_artifact_to_url(&artifact, &repo)
let url = util::mvn_artifact_to_url(&artifact, repo)
.context("Failed to convert maven artifact to url")?;
link_rels.push((installer, Link::Http(url)));

View file

@ -204,7 +204,7 @@ async fn process_file(
let url = match repo.repo_type {
RepositoryType::Maven => {
let url = mvn_artifact_to_url(&artifact, &repo)?;
let url = mvn_artifact_to_url(&artifact, repo)?;
pb.println(format!(
"{} {}",
"Resolved maven artifact with url".green(),

123
mpt/src/commands/import.rs Normal file
View file

@ -0,0 +1,123 @@
use addonscript::{
manifest::{
installer::Installer,
link::Link,
Contributor,
File,
Manifest,
ManifestType,
Meta,
Relation,
RelationType,
Repository,
RepositoryType,
Version,
},
util::default_file_opts,
};
use anyhow::{bail, Context};
use crossterm::style::Stylize;
use twitch::manifest::Manifest as TwManifest;
use url::Url;
use std::path::PathBuf;
use crate::config::Config;
pub async fn run(config: Config, infile: PathBuf) -> anyhow::Result<()> {
if config.locations.src.join("modpack.json").exists() ||
config.locations.src.join("modpack.json5").exists()
{
bail!("Manifest already exists!");
}
let mut data = serde_json::from_slice::<TwManifest>(
&tokio::fs::read(infile)
.await
.context("Failed to read twitch manifest")?,
)
.context("Failed to parse twitch manifest")?;
let mut relations = data
.files
.into_iter()
.map(|f| Relation {
id: f.project_id.to_string(),
file: Some(File::Maven {
installer: Installer::Dir("mods".into()),
artifact: format!("curse:{}:{}", f.project_id, f.file_id),
repository: "curseforge".into(),
}),
versions: None,
meta: None,
relation_type: RelationType::Mod,
options: default_file_opts(),
})
.collect::<Vec<_>>();
if let Some(ml) = data.minecraft.mod_loaders.pop() {
let mut splits = ml.id.split('-');
if !matches!(splits.next(), Some("forge")) {
bail!("Twitch manifest contains invalid or unknown modloader!");
}
let forgever = splits.next();
if forgever.is_none() {
bail!("Modloader in twitch manifest missing version!");
}
let forgever = forgever.unwrap();
relations.push(Relation {
id: "forge".into(),
file: None,
relation_type: RelationType::Modloader,
options: default_file_opts(),
versions: Some(format!(
"[{mcver}-{forgever}]",
mcver = &data.minecraft.version,
forgever = forgever,
)),
meta: None,
});
}
let manif = Manifest {
// TODO convert to snake_case
id: data.name.clone(),
manifest_type: ManifestType::Modpack,
versions: vec![Version {
mcversion: vec![data.minecraft.version],
version: data.version,
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: data.name,
contributors: vec![Contributor {
roles: vec!["owner".into()],
name: data.author,
}],
description: None,
icon_url: None,
website_url: None,
},
};
let json = serde_json::to_vec_pretty(&manif)?;
tokio::fs::create_dir_all(&config.locations.src).await?;
tokio::fs::write(config.locations.src.join("modpack.json5"), json).await?;
println!("{}", "Imported manifest!".green());
Ok(())
}

View file

@ -2,4 +2,5 @@ pub mod buildtwitch;
pub mod clean;
pub mod createmodlist;
pub mod downloadmods;
pub mod import;
pub mod init;

View file

@ -57,6 +57,14 @@ enum Command {
)]
outfile: PathBuf,
},
#[structopt(
about = "Imports a twitch manifest file and converts it to an addonscript modpack.json"
)]
Import {
#[structopt(help = "Twitch manifest to convert")]
infile: PathBuf,
},
}
#[tokio::main]
@ -83,6 +91,10 @@ async fn main() -> anyhow::Result<()> {
Command::CreateModList { outfile } => {
commands::createmodlist::run(util::parse_config_and_manifest().await?, outfile).await?
},
Command::Import { infile } => {
commands::import::run(util::parse_config().await?, infile).await?
},
}
Ok(())

View file

@ -17,8 +17,10 @@ use crate::config::Config;
/// reads and parses the config from the current working directory
pub async fn parse_config() -> anyhow::Result<Config> {
let conf = tokio::fs::read("modpacktoolsconfig.toml").await?;
Ok(toml::from_slice(&conf)?)
let conf = tokio::fs::read("modpacktoolsconfig.toml")
.await
.context("Failed to read config")?;
Ok(toml::from_slice(&conf).context("Failed to parse config")?)
}
/// parses the config from the current working directory, reads the location of
@ -34,9 +36,11 @@ pub async fn parse_config_and_manifest() -> anyhow::Result<(Config, Manifest)> {
src.join("modpack.json")
};
let data = tokio::fs::read(path).await?;
let data = std::str::from_utf8(&data)?;
let manifest = json5::from_str::<Manifest>(data)?;
let data = tokio::fs::read(path)
.await
.context("Failed to read manifest")?;
let data = std::str::from_utf8(&data).context("Manifest is invalid UTF-8")?;
let manifest = json5::from_str::<Manifest>(data).context("Failed to parse manifest")?;
Ok((config, manifest))
}

View file

@ -67,8 +67,8 @@ pub enum ManifestType {
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Minecraft {
version: String,
mod_loaders: Vec<ModLoader>,
pub version: String,
pub mod_loaders: Vec<ModLoader>,
}
#[derive(Serialize, Deserialize, Debug)]