feat: multiline logging

This commit is contained in:
Strix 2023-10-14 22:39:44 +02:00
parent 401efe3862
commit 9a852ee88e
No known key found for this signature in database
GPG key ID: 49B2E37B8915B774
7 changed files with 75 additions and 38 deletions

View file

@ -107,11 +107,11 @@ impl Command {
error!("Update is not yet implemented."); error!("Update is not yet implemented.");
} }
Command::Debug => { Command::Debug => {
trace!("Trace message."); trace!("Trace message.\nWith newline.");
debug!("Debug message."); debug!("Debug message.\nWith newline.");
info!("Info message."); info!("Info message.\nWith newline.");
warn!("Warning message."); warn!("Warning message.\nWith newline.");
error!("Error message."); error!("Error message.\nWith newline.");
info!(""); info!("");
Process::command(vec!["sh", "-c", "echo whoami: $(whoami)"]) Process::command(vec!["sh", "-c", "echo whoami: $(whoami)"])

View file

@ -4,12 +4,15 @@ use serde::{Deserialize, Serialize};
pub struct Config { pub struct Config {
#[serde(default)] #[serde(default)]
pub build_by_default: bool, pub build_by_default: bool,
#[serde(default)]
pub tmp_dir: Option<String>,
} }
impl Default for Config { impl Default for Config {
fn default() -> Config { fn default() -> Config {
Config { Config {
build_by_default: false, build_by_default: false,
tmp_dir: Some(String::from("/tmp/pkgr"))
} }
} }
} }

View file

@ -1,40 +1,57 @@
use colored::Colorize; use colored::Colorize;
use fern::Dispatch; use fern::Dispatch;
use log::SetLoggerError; use log::{Record, SetLoggerError};
use std::env; use std::env;
fn format_regular<S: Into<String>>(log: S, record: &Record) -> String {
let log = log.into();
let line_prefix = |line: String, extend: bool| {
let prefix = if extend {
match record.level() {
log::Level::Trace => " :".bright_blue(),
log::Level::Debug => " :".green(),
log::Level::Info => " :".blue(),
log::Level::Warn => " :".yellow(),
log::Level::Error => " :".red(),
}.to_string()
} else {
match record.level() {
log::Level::Trace => "[TRACE]".bright_blue(),
log::Level::Debug => "??".green(),
log::Level::Info => "=>".blue(),
log::Level::Warn => "##".yellow(),
log::Level::Error => "!!".red()
}.to_string()
};
return format!("{} {}", prefix, line);
};
let mut lines = log.lines().peekable();
let mut output = match lines.peek() {
Some(line) => line_prefix(lines.next().unwrap().to_string(), false),
None => return "".to_string(),
};
for line in lines {
output.push_str(&*format!("\n{}", line_prefix(line.to_string(), true)));
}
output
}
pub fn setup_logger() -> Result<(), SetLoggerError> { pub fn setup_logger() -> Result<(), SetLoggerError> {
Dispatch::new() Dispatch::new()
.format(|out, message, record| { .format(|out, message, record| {
match record.metadata().target() { match record.metadata().target() {
"command:stdout" => { "command:stdout" => {
out.finish(format_args!("{} {}", "::".cyan(), message.to_string())); out.finish(format_args!("{} {}", ">>".cyan(), message.to_string()));
return; return;
} }
"command:stderr" => { "command:stderr" => {
out.finish(format_args!("{} {}", "!!".red(), message.to_string())); out.finish(format_args!("{} {}", ">>".red(), message.to_string()));
return; return;
} }
_ => { _ => out.finish(format_args!("{}", format_regular(message.to_string(), record))),
out.finish(format_args!(
"{} {}",
// Some logic so messages look nice
if message.to_string().len() > 0 {
match record.level().to_string().chars().nth(0).unwrap_or('T') {
'T' => "[TRACE]".bright_blue(),
'D' => "??".green(),
'I' => "=>".blue(),
'W' => "##".yellow(),
'E' => "!!".red(),
_ => "**".blue(),
}
.to_string()
} else {
"".to_string()
},
message.to_string().bright_white()
))
}
} }
}) })
.level( .level(

View file

@ -7,15 +7,15 @@ use regex::Regex;
pub enum PackageIdentifierError { pub enum PackageIdentifierError {
InvalidPackageLocator(String), InvalidPackageLocator(String),
InvalidURI(String), InvalidURI(String),
InvalidPath(String),
} }
impl std::fmt::Display for PackageIdentifierError { impl std::fmt::Display for PackageIdentifierError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self { match self {
PackageIdentifierError::InvalidPackageLocator(s) => { PackageIdentifierError::InvalidPackageLocator(s) => write!(f, "Invalid package locator: {}", s),
write!(f, "Invalid package locator: {}", s)
}
PackageIdentifierError::InvalidURI(s) => write!(f, "Invalid URI: {}", s), PackageIdentifierError::InvalidURI(s) => write!(f, "Invalid URI: {}", s),
PackageIdentifierError::InvalidPath(s) => write!(f, "Invalid path: {}", s),
} }
} }
} }
@ -71,7 +71,18 @@ impl FromStr for PackageIdentifier {
return Err(PackageIdentifierError::InvalidURI(s.to_string())); return Err(PackageIdentifierError::InvalidURI(s.to_string()));
} }
Ok(PackageIdentifier::URI(s.to_string())) Ok(PackageIdentifier::URI(s.to_string()))
} else if std::path::Path::new(s).exists() { } else if s.starts_with("/")
|| s.starts_with("./")
|| s.starts_with("../")
|| s.starts_with("~/")
{
let path = std::path::Path::new(s);
if s.ends_with("/")
|| !path.exists()
|| path.is_dir()
{
return Err(PackageIdentifierError::InvalidPath(s.to_string()));
}
return Ok(PackageIdentifier::Path(s.to_string())); return Ok(PackageIdentifier::Path(s.to_string()));
} else { } else {
let pl = match PackageLocator::from_str(s) { let pl = match PackageLocator::from_str(s) {

View file

@ -37,8 +37,8 @@ pub enum InstallError {
impl ToString for InstallError { impl ToString for InstallError {
fn to_string(&self) -> String { fn to_string(&self) -> String {
match self { match self {
InstallError::BuildError(e) => format!("Build error: {}", e), InstallError::BuildError(e) => format!("Build error: \n{}", e),
InstallError::BinError(e) => format!("Bin error: {}", e), InstallError::BinError(e) => format!("Bin error: \n{}", e),
InstallError::InvalidManifest => "Invalid manifest".to_string(), InstallError::InvalidManifest => "Invalid manifest".to_string(),
InstallError::Generic => "Install error".to_string(), InstallError::Generic => "Install error".to_string(),
} }

View file

@ -38,7 +38,10 @@ impl PackageInstaller {
return Err(BinError::UnpackError("package has no data".to_string())); return Err(BinError::UnpackError("package has no data".to_string()));
} }
if std::path::Path::new(&path).exists() { if std::path::Path::new(&path).exists() {
return Err(BinError::UnpackError("path already exists".to_string())); return Err(BinError::UnpackError(format!(
"path already exists: {}",
path
)));
} }
tar::Archive::new(self.pkgfile.data.as_slice()) tar::Archive::new(self.pkgfile.data.as_slice())
.unpack(&path) .unpack(&path)

View file

@ -1,4 +1,5 @@
use std::path::PathBuf; use std::path::PathBuf;
use crate::CONFIG;
pub struct TempDir { pub struct TempDir {
path: PathBuf, path: PathBuf,
@ -20,9 +21,11 @@ impl TempDir {
impl Default for TempDir { impl Default for TempDir {
fn default() -> TempDir { fn default() -> TempDir {
TempDir::new({ TempDir::new({
let mut t = std::env::temp_dir(); if let Some(d) = CONFIG.with(|c| c.tmp_dir.clone()) {
t.push("pkgr"); PathBuf::from(d)
t } else {
PathBuf::from("/tmp/pkgr")
}
}) })
} }
} }