Compare commits
2 commits
c79d6dd8ca
...
5ead609763
Author | SHA1 | Date | |
---|---|---|---|
LordMZTE | 5ead609763 | ||
LordMZTE | cecf32b413 |
|
@ -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
|
||||||
|
|
|
@ -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"] }
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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 %}
|
|
||||||
},
|
|
||||||
}
|
|
|
@ -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()?;
|
||||||
|
|
|
@ -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()?;
|
||||||
|
|
||||||
|
|
|
@ -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),* $(,)?) => {{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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"] }
|
||||||
|
|
Loading…
Reference in a new issue