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