1use crate::cmd::{cfg_spinner, run_stage};
2use crate::errors::*;
3use crate::install::Tools;
4use crate::parse::Opts;
5use crate::thread::{spawn_thread, ThreadHandle};
6use console::{style, Emoji};
7use indicatif::{MultiProgress, ProgressBar};
8use std::path::PathBuf;
9
10static TINKERING: Emoji<'_, '_> = Emoji("🔧", ""); macro_rules! handle_exit_code {
15 ($code:expr) => {
16 let (_, _, code) = $code;
17 if code != 0 {
18 return ::std::result::Result::Ok(code);
19 }
20 };
21}
22
23#[allow(clippy::type_complexity)]
29pub fn tinker_internal(
30 dir: PathBuf,
31 spinners: &MultiProgress,
32 num_steps: u8,
33 tools: &Tools,
34 global_opts: &Opts,
35) -> Result<
36 ThreadHandle<impl FnOnce() -> Result<i32, ExecutionError>, Result<i32, ExecutionError>>,
37 Error,
38> {
39 let tools = tools.clone();
40 let Opts {
41 cargo_engine_args,
42 verbose,
43 ..
44 } = global_opts.clone();
45
46 let tk_msg = format!(
48 "{} {} Running plugin tinkers",
49 style(format!("[1/{}]", num_steps)).bold().dim(),
50 TINKERING
51 );
52
53 let tk_spinner = spinners.insert(0, ProgressBar::new_spinner());
56 let tk_spinner = cfg_spinner(tk_spinner, &tk_msg);
57 let tk_target = dir;
58 let tk_thread = spawn_thread(
59 move || {
60 handle_exit_code!(run_stage(
61 vec![&format!("{} run {}", tools.cargo_engine, cargo_engine_args)],
62 &tk_target,
63 &tk_spinner,
64 &tk_msg,
65 vec![
66 ("PERSEUS_ENGINE_OPERATION", "tinker"),
67 ("CARGO_TARGET_DIR", "dist/target_engine"),
68 ("RUSTFLAGS", "--cfg=engine"),
69 ("CARGO_TERM_COLOR", "always")
70 ],
71 verbose,
72 )?);
73
74 Ok(0)
75 },
76 global_opts.sequential,
77 );
78
79 Ok(tk_thread)
80}
81
82pub fn tinker(dir: PathBuf, tools: &Tools, global_opts: &Opts) -> Result<i32, Error> {
86 let spinners = MultiProgress::new();
87
88 let tk_thread = tinker_internal(dir, &spinners, 1, tools, global_opts)?;
89 let tk_res = tk_thread
90 .join()
91 .map_err(|_| ExecutionError::ThreadWaitFailed)??;
92 if tk_res != 0 {
93 return Ok(tk_res);
94 }
95
96 Ok(0)
98}