add debug logging
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
LordMZTE 2021-09-08 17:31:27 +02:00
parent 6d44b60182
commit 1fe7ef0f2d
9 changed files with 82 additions and 24 deletions

View file

@ -1,2 +1,3 @@
# 0.1.2 # 0.1.2
- optimize curseforge relation meta querying - optimize curseforge relation meta querying
- add debug logging

View file

@ -17,10 +17,12 @@ crossterm = "0.21.0"
futures = "0.3.16" futures = "0.3.16"
indicatif = "0.16.2" indicatif = "0.16.2"
json5 = "0.3.0" json5 = "0.3.0"
log = "0.4.14"
percent-encoding = "2.1.0" percent-encoding = "2.1.0"
reqwest = { version = "0.11.4", features = ["stream"] } reqwest = { version = "0.11.4", features = ["stream"] }
serde = { version = "1.0.129", features = ["derive"] } serde = { version = "1.0.129", features = ["derive"] }
serde_json = "1.0.67" serde_json = "1.0.67"
simplelog = "0.10.0"
structopt = "0.3.22" structopt = "0.3.22"
tera = "1.12.1" tera = "1.12.1"
thiserror = "1.0.28" thiserror = "1.0.28"

View file

@ -24,6 +24,7 @@ use addonscript::manifest::{
use anyhow::{bail, Context}; use anyhow::{bail, Context};
use async_trait::async_trait; use async_trait::async_trait;
use indicatif::ProgressBar; use indicatif::ProgressBar;
use log::{debug, info};
use reqwest::Client; use reqwest::Client;
use std::{collections::HashMap, io::Write, path::Path, sync::Arc}; use std::{collections::HashMap, io::Write, path::Path, sync::Arc};
use tokio::io::AsyncReadExt; use tokio::io::AsyncReadExt;
@ -110,6 +111,7 @@ pub async fn run((config, mut manifest): (Config, Manifest), all: bool) -> anyho
match installer { match installer {
Installer::Dir(dir) => { Installer::Dir(dir) => {
info!("copying dir installer file {}", path.to_string_lossy());
tokio::fs::copy(config.locations.src.join(path), twitch_dir.join(dir)) tokio::fs::copy(config.locations.src.join(path), twitch_dir.join(dir))
.await?; .await?;
}, },
@ -246,6 +248,7 @@ fn sort_file(
link_rels: &mut Vec<(Installer, Link)>, link_rels: &mut Vec<(Installer, Link)>,
cf_rels: &mut Vec<(u32, u32)>, cf_rels: &mut Vec<(u32, u32)>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
debug!("Sorting file {:?}", &file);
match file { match file {
File::Link { File::Link {
installer, link, .. installer, link, ..

View file

@ -3,7 +3,8 @@ use crate::{config::Config, util::CliStyle};
pub async fn run(config: Config) -> anyhow::Result<()> { pub async fn run(config: Config) -> anyhow::Result<()> {
// These operations are so incredibly performance-critical that we absolutely // These operations are so incredibly performance-critical that we absolutely
// must execute them in parallel! // must execute them in parallel!
let (res1, res2) = tokio::join!( // we ignore the results on purpose, so nothing fails when the dirs dont exist.
let (_, _) = tokio::join!(
async { async {
println!( println!(
"{}", "{}",
@ -17,8 +18,5 @@ pub async fn run(config: Config) -> anyhow::Result<()> {
} }
); );
res1?;
res2?;
Ok(()) Ok(())
} }

View file

@ -9,6 +9,7 @@ use addonscript::manifest::{
RepositoryType, RepositoryType,
}; };
use anyhow::Context; use anyhow::Context;
use log::{debug, info};
use reqwest::Client; use reqwest::Client;
use serde::Serialize; use serde::Serialize;
use std::{collections::HashMap, path::PathBuf, sync::Arc}; use std::{collections::HashMap, path::PathBuf, sync::Arc};
@ -27,6 +28,7 @@ pub async fn run(
.context("Manifest has no versions!")?; .context("Manifest has no versions!")?;
let repos = util::repo_map(manifest.repositories); let repos = util::repo_map(manifest.repositories);
info!("instatiating tera engine");
let mut tera = Tera::default(); let mut tera = Tera::default();
tera.add_raw_template("modlist", TEMPLATE)?; tera.add_raw_template("modlist", TEMPLATE)?;
@ -47,6 +49,11 @@ pub async fn run(
if !cf_rels.is_empty() { if !cf_rels.is_empty() {
println!("{}", "Querying CF metas.".info()); println!("{}", "Querying CF metas.".info());
info!(
"Requesting addon info for {} curseforge mods",
cf_rels.len()
);
let res = http let res = http
.post("https://addons-ecs.forgesvc.net/api/v2/addon") .post("https://addons-ecs.forgesvc.net/api/v2/addon")
.body( .body(
@ -64,6 +71,7 @@ pub async fn run(
let cf_metas = serde_json::from_slice::<Vec<AddonInfoResponse>>(&res) let cf_metas = serde_json::from_slice::<Vec<AddonInfoResponse>>(&res)
.context("Failed deserializing CF relation response")?; .context("Failed deserializing CF relation response")?;
info!("Converting CF metas to AS metas");
let cf_metas = cf_metas.into_iter().map(|m| Meta { let cf_metas = cf_metas.into_iter().map(|m| Meta {
name: m.name, name: m.name,
contributors: m contributors: m
@ -108,6 +116,7 @@ pub async fn run(
} }
fn get_meta(rel: Relation, repos: &HashMap<String, Repository>) -> anyhow::Result<MetaInfo> { fn get_meta(rel: Relation, repos: &HashMap<String, Repository>) -> anyhow::Result<MetaInfo> {
debug!("getting meta for {:?}", &rel);
if let Some(meta) = rel.meta { if let Some(meta) = rel.meta {
return Ok(MetaInfo::Meta(meta)); return Ok(MetaInfo::Meta(meta));
} }

View file

@ -17,6 +17,7 @@ use addonscript::{
}; };
use anyhow::{bail, Context}; use anyhow::{bail, Context};
use crossterm::style::Stylize; use crossterm::style::Stylize;
use log::info;
use twitch::manifest::Manifest as TwManifest; use twitch::manifest::Manifest as TwManifest;
use url::Url; use url::Url;
@ -38,6 +39,7 @@ pub async fn run(config: Config, infile: PathBuf) -> anyhow::Result<()> {
) )
.context("Failed to parse twitch manifest")?; .context("Failed to parse twitch manifest")?;
info!("converting twitch mods to AS relations");
let mut relations = data let mut relations = data
.files .files
.into_iter() .into_iter()
@ -56,6 +58,7 @@ pub async fn run(config: Config, infile: PathBuf) -> anyhow::Result<()> {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
if let Some(ml) = data.minecraft.mod_loaders.pop() { if let Some(ml) = data.minecraft.mod_loaders.pop() {
info!("fount modloader {:?}", &ml);
let mut splits = ml.id.split('-'); let mut splits = ml.id.split('-');
if !matches!(splits.next(), Some("forge")) { if !matches!(splits.next(), Some("forge")) {
bail!("Twitch manifest contains invalid or unknown modloader!"); bail!("Twitch manifest contains invalid or unknown modloader!");

View file

@ -1,6 +1,7 @@
use async_trait::async_trait; use async_trait::async_trait;
use crossterm::style::Stylize; use crossterm::style::Stylize;
use futures::{stream, StreamExt}; use futures::{stream, StreamExt};
use log::info;
use reqwest::{Client, StatusCode}; use reqwest::{Client, StatusCode};
use std::{path::PathBuf, sync::Arc}; use std::{path::PathBuf, sync::Arc};
use thiserror::Error; use thiserror::Error;
@ -58,6 +59,8 @@ impl<C: Callback> Downloader<C> {
url: Url, url: Url,
target: PathBuf, target: PathBuf,
) -> Result<DownloadInfo, DownloadError> { ) -> Result<DownloadInfo, DownloadError> {
info!("Downloading {}", &url);
if let Some(parent) = target.parent() { if let Some(parent) = target.parent() {
tokio::fs::create_dir_all(parent).await?; tokio::fs::create_dir_all(parent).await?;
} }

View file

@ -1,3 +1,6 @@
use anyhow::Context;
use log::{info, LevelFilter};
use simplelog::{ColorChoice, TermLogger, TerminalMode};
use std::path::PathBuf; use std::path::PathBuf;
use structopt::StructOpt; use structopt::StructOpt;
@ -9,6 +12,9 @@ mod util;
#[derive(StructOpt)] #[derive(StructOpt)]
struct Opt { struct Opt {
#[structopt(short, long, parse(from_occurrences), help = "enable verbose logging")]
verbose: u8,
#[structopt(subcommand)] #[structopt(subcommand)]
cmd: Command, cmd: Command,
} }
@ -69,32 +75,54 @@ enum Command {
#[tokio::main] #[tokio::main]
async fn main() -> anyhow::Result<()> { async fn main() -> anyhow::Result<()> {
let Opt { cmd } = Opt::from_args(); let Opt { cmd, verbose } = Opt::from_args();
let log_level = match verbose {
0 => LevelFilter::Off,
1 => LevelFilter::Info,
2 => LevelFilter::Debug,
_ => LevelFilter::Trace,
};
TermLogger::init(
log_level,
simplelog::ConfigBuilder::new()
.set_time_to_local(true)
.set_target_level(LevelFilter::Error)
.build(),
TerminalMode::Stderr,
ColorChoice::Auto,
)
.context("Failed to init logger")?;
/// runs a given command, if the first arg is config or manifest, the
/// manifest or config file is passed to the comand respectively.
macro_rules! run_cmd {
(config: $cmd:ident $($args:expr),* $(,)?) => {
run_cmd!($cmd util::parse_config().await?, $($args),*)
};
(manifest: $cmd:ident $($args:expr),* $(,)?) => {
run_cmd!($cmd util::parse_config_and_manifest().await?, $($args),*)
};
($cmd:ident $($args:expr),* $(,)?) => {{
info!("Running command {}", stringify!($cmd));
commands::$cmd::run($($args),*).await?;
}}
}
match cmd { match cmd {
Command::Init { Command::Init {
modpack_name, modpack_name,
name, name,
mcversion, mcversion,
} => commands::init::run(modpack_name, name, mcversion).await?, } => run_cmd!(init modpack_name, name, mcversion),
Command::DownloadMods { dir, all } => run_cmd!(manifest: downloadmods dir, all),
Command::DownloadMods { dir, all } => { Command::BuildTwitch { all } => run_cmd!(manifest: buildtwitch all),
commands::downloadmods::run(util::parse_config_and_manifest().await?, dir, all).await? Command::Clean => run_cmd!(config: clean),
}, Command::CreateModList { outfile } => run_cmd!(manifest: createmodlist outfile),
Command::Import { infile } => run_cmd!(config: import infile),
Command::BuildTwitch { all } => {
commands::buildtwitch::run(util::parse_config_and_manifest().await?, all).await?
},
Command::Clean => commands::clean::run(util::parse_config().await?).await?,
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(()) Ok(())

View file

@ -2,6 +2,7 @@ use addonscript::manifest::{link::Link, Manifest, Repository};
use anyhow::Context; use anyhow::Context;
use crossterm::style::{Attribute, Attributes, Color, ContentStyle, Stylize}; use crossterm::style::{Attribute, Attributes, Color, ContentStyle, Stylize};
use indicatif::ProgressStyle; use indicatif::ProgressStyle;
use log::info;
use percent_encoding::percent_decode; use percent_encoding::percent_decode;
use std::{ use std::{
collections::HashMap, collections::HashMap,
@ -17,6 +18,7 @@ use crate::config::Config;
/// reads and parses the config from the current working directory /// reads and parses the config from the current working directory
pub async fn parse_config() -> anyhow::Result<Config> { pub async fn parse_config() -> anyhow::Result<Config> {
info!("reading config");
let conf = tokio::fs::read("modpacktoolsconfig.toml") let conf = tokio::fs::read("modpacktoolsconfig.toml")
.await .await
.context("Failed to read config")?; .context("Failed to read config")?;
@ -36,6 +38,8 @@ pub async fn parse_config_and_manifest() -> anyhow::Result<(Config, Manifest)> {
src.join("modpack.json") src.join("modpack.json")
}; };
info!("reading manifest");
let data = tokio::fs::read(path) let data = tokio::fs::read(path)
.await .await
.context("Failed to read manifest")?; .context("Failed to read manifest")?;
@ -109,6 +113,7 @@ pub fn progress_style() -> ProgressStyle {
/// creates the modpacktools temporary directory (set in the config) /// creates the modpacktools temporary directory (set in the config)
pub async fn make_tmp_dir(config: &Config) -> anyhow::Result<()> { pub async fn make_tmp_dir(config: &Config) -> anyhow::Result<()> {
info!("creating temporary directory");
tokio::fs::create_dir_all(&config.locations.temp_dir) tokio::fs::create_dir_all(&config.locations.temp_dir)
.await .await
.context("Failed to create temporary directory")?; .context("Failed to create temporary directory")?;
@ -181,6 +186,12 @@ pub fn link_file_name(link: &Link) -> Result<String, LinkFileNameError> {
/// Copies a directory inclding all files /// Copies a directory inclding all files
pub async fn copy_dir(from: PathBuf, to: PathBuf) -> io::Result<()> { pub async fn copy_dir(from: PathBuf, to: PathBuf) -> io::Result<()> {
info!(
"Copying directory {} to {}",
from.to_string_lossy(),
to.to_string_lossy()
);
for file in WalkDir::new(&from) { for file in WalkDir::new(&from) {
let file = file?; let file = file?;