workspacer_cli/analyze_crate.rs
1// ---------------- [ File: workspacer-cli/src/analyze_crate.rs ]
2crate::ix!();
3
4/// For analyzing a single crate, we’ll require:
5/// - `crate_name` (string) — we’ll interpret it as the crate’s name in the workspace
6/// - `workspace_path` (optional) — or else current dir
7/// - `skip_git_check` (bool) — skip checking for a clean Git state if desired
8#[derive(Debug, StructOpt, Getters, Setters)]
9#[getset(get = "pub")]
10pub struct AnalyzeCrateCommand {
11 /// The name of the crate to analyze
12 #[structopt(long = "crate")]
13 crate_name: String,
14
15 /// If provided, we use this as the workspace root
16 #[structopt(long = "workspace")]
17 workspace_path: Option<PathBuf>,
18
19 /// Skip Git clean check
20 #[structopt(long = "skip-git-check")]
21 skip_git_check: bool,
22}
23
24impl AnalyzeCrateCommand {
25 #[tracing::instrument(level="trace", skip(self))]
26 pub async fn run(&self) -> Result<(), WorkspaceError> {
27 let crate_name_owned = self.crate_name().clone();
28
29 // 1) We reuse our existing helper `run_with_workspace_and_crate_name`.
30 // That loads the workspace, optionally checks Git, etc.
31 run_with_workspace_and_crate_name(
32 self.workspace_path().clone(),
33 *self.skip_git_check(),
34 crate_name_owned,
35 // 2) Provide a closure that finds the crate, calls `CrateAnalysis::new(...)`,
36 // and then prints or logs the result.
37 |ws, crate_name| {
38 Box::pin(async move {
39 // a) find the crate by name
40 let arc_h = ws
41 .find_crate_by_name(crate_name)
42 .await
43 .ok_or_else(|| {
44 error!("No crate named '{}' found in workspace", crate_name);
45 CrateError::CrateNotFoundInWorkspace {
46 crate_name: crate_name.to_owned(),
47 }
48 })?;
49 // b) lock to get the real handle
50 let handle = arc_h.lock().await.clone();
51
52 // c) create the crate analysis
53 let analysis = CrateAnalysis::new(&handle).await?;
54 info!("Crate analysis complete for '{}'\n{:#?}", crate_name,analysis);
55 Ok(())
56 })
57 },
58 )
59 .await
60 }
61}