workspacer_cli/
write.rs

1// ---------------- [ File: workspacer-cli/src/write.rs ]
2crate::ix!();
3
4/// A single fused enum with subcommands, each having **all** the config flags duplicated.
5#[derive(StructOpt, Clone, Debug)]
6pub enum ReadmeWriterCli {
7    /// Generate or update README for a single crate
8    SingleCrate {
9        /// If set, do not include doc comments in the crate interface.
10        #[structopt(long = "skip-docs")]
11        skip_docs: bool,
12
13        /// If set, do not include function bodies in the crate interface.
14        #[structopt(long = "skip-fn-bodies")]
15        skip_fn_bodies: bool,
16
17        /// If set, include test items (`#[cfg(test)]`) in the crate interface.
18        #[structopt(long = "include-test-items")]
19        include_test_items: bool,
20
21        /// If set, include private (non-pub) items in the crate interface.
22        #[structopt(long = "include-private-items")]
23        include_private_items: bool,
24
25        /// If set, the crate interface text is truncated if it exceeds this length.
26        #[structopt(long = "max-interface-length")]
27        max_interface_length: Option<usize>,
28
29        /// Path to the crate directory containing Cargo.toml
30        #[structopt(parse(from_os_str), long = "crate-path")]
31        crate_path: PathBuf,
32
33        /// If true, we write seeds (plant) but do not attempt to read expansions.
34        #[structopt(long = "plant")]
35        plant: bool,
36
37        /// Pass this to force re-writing an existing README
38        #[structopt(long = "force")]
39        force: bool,
40    },
41
42    /// Generate or update READMEs for multiple distinct crates
43    MultiCrate {
44        /// If set, do not include doc comments in the crate interface.
45        #[structopt(long = "skip-docs")]
46        skip_docs: bool,
47
48        /// If set, do not include function bodies in the crate interface.
49        #[structopt(long = "skip-fn-bodies")]
50        skip_fn_bodies: bool,
51
52        /// If set, include test items (`#[cfg(test)]`) in the crate interface.
53        #[structopt(long = "include-test-items")]
54        include_test_items: bool,
55
56        /// If set, include private (non-pub) items in the crate interface.
57        #[structopt(long = "include-private-items")]
58        include_private_items: bool,
59
60        /// If set, the crate interface text is truncated if it exceeds this length.
61        #[structopt(long = "max-interface-length")]
62        max_interface_length: Option<usize>,
63
64        /// Paths to the crate directories containing Cargo.toml
65        #[structopt(parse(from_os_str))]
66        crate_paths: Vec<PathBuf>,
67
68        /// If true, we write seeds (plant) but do not attempt to read expansions.
69        #[structopt(long = "plant")]
70        plant: bool,
71
72        /// Pass this to force re-writing an existing README
73        #[structopt(long = "force")]
74        force: bool,
75    },
76
77    /// Generate or update READMEs for an entire workspace
78    Workspace {
79        /// If set, do not include doc comments in the crate interface.
80        #[structopt(long = "skip-docs")]
81        skip_docs: bool,
82
83        /// If set, do not include function bodies in the crate interface.
84        #[structopt(long = "skip-fn-bodies")]
85        skip_fn_bodies: bool,
86
87        /// If set, include test items (`#[cfg(test)]`) in the crate interface.
88        #[structopt(long = "include-test-items")]
89        include_test_items: bool,
90
91        /// If set, include private (non-pub) items in the crate interface.
92        #[structopt(long = "include-private-items")]
93        include_private_items: bool,
94
95        /// If set, the crate interface text is truncated if it exceeds this length.
96        #[structopt(long = "max-interface-length")]
97        max_interface_length: Option<usize>,
98
99        /// Path to the workspace directory containing Cargo.toml(s)
100        #[structopt(parse(from_os_str), long = "workspace-path")]
101        workspace_path: PathBuf,
102
103        /// If true, we write seeds (plant) but do not attempt to read expansions.
104        #[structopt(long = "plant")]
105        plant: bool,
106
107        /// Pass this to force re-writing existing READMEs in the workspace
108        #[structopt(long = "force")]
109        force: bool,
110    },
111}
112
113impl ReadmeWriterCli {
114    /// Runs the readme-writer logic for whichever subcommand was chosen.
115    pub async fn run(&self) -> Result<(), WorkspaceError> {
116        match self {
117            Self::SingleCrate {
118                skip_docs,
119                skip_fn_bodies,
120                include_test_items,
121                include_private_items,
122                max_interface_length,
123                crate_path,
124                plant,
125                force,
126            } => {
127                // Build config from these fields:
128                let config = ReadmeWriterConfigBuilder::default()
129                    .skip_docs(*skip_docs)
130                    .skip_fn_bodies(*skip_fn_bodies)
131                    .include_test_items(*include_test_items)
132                    .include_private_items(*include_private_items)
133                    .max_interface_length(*max_interface_length)
134                    .build()
135                    .unwrap();
136
137                trace!(
138                    "SingleCrate => path={:?}, plant={}, force={}, config={:?}",
139                    crate_path, plant, force, config
140                );
141
142                let handle = Arc::new(AsyncMutex::new(
143                    CrateHandle::new(crate_path).await?
144                ));
145                UpdateReadmeFiles::update_readme_files(handle, *plant, *force, &config).await?;
146                info!("Done updating readme for single crate at {:?}", crate_path);
147            }
148
149            Self::MultiCrate {
150                skip_docs,
151                skip_fn_bodies,
152                include_test_items,
153                include_private_items,
154                max_interface_length,
155                crate_paths,
156                plant,
157                force,
158            } => {
159                let config = ReadmeWriterConfigBuilder::default()
160                    .skip_docs(*skip_docs)
161                    .skip_fn_bodies(*skip_fn_bodies)
162                    .include_test_items(*include_test_items)
163                    .include_private_items(*include_private_items)
164                    .max_interface_length(*max_interface_length)
165                    .build()
166                    .unwrap();
167
168                trace!(
169                    "MultiCrate => paths={:?}, plant={}, force={}, config={:?}",
170                    crate_paths, plant, force, config
171                );
172
173                for path in crate_paths {
174                    let handle = Arc::new(AsyncMutex::new(
175                        CrateHandle::new(path).await?
176                    ));
177                    UpdateReadmeFiles::update_readme_files(handle, *plant, *force, &config).await?;
178                    debug!("Finished readme updates for crate at {:?}", path);
179                }
180                info!("Done updating readmes for all crates in MultiCrate mode.");
181            }
182
183            Self::Workspace {
184                skip_docs,
185                skip_fn_bodies,
186                include_test_items,
187                include_private_items,
188                max_interface_length,
189                workspace_path,
190                plant,
191                force,
192            } => {
193                let config = ReadmeWriterConfigBuilder::default()
194                    .skip_docs(*skip_docs)
195                    .skip_fn_bodies(*skip_fn_bodies)
196                    .include_test_items(*include_test_items)
197                    .include_private_items(*include_private_items)
198                    .max_interface_length(*max_interface_length)
199                    .build()
200                    .unwrap();
201
202                trace!(
203                    "Workspace => path={:?}, plant={}, force={}, config={:?}",
204                    workspace_path, plant, force, config
205                );
206
207                let ws = Arc::new(AsyncMutex::new(
208                    Workspace::<PathBuf, CrateHandle>::new(workspace_path).await?
209                ));
210                UpdateReadmeFiles::update_readme_files(ws, *plant, *force, &config).await?;
211                info!("Done updating readmes for entire workspace at {:?}", workspace_path);
212            }
213        }
214
215        info!("All done with readme-writer-cli. Exiting successfully.");
216        Ok(())
217    }
218}