Skip to content

Commit d06a199

Browse files
refactor: improve cli code readability (#14333)
1 parent b446a85 commit d06a199

File tree

1 file changed

+65
-59
lines changed

1 file changed

+65
-59
lines changed

crates/tauri-cli/src/lib.rs

Lines changed: 65 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -65,28 +65,23 @@ impl FromStr for ConfigValue {
6565
let path = PathBuf::from(config);
6666
let raw =
6767
read_to_string(&path).fs_context("failed to read configuration file", path.clone())?;
68-
match path.extension() {
69-
Some(ext) if ext == "toml" => {
70-
Ok(Self(::toml::from_str(&raw).with_context(|| {
71-
format!("failed to parse config at {} as TOML", path.display())
72-
})?))
73-
}
74-
Some(ext) if ext == "json5" => {
75-
Ok(Self(::json5::from_str(&raw).with_context(|| {
76-
format!("failed to parse config at {} as JSON5", path.display())
77-
})?))
78-
}
79-
// treat all other extensions as json
80-
_ => Ok(Self(
81-
// from tauri-utils/src/config/parse.rs:
82-
// we also want to support **valid** json5 in the .json extension
83-
// if the json5 is not valid the serde_json error for regular json will be returned.
84-
match ::json5::from_str(&raw) {
85-
Ok(json5) => json5,
86-
Err(_) => serde_json::from_str(&raw)
87-
.with_context(|| format!("failed to parse config at {} as JSON", path.display()))?,
88-
},
89-
)),
68+
69+
// treat all other extensions as json
70+
// from tauri-utils/src/config/parse.rs:
71+
// we also want to support **valid** json5 in the .json extension
72+
// if the json5 is not valid the serde_json error for regular json will be returned.
73+
match path.extension().and_then(|ext| ext.to_str()) {
74+
Some("toml") => Ok(Self(::toml::from_str(&raw).with_context(|| {
75+
format!("failed to parse config at {} as TOML", path.display())
76+
})?)),
77+
Some("json5") => Ok(Self(::json5::from_str(&raw).with_context(|| {
78+
format!("failed to parse config at {} as JSON5", path.display())
79+
})?)),
80+
_ => Ok(Self(match ::json5::from_str(&raw) {
81+
Ok(json5) => json5,
82+
Err(_) => serde_json::from_str(&raw)
83+
.with_context(|| format!("failed to parse config at {} as JSON", path.display()))?,
84+
})),
9085
}
9186
}
9287
}
@@ -178,6 +173,13 @@ fn format_error<I: CommandFactory>(err: clap::Error) -> clap::Error {
178173
err.format(&mut app)
179174
}
180175

176+
fn get_verbosity(cli_verbose: u8) -> u8 {
177+
std::env::var("TAURI_CLI_VERBOSITY")
178+
.ok()
179+
.and_then(|v| v.parse().ok())
180+
.unwrap_or(cli_verbose)
181+
}
182+
181183
/// Run the Tauri CLI with the passed arguments, exiting if an error occurs.
182184
///
183185
/// The passed arguments should have the binary argument(s) stripped out before being passed.
@@ -222,23 +224,17 @@ where
222224
Err(e) => e.exit(),
223225
};
224226

225-
let verbosity_number = std::env::var("TAURI_CLI_VERBOSITY")
226-
.ok()
227-
.and_then(|v| v.parse().ok())
228-
.unwrap_or(cli.verbose);
229-
// set the verbosity level so subsequent CLI calls (xcode-script, android-studio-script) refer to it
227+
let verbosity_number = get_verbosity(cli.verbose);
230228
std::env::set_var("TAURI_CLI_VERBOSITY", verbosity_number.to_string());
231229

232230
let mut builder = Builder::from_default_env();
233-
let init_res = builder
231+
if let Err(err) = builder
234232
.format_indent(Some(12))
235233
.filter(None, verbosity_level(verbosity_number).to_level_filter())
236-
// golbin spams an insane amount of really technical logs on the debug level so we're reducing one level
237234
.filter(
238235
Some("goblin"),
239236
verbosity_level(verbosity_number.saturating_sub(1)).to_level_filter(),
240237
)
241-
// handlebars is not that spammy but its debug logs are typically far from being helpful
242238
.filter(
243239
Some("handlebars"),
244240
verbosity_level(verbosity_number.saturating_sub(1)).to_level_filter(),
@@ -250,7 +246,6 @@ where
250246
is_command_output = action == "stdout" || action == "stderr";
251247
if !is_command_output {
252248
let style = Style::new().fg_color(Some(AnsiColor::Green.into())).bold();
253-
254249
write!(f, "{style}{action:>12}{style:#} ")?;
255250
}
256251
} else {
@@ -264,15 +259,13 @@ where
264259

265260
if !is_command_output && log::log_enabled!(Level::Debug) {
266261
let style = Style::new().fg_color(Some(AnsiColor::Black.into()));
267-
268262
write!(f, "[{style}{}{style:#}] ", record.target())?;
269263
}
270264

271265
writeln!(f, "{}", record.args())
272266
})
273-
.try_init();
274-
275-
if let Err(err) = init_res {
267+
.try_init()
268+
{
276269
eprintln!("Failed to attach logger: {err}");
277270
}
278271

@@ -305,7 +298,7 @@ fn verbosity_level(num: u8) -> Level {
305298
match num {
306299
0 => Level::Info,
307300
1 => Level::Debug,
308-
2.. => Level::Trace,
301+
_ => Level::Trace,
309302
}
310303
}
311304

@@ -321,8 +314,6 @@ fn prettyprint_level(lvl: Level) -> &'static str {
321314
}
322315

