Compare commits

...

2 commits

Author SHA1 Message Date
LordMZTE 5ead609763
0.1.3
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-05 01:49:37 +01:00
LordMZTE cecf32b413
scrap lua manifest generation 2022-03-05 00:42:48 +01:00
9 changed files with 94 additions and 157 deletions

View file

@ -1,4 +1,11 @@
# 0.1.3
- add support for defines
- update dependencies
- switch from structopt to clap with macro
# 0.1.2 # 0.1.2
- optimize curseforge relation meta querying - optimize curseforge relation meta querying
- add debug logging - add debug logging
- import and init now set the modpack's ID to a kebab-case version of the name - import and init now set the modpack's ID to a kebab-case version of the name

View file

@ -6,6 +6,6 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
serde = { version = "1.0.129", features = ["derive"] } serde = { version = "1.0.136", features = ["derive"] }
thiserror = "1.0.26" thiserror = "1.0.30"
url = { version = "2.2.2", features = ["serde"] } url = { version = "2.2.2", features = ["serde"] }

View file

@ -1,6 +1,6 @@
[package] [package]
name = "mpt" name = "mpt"
version = "0.1.2" version = "0.1.3"
edition = "2018" edition = "2018"
[[bin]] [[bin]]
@ -11,24 +11,24 @@ path = "src/main.rs"
[dependencies] [dependencies]
addonscript = { path = "../addonscript" } addonscript = { path = "../addonscript" }
async-trait = "0.1.51" async-trait = "0.1.52"
crossterm = "0.21.0" clap = { version = "3.1.5", features = ["derive"] }
crossterm = "0.23.0"
futures = "0.3.16" futures = "0.3.16"
heck = "0.3.3" heck = "0.4.0"
indicatif = "0.16.2" indicatif = "0.16.2"
json5 = "0.3.0" json5 = "0.4.1"
log = "0.4.14" log = "0.4.14"
miette = { version = "3.1.0", features = ["fancy"] } miette = { version = "4.2.1", features = ["fancy"] }
mlua = { version = "0.6.6", features = ["luajit", "serialize"] } mlua = { version = "0.7.4", features = ["luajit", "serialize"] }
percent-encoding = "2.1.0" percent-encoding = "2.1.0"
reqwest = { version = "0.11.4", features = ["stream"] } reqwest = { version = "0.11.9", features = ["stream"] }
serde = { version = "1.0.129", features = ["derive"] } serde = { version = "1.0.136", features = ["derive"] }
serde_json = "1.0.67" serde_json = "1.0.79"
simplelog = "0.10.0" simplelog = "0.11.2"
structopt = "0.3.22" tera = "1.15.0"
tera = "1.12.1" thiserror = "1.0.30"
thiserror = "1.0.28" tokio = { version = "1.17.0", features = ["rt-multi-thread", "macros", "fs"] }
tokio = { version = "1.10.1", features = ["rt-multi-thread", "macros", "fs"] }
toml = "0.5.8" toml = "0.5.8"
twitch = { path = "../twitch" } twitch = { path = "../twitch" }
url = "2.2.2" url = "2.2.2"

View file

