workspacer_cli/
register.rs

1// ---------------- [ File: workspacer-cli/src/register.rs ]
2crate::ix!();
3
4/// Register subcommand for naming files, adding crate references, etc.
5#[derive(Debug, StructOpt)]
6pub enum RegisterSubcommand {
7    /// Ensure all source files in a single crate are “registered”
8    /// (that is, it calls `CrateHandle::ensure_all_source_files_are_registered()`).
9    CrateFiles {
10        /// Path (or name) of the crate directory
11        #[structopt(long = "crate")]
12        crate_name: PathBuf,
13
14        /// If true, skip checking for Git cleanliness
15        #[structopt(long)]
16        skip_git_check: bool,
17    },
18
19    /// Ensure all source files in every crate of a workspace are “registered.”
20    /// (Calls `Workspace::ensure_all_source_files_are_registered()`.)
21    AllFiles {
22        /// Path to the workspace root
23        #[structopt(long = "path")]
24        workspace_path: PathBuf,
25
26        /// If true, skip checking for Git cleanliness
27        #[structopt(long)]
28        skip_git_check: bool,
29    },
30
31    /// Register a new internal crate in a “prefix group” crate
32    /// by adding a `[dependencies]` entry in the prefix crate’s Cargo.toml
33    /// plus a `pub use new_crate_name::*;` line in `src/lib.rs`.
34    Internal {
35        /// Path (or name) of the prefix crate
36        #[structopt(long = "prefix-crate")]
37        prefix_crate: PathBuf,
38
39        /// Path (or name) of the new crate to add
40        #[structopt(long = "new-crate")]
41        new_crate: PathBuf,
42
43        /// Optionally specify the workspace root path
44        /// (defaults to current directory if omitted).
45        #[structopt(long = "workspace-path")]
46        workspace_path: Option<PathBuf>,
47
48        /// If true, skip checking for Git cleanliness
49        #[structopt(long)]
50        skip_git_check: bool,
51    },
52}
53
54impl RegisterSubcommand {
55    pub async fn run(&self) -> Result<(), WorkspaceError> {
56        match self {
57            // ------------------------------------------------------------
58            // 1) Single crate “register” => ensure_all_source_files_are_registered
59            // ------------------------------------------------------------
60            RegisterSubcommand::CrateFiles {
61                crate_name,
62                skip_git_check,
63            } => {
64                // Use our helper that loads the workspace plus a specific crate
65                // e.g. `run_with_workspace_and_crate_name`.
66                // Then call `crate_handle.ensure_all_source_files_are_registered()`.
67
68                let crate_name_owned = crate_name.clone();
69                let skip_git = *skip_git_check;
70                run_with_workspace_and_crate_name(Some(crate_name_owned), skip_git, crate_name.to_string_lossy().to_string(),
71                    |ws, crate_name_str| {
72                        Box::pin(async move {
73                            // Find that crate in the workspace
74                            let crate_option = ws.find_crate_by_name(crate_name_str).await;
75                            let ch = match crate_option {
76                                Some(ch) => ch,
77                                None => {
78                                    return Err(CrateError::CrateNotFoundInWorkspace { 
79                                        crate_name: crate_name_str.to_string() 
80                                    }.into());
81                                }
82                            };
83
84                            let mut guard = ch.lock().await;
85                            guard.ensure_all_source_files_are_registered().await?;
86
87                            Ok(())
88                        })
89                    }
90                ).await
91            }
92
93            // ------------------------------------------------------------
94            // 2) AllFiles => entire workspace `ensure_all_source_files_are_registered`
95            // ------------------------------------------------------------
96            RegisterSubcommand::AllFiles {
97                workspace_path,
98                skip_git_check,
99            } => {
100                let ws_path = Some(workspace_path.clone());
101                let skip_git = *skip_git_check;
102
103                run_with_workspace(ws_path, skip_git, move |ws| {
104                    Box::pin(async move {
105                        ws.ensure_all_source_files_are_registered().await?;
106
107                        Ok(())
108                    })
109                }).await
110            }
111
112            // ------------------------------------------------------------
113            // 3) Internal => “register_in_prefix_crate” routine
114            // ------------------------------------------------------------
115            RegisterSubcommand::Internal {
116                prefix_crate,
117                new_crate,
118                workspace_path,
119                skip_git_check,
120            } => {
121                // We'll interpret `prefix_crate` and `new_crate` as *names* or *paths*
122                // and do the usual pattern: load the workspace, find the two crates,
123                // then call `ws.register_in_prefix_crate(&prefix_crate_handle, &new_crate_handle)`.
124                let skip_git = *skip_git_check;
125                let ws_path = workspace_path.clone();
126                let prefix_crate_str = prefix_crate.to_string_lossy().to_string();
127                let new_crate_str    = new_crate.to_string_lossy().to_string();
128
129                run_with_workspace(ws_path, skip_git, move |ws| {
130                    Box::pin(async move {
131                        // We do `ws.find_crate_by_name(...)` or by path. 
132                        // Or you can do the `CrateHandle::new(&prefix_crate_path).await` 
133                        // if it’s not truly a name but a path. 
134                        // For consistency, let's treat them as “workspace crate name”:
135                        let prefix_opt = ws.find_crate_by_name(&prefix_crate_str).await;
136                        let prefix_h = match prefix_opt {
137                            Some(ch) => ch,
138                            None => {
139                                return Err(CrateError::CrateNotFoundInWorkspace { 
140                                    crate_name: prefix_crate_str 
141                                }.into());
142                            }
143                        };
144
145                        let new_opt = ws.find_crate_by_name(&new_crate_str).await;
146                        let new_h = match new_opt {
147                            Some(ch) => ch,
148                            None => {
149                                return Err(CrateError::CrateNotFoundInWorkspace { 
150                                    crate_name: new_crate_str 
151                                }.into());
152                            }
153                        };
154
155                        // For the call to `ws.register_in_prefix_crate`, 
156                        // we need ephemeral handles of type H (not Arc<Mutex<H>>).
157                        let prefix_clone = {
158                            let locked = prefix_h.lock().await;
159                            locked.clone()
160                        };
161                        let new_clone = {
162                            let locked = new_h.lock().await;
163                            locked.clone()
164                        };
165
166                        // Now call the library trait:
167                        ws.register_in_prefix_crate(&prefix_clone, &new_clone).await
168                    })
169                }).await
170            }
171        }
172    }
173}