323316
pub trait CommandExt {
324-
// The `pipe` function sets the stdout and stderr to properly
325-
// show the command output in the Node.js wrapper.
326317
fn piped(&mut self) -> std::io::Result<ExitStatus>;
327318
fn output_ok(&mut self) -> crate::Result<Output>;
328319
}
@@ -332,18 +323,25 @@ impl CommandExt for Command {
332323
self.stdin(os_pipe::dup_stdin()?);
333324
self.stdout(os_pipe::dup_stdout()?);
334325
self.stderr(os_pipe::dup_stderr()?);
326+
335327
let program = self.get_program().to_string_lossy().into_owned();
336-
log::debug!(action = "Running"; "Command `{} {}`", program, self.get_args().map(|arg| arg.to_string_lossy()).fold(String::new(), |acc, arg| format!("{acc} {arg}")));
328+
let args = self
329+
.get_args()
330+
.map(|a| a.to_string_lossy())
331+
.collect::<Vec<_>>()
332+
.join(" ");
337333

334+
log::debug!(action = "Running"; "Command `{program} {args}`");
338335
self.status()
339336
}
340337

341338
fn output_ok(&mut self) -> crate::Result<Output> {
342339
let program = self.get_program().to_string_lossy().into_owned();
343340
let args = self
344341
.get_args()
345-
.map(|arg| arg.to_string_lossy())
346-
.fold(String::new(), |acc, arg| format!("{acc} {arg}"));
342+
.map(|a| a.to_string_lossy())
343+
.collect::<Vec<_>>()
344+
.join(" ");
347345
let cmdline = format!("{program} {args}");
348346
log::debug!(action = "Running"; "Command `{cmdline}`");
349347

@@ -359,16 +357,17 @@ impl CommandExt for Command {
359357
let stdout_lines_ = stdout_lines.clone();
360358
std::thread::spawn(move || {
361359
let mut line = String::new();
362-
let mut lines = stdout_lines_.lock().unwrap();
363-
loop {
364-
line.clear();
365-
match stdout.read_line(&mut line) {
366-
Ok(0) => break,
367-
Ok(_) => {
368-
log::debug!(action = "stdout"; "{}", line.trim_end());
369-
lines.extend(line.as_bytes().to_vec());
360+
if let Ok(mut lines) = stdout_lines_.lock() {
361+
loop {
362+
line.clear();
363+
match stdout.read_line(&mut line) {
364+
Ok(0) => break,
365+
Ok(_) => {
366+
log::debug!(action = "stdout"; "{}", line.trim_end());
367+
lines.extend(line.as_bytes());
368+
}
369+
Err(_) => (),
370370
}
371-
Err(_) => (),
372371
}
373372
}
374373
});
@@ -378,16 +377,17 @@ impl CommandExt for Command {
378377
let stderr_lines_ = stderr_lines.clone();
379378
std::thread::spawn(move || {
380379
let mut line = String::new();
381-
let mut lines = stderr_lines_.lock().unwrap();
382-
loop {
383-
line.clear();
384-
match stderr.read_line(&mut line) {
385-
Ok(0) => break,
386-
Ok(_) => {
387-
log::debug!(action = "stderr"; "{}", line.trim_end());
388-
lines.extend(line.as_bytes().to_vec());
380+
if let Ok(mut lines) = stderr_lines_.lock() {
381+
loop {
382+
line.clear();
383+
match stderr.read_line(&mut line) {
384+
Ok(0) => break,
385+
Ok(_) => {
386+
log::debug!(action = "stderr"; "{}", line.trim_end());
387+
lines.extend(line.as_bytes());
388+
}
389+
Err(_) => (),
389390
}
390-
Err(_) => (),
391391
}
392392
}
393393
});
@@ -423,4 +423,10 @@ mod tests {
423423
fn verify_cli() {
424424
Cli::command().debug_assert();
425425
}
426+
427+
#[test]
428+
fn help_output_includes_build() {
429+
let help = Cli::command().render_help().to_string();
430+
assert!(help.contains("Build"));
431+
}
426432
}

0 commit comments

Comments
 (0)