vdev/commands/check/
rust.rs1use anyhow::{Result, bail};
2use std::{ffi::OsString, fs};
3
4use crate::{
5 app,
6 utils::{command::ChainArgs as _, git, paths},
7};
8
9#[derive(clap::Args, Debug)]
11#[command()]
12pub struct Cli {
13 #[arg(long, default_value_t = true)]
14 clippy: bool,
15
16 #[arg(value_name = "FEATURE")]
17 features: Vec<String>,
18
19 #[arg(long)]
20 fix: bool,
21}
22
23#[derive(strum::Display, strum::AsRefStr, Clone, Copy, Debug)]
24#[strum(serialize_all = "lowercase")]
25enum Tool {
26 Clippy,
27 Check,
28}
29
30impl Cli {
31 fn build_args(&self, tool: Tool) -> Vec<OsString> {
33 let pre_args = if self.fix {
34 vec!["--fix"]
35 } else {
36 Vec::default()
37 };
38
39 let feature_args = if self.features.is_empty() {
40 vec!["--all-features".to_string()]
41 } else {
42 vec![
43 "--no-default-features".to_string(),
44 "--features".to_string(),
45 self.features.join(",").clone(),
46 ]
47 };
48
49 [tool.as_ref(), "--workspace", "--all-targets"]
50 .chain_args(feature_args)
51 .chain_args(pre_args)
52 }
53
54 pub fn exec(self) -> Result<()> {
55 let lock_file = paths::find_repo_root()?.join("Cargo.lock");
56 let lock_before = fs::read(&lock_file)?;
57
58 let tool = if self.clippy {
59 Tool::Clippy
60 } else {
61 Tool::Check
62 };
63
64 app::exec("cargo", self.build_args(tool), true)?;
65
66 let lock_after = fs::read(&lock_file)?;
67 if lock_before != lock_after {
68 bail!(
69 "Cargo.lock was modified by `cargo {tool}`. Please commit the updated Cargo.lock."
70 );
71 }
72
73 if self.fix {
75 let has_changes = !git::get_modified_files()?.is_empty();
76 if has_changes {
77 app::exec("cargo", ["fmt", "--all"], true)?;
78 git::commit("chore(vdev): apply vdev rust check fixes")?;
79 }
80 }
81
82 Ok(())
83 }
84}