1use crate::{
2 cmd::{cfg_spinner, run_stage},
3 errors::*,
4 parse::{CheckOpts, Opts},
5 thread::{spawn_thread, ThreadHandle},
6 Tools,
7};
8use console::{style, Emoji};
9use indicatif::{MultiProgress, ProgressBar};
10use std::path::PathBuf;
11
12static CHECKING_ENGINE: Emoji<'_, '_> = Emoji("🦾", "");
14static CHECKING_BROWSER: Emoji<'_, '_> = Emoji("🌐", "");
15static GENERATING: Emoji<'_, '_> = Emoji("🔨", "");
16
17macro_rules! handle_exit_code {
19 ($code:expr) => {
20 let (_, _, code) = $code;
21 if code != 0 {
22 return ::std::result::Result::Ok(code);
23 }
24 };
25}
26
27pub fn check(
33 dir: PathBuf,
34 check_opts: &CheckOpts,
35 tools: &Tools,
36 global_opts: &Opts,
37) -> Result<i32, ExecutionError> {
38 let spinners = MultiProgress::new();
40 let num_steps = if check_opts.generate { 3 } else { 2 };
41
42 let (engine_thread, browser_thread) =
43 cargo_check(dir.clone(), &spinners, num_steps, tools, global_opts)?;
44 let engine_res = engine_thread
45 .join()
46 .map_err(|_| ExecutionError::ThreadWaitFailed)??;
47 if engine_res != 0 {
48 return Ok(engine_res);
49 }
50 let browser_res = browser_thread
51 .join()
52 .map_err(|_| ExecutionError::ThreadWaitFailed)??;
53 if browser_res != 0 {
54 return Ok(browser_res);
55 }
56
57 if check_opts.generate {
59 let generation_res =
60 run_static_generation(dir, &MultiProgress::new(), num_steps, tools, global_opts)?;
61 Ok(generation_res)
62 } else {
63 Ok(0)
64 }
65}
66
67#[allow(clippy::type_complexity)]
71fn cargo_check(
72 dir: PathBuf,
73 spinners: &MultiProgress,
74 num_steps: u8,
75 tools: &Tools,
76 global_opts: &Opts,
77) -> Result<
78 (
79 ThreadHandle<impl FnOnce() -> Result<i32, ExecutionError>, Result<i32, ExecutionError>>,
80 ThreadHandle<impl FnOnce() -> Result<i32, ExecutionError>, Result<i32, ExecutionError>>,
81 ),
82 ExecutionError,
83> {
84 let tools = tools.clone();
86 let Opts {
87 cargo_engine_args,
88 cargo_browser_args,
89 verbose,
90 ..
91 } = global_opts.clone();
92
93 let engine_msg = format!(
94 "{} {} Checking your app's engine-side",
95 style(format!("[1/{}]", num_steps)).bold().dim(),
96 CHECKING_ENGINE
97 );
98 let browser_msg = format!(
99 "{} {} Checking your app's browser-side",
100 style(format!("[2/{}]", num_steps)).bold().dim(),
101 CHECKING_BROWSER
102 );
103
104 let engine_spinner = spinners.insert(0, ProgressBar::new_spinner());
106 let engine_spinner = cfg_spinner(engine_spinner, &engine_msg);
107 let engine_dir = dir.clone();
108 let browser_spinner = spinners.insert(1, ProgressBar::new_spinner());
109 let browser_spinner = cfg_spinner(browser_spinner, &browser_msg);
110 let browser_dir = dir;
111 let cargo_engine_exec = tools.cargo_engine.clone();
112 let engine_thread = spawn_thread(
113 move || {
114 handle_exit_code!(run_stage(
115 vec![&format!(
116 "{} check {}",
117 cargo_engine_exec, cargo_engine_args
118 )],
119 &engine_dir,
120 &engine_spinner,
121 &engine_msg,
122 vec![
123 ("CARGO_TARGET_DIR", "dist/target_engine"),
127 ("RUSTFLAGS", "--cfg=engine"),
128 ("CARGO_TERM_COLOR", "always")
129 ],
130 verbose,
131 )?);
132
133 Ok(0)
134 },
135 global_opts.sequential,
136 );
137 let browser_thread = spawn_thread(
138 move || {
139 handle_exit_code!(run_stage(
140 vec![&format!(
141 "{} check --target wasm32-unknown-unknown {}",
142 tools.cargo_browser, cargo_browser_args
143 )],
144 &browser_dir,
145 &browser_spinner,
146 &browser_msg,
147 vec![
148 ("CARGO_TARGET_DIR", "dist/target_wasm"),
149 ("RUSTFLAGS", "--cfg=client"),
150 ("CARGO_TERM_COLOR", "always")
151 ],
152 verbose,
153 )?);
154
155 Ok(0)
156 },
157 global_opts.sequential,
158 );
159
160 Ok((engine_thread, browser_thread))
161}
162
163#[allow(clippy::type_complexity)]
164fn run_static_generation(
165 dir: PathBuf,
166 spinners: &MultiProgress,
167 num_steps: u8,
168 tools: &Tools,
169 global_opts: &Opts,
170) -> Result<i32, ExecutionError> {
171 let Opts {
172 cargo_engine_args,
173 verbose,
174 ..
175 } = global_opts.clone();
176
177 let msg = format!(
178 "{} {} Checking your app's page generation",
179 style(format!("[3/{}]", num_steps)).bold().dim(),
180 GENERATING
181 );
182
183 let spinner = spinners.insert(0, ProgressBar::new_spinner());
185 let spinner = cfg_spinner(spinner, &msg);
186
187 handle_exit_code!(run_stage(
188 vec![&format!("{} run {}", tools.cargo_engine, cargo_engine_args)],
189 &dir,
190 &spinner,
191 &msg,
192 vec![
193 ("PERSEUS_ENGINE_OPERATION", "build"),
194 ("CARGO_TARGET_DIR", "dist/target_engine"),
195 ("RUSTFLAGS", "--cfg=engine"),
196 ("CARGO_TERM_COLOR", "always")
197 ],
198 verbose,
199 )?);
200
201 Ok(0)
202}