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}