#[cfg(test)]
pub mod tests;
use crate::Verbosity;
use anyhow::Result;
use duct::Expression;
use std::{
ffi::OsString,
path::Path,
};
use term_size as _;
pub(crate) fn rust_toolchain() -> Result<String> {
let meta = rustc_version::version_meta()?;
let toolchain = format!("{:?}-{}", meta.channel, meta.host,).to_lowercase();
Ok(toolchain)
}
pub fn cargo_cmd<I, S, P>(
command: &str,
args: I,
working_dir: Option<P>,
verbosity: Verbosity,
env: Vec<(&str, Option<String>)>,
) -> Expression
where
I: IntoIterator<Item = S> + std::fmt::Debug,
S: Into<OsString>,
P: AsRef<Path>,
{
let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_string());
let mut cmd_args = Vec::new();
cmd_args.push(command);
cmd_args.push("--color=always");
match verbosity {
Verbosity::Quiet => cmd_args.push("--quiet"),
Verbosity::Verbose => {
if command != "dylint" {
cmd_args.push("--verbose")
}
}
Verbosity::Default => (),
};
let mut cmd_args: Vec<OsString> = cmd_args.iter().map(Into::into).collect();
for arg in args {
cmd_args.push(arg.into());
}
let mut cmd = duct::cmd(cargo, &cmd_args);
env.iter().for_each(|(env_key, maybe_env_val)| {
match maybe_env_val {
Some(env_val) => cmd = cmd.env(env_key, env_val),
None => cmd = cmd.env_remove(env_key),
};
});
if let Some(path) = working_dir {
tracing::debug!("Setting cargo working dir to '{}'", path.as_ref().display());
cmd = cmd.dir(path.as_ref());
}
cmd
}
pub fn cargo_tty_output(cmd: Expression) -> Expression {
#[cfg(windows)]
let term_size = "100";
#[cfg(not(windows))]
let term_size = term_size::dimensions_stderr()
.map(|(width, _)| width.to_string())
.unwrap_or_else(|| "100".to_string());
cmd.env("CARGO_TERM_COLOR", "always")
.env("CARGO_TERM_PROGRESS_WIDTH", term_size)
.env("CARGO_TERM_PROGRESS_WHEN", "always")
}
pub(crate) fn base_name(path: &Path) -> &str {
path.file_name()
.expect("file name must exist")
.to_str()
.expect("must be valid utf-8")
}
pub fn decode_hex(input: &str) -> Result<Vec<u8>, hex::FromHexError> {
hex::decode(input.trim_start_matches("0x"))
}
#[macro_export]
macro_rules! maybe_println {
($verbosity:expr, $($msg:tt)*) => {
if $verbosity.is_verbose() {
::std::println!($($msg)*);
}
};
}
pub const DEFAULT_KEY_COL_WIDTH: usize = 12;
#[macro_export]
macro_rules! name_value_println {
($name:tt, $value:expr, $width:expr) => {{
use colored::Colorize as _;
::std::println!(
"{:>width$} {}",
$name.bright_purple().bold(),
$value,
width = $width,
);
}};
($name:tt, $value:expr) => {
$crate::name_value_println!($name, $value, $crate::DEFAULT_KEY_COL_WIDTH)
};
}