contract_build/util/
mod.rs1#[cfg(test)]
18pub mod tests;
19
20use crate::Verbosity;
21use anyhow::Result;
22use duct::Expression;
23use std::{
24 ffi::OsString,
25 path::Path,
26};
27use term_size as _;
28
29pub fn rust_toolchain() -> Result<String> {
31 let meta = rustc_version::version_meta()?;
32 let toolchain = format!("{:?}-{}", meta.channel, meta.host,).to_lowercase();
33
34 Ok(toolchain)
35}
36
37pub fn cargo_cmd<I, S, P>(
46 command: &str,
47 args: I,
48 working_dir: Option<P>,
49 verbosity: Verbosity,
50 env: Vec<(&str, Option<String>)>,
51) -> Expression
52where
53 I: IntoIterator<Item = S> + std::fmt::Debug,
54 S: Into<OsString>,
55 P: AsRef<Path>,
56{
57 let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_string());
58 let mut cmd_args = Vec::new();
59
60 cmd_args.push(command);
61 if command != "dylint" {
62 cmd_args.push("--color=always");
63 }
64
65 match verbosity {
66 Verbosity::Quiet => cmd_args.push("--quiet"),
67 Verbosity::Verbose => {
68 if command != "dylint" {
69 cmd_args.push("--verbose")
70 }
71 }
72 Verbosity::Default => (),
73 };
74
75 let mut cmd_args: Vec<OsString> = cmd_args.iter().map(Into::into).collect();
76 for arg in args {
77 cmd_args.push(arg.into());
78 }
79
80 let mut cmd = duct::cmd(cargo, &cmd_args);
81
82 env.iter().for_each(|(env_key, maybe_env_val)| {
83 match maybe_env_val {
84 Some(env_val) => cmd = cmd.env(env_key, env_val),
85 None => cmd = cmd.env_remove(env_key),
86 };
87 });
88
89 if let Some(path) = working_dir {
90 tracing::debug!("Setting cargo working dir to '{}'", path.as_ref().display());
91 cmd = cmd.dir(path.as_ref());
92 }
93
94 cmd
95}
96
97pub fn cargo_tty_output(cmd: Expression) -> Expression {
99 #[cfg(windows)]
100 let term_size = "100";
101
102 #[cfg(not(windows))]
103 let term_size = term_size::dimensions_stderr()
104 .map(|(width, _)| width.to_string())
105 .unwrap_or_else(|| "100".to_string());
106
107 cmd.env("CARGO_TERM_COLOR", "auto")
108 .env("CARGO_TERM_PROGRESS_WIDTH", term_size)
109 .env("CARGO_TERM_PROGRESS_WHEN", "auto")
110}
111
112pub(crate) fn base_name(path: &Path) -> &str {
114 path.file_name()
115 .expect("file name must exist")
116 .to_str()
117 .expect("must be valid utf-8")
118}
119
120pub fn decode_hex(input: &str) -> Result<Vec<u8>, hex::FromHexError> {
122 hex::decode(input.trim_start_matches("0x"))
123}
124
125#[macro_export]
128macro_rules! verbose_eprintln {
129 ($verbosity:expr, $($msg:tt)*) => {
130 if $verbosity.is_verbose() {
131 ::std::eprintln!($($msg)*);
132 }
133 };
134}
135
136pub const DEFAULT_KEY_COL_WIDTH: usize = 12;
137
138#[macro_export]
140macro_rules! name_value_println {
141 ($name:tt, $value:expr, $width:expr) => {{
142 use colored::Colorize as _;
143 ::std::println!(
144 "{:>width$} {}",
145 $name.bright_purple().bold(),
146 $value,
147 width = $width,
148 );
149 }};
150 ($name:tt, $value:expr) => {
151 $crate::name_value_println!($name, $value, $crate::DEFAULT_KEY_COL_WIDTH)
152 };
153}