@ -1,78 +0,0 @@
manifest = {
id = "{{ id }}",
type = "{{ type }}",
meta = {
name = "{{ meta.name }}",
contributors = {
{% for cont in meta.contributors %} {
name = "{{ cont.name }}",
roles = {% for role in cont.roles %}{
"{{ role }}",
{% endfor %}},
{% endfor %}},
{% if meta.description %}description = "{{ meta.description }}",
{% endif %}{% if meta.icon_url %}icon_url = "{{ meta.icon_url }}",
{% endif %}{% if meta.website_url %}website_url = "{{ meta.website_url }}",
{% endif %}},
},
versions = {
{% for ver in versions %}{
version = "{{ ver.version }}",
mcversion = {
{% for mcver in ver.mcversion %} "{{ mcver }}",
{% endfor %}},
files = {
{% for file in ver.files %} {
{% if file.artifact %}installer = "{{ file.installer }}",
artifact = "{{ file.artifact }}",
repository = "{{ file.repository }}",{% else %}{% if file.id %}id = "{{ file.id }}",{% endif %}
installer = "{{ file.installer }}",
link = "{{ file.link }}",{% if file.options %}
options = {
{% for opt in file.options %} "{{ opt }}",
{% endfor %}},{% endif %}{% endif %}
},{% endfor %}
},
},
relations = {
{% for rel in ver.relations %} {
id = "{{ rel.id }}",
{% if rel.file %}file = {
{% if file.artifact %}installer = "{{ file.installer }}",
artifact = "{{ file.artifact }}",
repository = "{{ file.repository }}",{% else %}{% if file.id %}id = "{{ file.id }}",{% endif %}
installer = "{{ file.installer }}",
link = "{{ file.link }}",{% if file.options %}
options = {
{% for opt in file.options %} "{{ opt }}",
{% endfor %}},{% endif %}{% endif %}
},
{% endif %}{% if rel.versions %}versions = "{{ rel.versions }}",
{% endif %}{% if rel.meta %}meta = {
name = "{{ rel.meta.name }}",
contributors = {
{% for cont in rel.meta.contributors %} {
name = "{{ cont.name }}",
roles = {% for role in cont.roles %}{
"{{ role }}",
{% endfor %}},
{% endfor %}},
{% if rel.meta.description %}description = "{{ rel.meta.description }}",
{% endif %}{% if rel.meta.icon_url %}icon_url = "{{ rel.meta.icon_url }}",
{% endif %}{% if rel.meta.website_url %}website_url = "{{ rel.meta.website_url }}",
{% endif %}},
{% endif %}type = "{{ rel.type }}",
options = {
{% for opt in rel.options %} "{{ opt }}",
{% endfor %}},
},{% endfor %}
},
},{% endfor %}
repositories = {
{% for repo in repositories %} {
id = "{{ repo.id }}",
type = "{{ repo.type }}",
url = "{{ repo.url }}",
},{% endfor %}
},
}

View file

@ -16,7 +16,7 @@ use addonscript::{
util::default_file_opts, util::default_file_opts,
}; };
use crossterm::style::Stylize; use crossterm::style::Stylize;
use heck::KebabCase; use heck::ToKebabCase;
use log::info; use log::info;
use miette::{bail, IntoDiagnostic, WrapErr}; use miette::{bail, IntoDiagnostic, WrapErr};
use twitch::manifest::Manifest as TwManifest; use twitch::manifest::Manifest as TwManifest;
@ -24,7 +24,7 @@ use url::Url;
use std::path::PathBuf; use std::path::PathBuf;
use crate::{config::Config, util::make_lua_manifest}; use crate::config::Config;
pub async fn run(config: Config, infile: PathBuf) -> miette::Result<()> { pub async fn run(config: Config, infile: PathBuf) -> miette::Result<()> {
if config.locations.src.join("modpack.json").exists() || if config.locations.src.join("modpack.json").exists() ||
@ -122,8 +122,10 @@ pub async fn run(config: Config, infile: PathBuf) -> miette::Result<()> {
.await .await
.into_diagnostic()?; .into_diagnostic()?;
tokio::fs::write( tokio::fs::write(
config.locations.src.join("modpack.lua"), config.locations.src.join("modpack.json5"),
make_lua_manifest(&manif)?, serde_json::to_vec_pretty(&manif)
.into_diagnostic()
.wrap_err("Failed to generate json data")?,
) )
.await .await
.into_diagnostic()?; .into_diagnostic()?;

View file

@ -1,4 +1,4 @@
use crate::{config::Locations, forge, util::make_lua_manifest}; use crate::{config::Locations, forge};
use addonscript::{ use addonscript::{
manifest::{ manifest::{
installer::Installer, installer::Installer,
@ -30,7 +30,7 @@ use crossterm::{
}, },
ExecutableCommand, ExecutableCommand,
}; };
use heck::KebabCase; use heck::ToKebabCase;
use miette::{IntoDiagnostic, WrapErr}; use miette::{IntoDiagnostic, WrapErr};
use reqwest::Client; use reqwest::Client;
use std::path::Path; use std::path::Path;
@ -164,7 +164,7 @@ pub async fn run(
.await .await
.into_diagnostic()?; .into_diagnostic()?;
let data = make_lua_manifest(&Manifest { let data = serde_json::to_vec_pretty(&Manifest {
id: modpack_name.to_kebab_case(), id: modpack_name.to_kebab_case(),
manifest_type: ManifestType::Modpack, manifest_type: ManifestType::Modpack,
versions: vec![Version { versions: vec![Version {
@ -193,9 +193,11 @@ pub async fn run(
icon_url: None, icon_url: None,
website_url: None, website_url: None,
}, },
})?; })
.into_diagnostic()
.wrap_err("Failed to generate json data")?;
tokio::fs::write(path.join("modpack.lua"), data) tokio::fs::write(path.join("modpack.json5"), data)
.await .await
.into_diagnostic()?; .into_diagnostic()?;

View file

@ -1,8 +1,8 @@
use clap::{Parser, Subcommand};
use log::{info, LevelFilter}; use log::{info, LevelFilter};
use miette::{IntoDiagnostic, WrapErr}; use miette::{IntoDiagnostic, WrapErr};
use simplelog::{ColorChoice, TermLogger, TerminalMode}; use simplelog::{ColorChoice, TermLogger, TerminalMode};
use std::path::PathBuf; use std::path::PathBuf;
use structopt::StructOpt;
mod commands; mod commands;
mod config; mod config;
@ -10,72 +10,79 @@ mod downloader;
mod forge; mod forge;
mod util; mod util;
#[derive(StructOpt)] #[derive(Parser)]
struct Opt { struct Opt {
#[structopt(short, long, parse(from_occurrences), help = "enable verbose logging")] /// enable verbose logging
#[clap(short, long, parse(from_occurrences))]
verbose: u8, verbose: u8,
#[structopt(subcommand)] /// add a parameter to be used by the build script
/// (only useful with lua manifests)
#[clap(short = 'D')]
defines: Vec<String>,
#[clap(subcommand)]
cmd: Command, cmd: Command,
} }
#[derive(StructOpt)] #[derive(Subcommand)]
enum Command { enum Command {
#[structopt(about = "Initializes a new modpack")] /// Initializes a new modpack
Init { Init {
#[structopt(help = "The name of the modpack")] /// The name of the modpack
modpack_name: String, modpack_name: String,
#[structopt(help = "Name of the modpack author")] /// Name of the modpack author
name: String, name: String,
#[structopt(help = "The minecraft version of the modpack")]
/// The minecraft version of the modpack
mcversion: String, mcversion: String,
}, },
#[structopt(name = "downloadmods", about = "Downloads mods of the pack")] /// Downloads mods of the pack
#[clap(name = "downloadmods")]
DownloadMods { DownloadMods {
#[structopt(help = "Directory to download mods to")] /// Directory to download mods to
dir: PathBuf, dir: PathBuf,
#[structopt(short, long, help = "Download all relations and not just mods")]
/// Download all relations and not just mods
#[clap(short, long)]
all: bool, all: bool,
}, },
#[structopt(name = "buildtwitch", about = "Builds a twitch export of the pack")] /// Builds a twitch export of the pack
#[clap(name = "buildtwitch")]
BuildTwitch { BuildTwitch {
#[structopt( /// Downloads all relations instead of just required ones
short, #[clap(short, long)]
long,
help = "Downloads all relations instead of just required ones"
)]
all: bool, all: bool,
}, },
#[structopt(about = "Deletes artifacts and temporary files")] /// Deletes artifacts and temporary files
Clean, Clean,
#[structopt( /// Creates a HTML list of the pack's mods
name = "createmodlist", #[clap(name = "createmodlist")]
about = "Creates a HTML list of the pack's mods."
)]
CreateModList { CreateModList {
#[structopt( /// File to write the mod list to
default_value = "build/modlist.html", #[clap(default_value = "build/modlist.html")]
help = "File to write the mod list to"
)]
outfile: PathBuf, outfile: PathBuf,
}, },
#[structopt( /// Imports a twitch manifest file and converts it to an addonscript
about = "Imports a twitch manifest file and converts it to an addonscript modpack.json" /// modpack.json
)]
Import { Import {
#[structopt(help = "Twitch manifest to convert")] /// Twitch manifest to convert
infile: PathBuf, infile: PathBuf,
}, },
} }
#[tokio::main] #[tokio::main]
async fn main() -> miette::Result<()> { async fn main() -> miette::Result<()> {
let Opt { cmd, verbose } = Opt::from_args(); let Opt {
cmd,
defines,
verbose,
} = Opt::parse();
let log_level = match verbose { let log_level = match verbose {
0 => LevelFilter::Off, 0 => LevelFilter::Off,
@ -104,7 +111,7 @@ async fn main() -> miette::Result<()> {
}; };
(manifest: $cmd:ident $($args:expr),* $(,)?) => { (manifest: $cmd:ident $($args:expr),* $(,)?) => {
run_cmd!($cmd util::parse_config_and_manifest().await?, $($args),*) run_cmd!($cmd util::parse_config_and_manifest(defines, stringify!($cmd)).await?, $($args),*)
}; };
($cmd:ident $($args:expr),* $(,)?) => {{ ($cmd:ident $($args:expr),* $(,)?) => {{

View file

@ -11,7 +11,6 @@ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
string::FromUtf8Error, string::FromUtf8Error,
}; };
use tera::{Context, Tera};
use thiserror::Error; use thiserror::Error;
use url::Url; use url::Url;
use walkdir::WalkDir; use walkdir::WalkDir;
@ -25,15 +24,19 @@ pub async fn parse_config() -> miette::Result<Config> {
.await .await
.into_diagnostic() .into_diagnostic()
.wrap_err("Failed to read config")?; .wrap_err("Failed to read config")?;
Ok(toml::from_slice(&conf)
toml::from_slice(&conf)
.into_diagnostic() .into_diagnostic()
.wrap_err("Failed to parse config")?) .wrap_err("Failed to parse config")
} }
/// parses the config from the current working directory, reads the location of /// parses the config from the current working directory, reads the location of
/// the manifest file from it, parses the manifest and returns both the conig /// the manifest file from it, parses the manifest and returns both the conig
/// and the manifest. /// and the manifest.
pub async fn parse_config_and_manifest() -> miette::Result<(Config, Manifest)> { pub async fn parse_config_and_manifest(
defines: Vec<String>,
command: &str,
) -> miette::Result<(Config, Manifest)> {
let config = parse_config().await?; let config = parse_config().await?;
let src = Path::new(&config.locations.src); let src = Path::new(&config.locations.src);
@ -56,6 +59,13 @@ pub async fn parse_config_and_manifest() -> miette::Result<(Config, Manifest)> {
let manifest = if is_lua { let manifest = if is_lua {
let lua = Lua::new(); let lua = Lua::new();
let mpt = lua.create_table().into_diagnostic()?;
mpt.set("defines", defines).into_diagnostic()?;
mpt.set("command", command).into_diagnostic()?;
lua.globals().set("mpt", mpt).into_diagnostic()?;
lua.load(&data) lua.load(&data)
.exec() .exec()
.into_diagnostic() .into_diagnostic()
@ -186,8 +196,7 @@ pub enum UrlFileNameError {
pub fn url_file_name(url: &Url) -> Result<String, UrlFileNameError> { pub fn url_file_name(url: &Url) -> Result<String, UrlFileNameError> {
let file_name = url let file_name = url
.path_segments() .path_segments()
.map(Iterator::last) .and_then(Iterator::last)
.flatten()
.ok_or(UrlFileNameError::BaseUrl)?; .ok_or(UrlFileNameError::BaseUrl)?;
if file_name.is_empty() { if file_name.is_empty() {
@ -246,18 +255,6 @@ pub async fn copy_dir(from: PathBuf, to: PathBuf) -> io::Result<()> {
Ok(()) Ok(())
} }
pub fn make_lua_manifest(manif: &Manifest) -> miette::Result<String> {
Tera::one_off(
include_str!("../assets/modpack.lua.tera"),
&Context::from_serialize(manif)
.into_diagnostic()
.wrap_err("Failed to create context for tera")?,
false,
)
.into_diagnostic()
.wrap_err("Failed to create lua manifest.")
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use addonscript::manifest::RepositoryType; use addonscript::manifest::RepositoryType;

View file

@ -7,6 +7,6 @@ edition = "2018"
[dependencies] [dependencies]
addonscript = { path = "../addonscript" } addonscript = { path = "../addonscript" }
serde = { version = "1.0.130", features = ["derive"] } serde = { version = "1.0.136", features = ["derive"] }
thiserror = "1.0.28" thiserror = "1.0.30"
url = { version = "2.2.2", features = ["serde"] } url = { version = "2.2.2", features = ["serde"] }