workspacer_cli/
tree.rs

1// ---------------- [ File: workspacer-cli/src/tree.rs ]
2crate::ix!();
3
4#[derive(Debug, StructOpt, Getters, Setters, Builder)]
5#[getset(get = "pub")]
6#[builder(setter(into))]
7pub struct TreeSubcommand {
8    /// How many dependency levels to recurse (default 999 means “no real limit”).
9    #[structopt(long, default_value = "999")]
10    levels: usize,
11
12    /// Whether to show crate versions in the tree
13    #[structopt(long)]
14    show_version: bool,
15
16    /// Whether to show crate path in the tree
17    #[structopt(long)]
18    show_path: bool,
19
20    /// Possibly a verbose flag
21    #[structopt(long)]
22    verbose: bool,
23
24    /// If provided, the name of a crate to act as our root (entrypoint).
25    /// Otherwise, we show all top-level roots in the workspace.
26    #[structopt(long)]
27    crate_name: Option<String>,
28}
29
30impl TreeSubcommand {
31    /// Executes the “tree” subcommand, building either the full workspace tree
32    /// or a focused subtree if `crate_name` is specified.
33    pub async fn run(&self) -> Result<(), WorkspaceError> {
34        use tracing::{debug, error, info, trace};
35
36        trace!(
37            "Entering TreeSubcommand::run (levels={}, show_version={}, show_path={}, verbose={}, crate_name={:?})",
38            self.levels(),
39            self.show_version(),
40            self.show_path(),
41            self.verbose(),
42            self.crate_name(),
43        );
44
45        let path = match std::env::current_dir() {
46            Ok(p) => {
47                debug!("Current dir = {:?}", p);
48                p
49            }
50            Err(e) => {
51                error!("Failed to get current dir: {:?}", e);
52                return Err(WorkspaceError::IoError {
53                    io_error: Arc::new(e),
54                    context: "Could not obtain current working directory".to_string(),
55                });
56            }
57        };
58
59        let ws = match Workspace::<PathBuf, CrateHandle>::new(&path).await {
60            Ok(w) => {
61                info!("Successfully built workspace at path: {:?}", path);
62                w
63            }
64            Err(e) => {
65                error!("Error building workspace: {:?}", e);
66                return Err(e);
67            }
68        };
69
70        // Decide whether we want the full workspace tree or just a single crate subtree
71        let tree = if let Some(name) = self.crate_name() {
72            info!("Building subtree for specified crate: {}", name);
73            ws.build_workspace_subtree(name, *self.levels(), *self.verbose())
74                .await?
75        } else {
76            debug!("No specific crate requested => building full workspace tree");
77            ws.build_workspace_tree(*self.levels(), *self.verbose()).await?
78        };
79
80        let output_str = tree.render(*self.show_version(), *self.show_path());
81        println!("{}", output_str);
82
83        Ok(())
84    }
85}