workspacer_cli/
publish.rs

1// ---------------- [ File: workspacer-cli/src/publish.rs ]
2crate::ix!();
3
4#[derive(Debug, StructOpt)]
5pub enum PublishSubcommand {
6    /// Publish a single crate (assuming there's a local Cargo.toml)
7    Crate {
8        #[structopt(long = "crate")]
9        crate_name: PathBuf,
10
11        #[structopt(long = "dry-run")]
12        dry_run: bool,
13    },
14
15    /// Publish all crates in a workspace, in topological order
16    Workspace {
17        #[structopt(long = "path")]
18        path: PathBuf,
19
20        #[structopt(long = "dry-run")]
21        dry_run: bool,
22    },
23
24    /// Publish one crate **and every workspace crate it depends on**
25    CrateTree {
26        /// Path to the workspace root (directory that contains the workspace‑level Cargo.toml)
27        #[structopt(long = "path")]
28        path: PathBuf,
29
30        /// Name of the crate that should act as the tree’s *root*
31        #[structopt(long = "root")]
32        root: String,
33
34        #[structopt(long = "dry-run")]
35        dry_run: bool,
36    },
37}
38
39impl PublishSubcommand {
40    pub async fn run(&self) -> Result<(), WorkspaceError> {
41        match self {
42            PublishSubcommand::Crate { crate_name, dry_run } => {
43                let dry_run = *dry_run;
44                trace!("Publishing single crate at '{}'", crate_name.display());
45
46                // Use `run_with_crate` to build a CrateHandle and optionally check Git, etc.
47                // Then call the `TryPublish` trait method on it.
48                run_with_crate(crate_name.clone(), /*skip_git_check=*/false, move |handle| {
49                    Box::pin(async move {
50                        // If you want a `dry_run` or other flags, you can pass them here.
51                        // For example, handle.try_publish(dry_run).await. We’ll use false for a real publish.
52                        handle.try_publish(dry_run).await.map_err(|crate_err| {
53                            error!("Could not publish crate='{}': {:?}", handle.name(), crate_err);
54                            WorkspaceError::CrateError(crate_err)
55                        })?;
56
57                        info!("Successfully published crate='{}'", handle.name());
58                        Ok(())
59                    })
60                })
61                .await
62            }
63
64            PublishSubcommand::Workspace { path, dry_run } => {
65                let dry_run = *dry_run;
66                trace!("Publishing entire workspace at '{}'", path.display());
67
68                // Use `run_with_workspace` to load the workspace, check Git, etc. Then call `TryPublish`.
69                run_with_workspace(Some(path.clone()), /*skip_git_check=*/false, move |ws| {
70                    Box::pin(async move {
71                        // If you want to do a "dry run" or pass flags, you can do that here.
72                        // We'll do a real publish with `dry_run=false`.
73                        ws.try_publish(dry_run).await.map_err(|err| {
74                            error!(
75                                "Could not publish workspace at '{}': {:?}",
76                                ws.as_ref().display(),
77                                err
78                            );
79                            err
80                        })?;
81
82                        info!("Successfully published all crates in workspace at '{}'", ws.as_ref().display());
83                        Ok(())
84                    })
85                })
86                .await
87            }
88
89            PublishSubcommand::CrateTree { path, root, dry_run } => {
90                let dry_run = *dry_run;
91                trace!(
92                    "Publishing crate‑tree rooted at '{}' in workspace '{}'",
93                    root,
94                    path.display()
95                );
96
97                let root_clone = root.clone();
98                run_with_workspace(Some(path.clone()), /*skip_git_check=*/false, move |ws| {
99                    Box::pin(async move {
100                        ws.try_publish_crate_tree(&root_clone, dry_run).await.map_err(|err| {
101                            error!(
102                                "Could not publish crate‑tree rooted at '{}' in workspace '{}': {:?}",
103                                root_clone,
104                                ws.as_ref().display(),
105                                err
106                            );
107                            err
108                        })
109                    })
110                })
111                .await
112            }
113        }
114    }
115}