cli_xtask/
subcommand.rs

1//! Command line interfaces for xtask workflows.
2use crate::{config::Config, Result, Run};
3
4#[cfg(feature = "subcommand-build")]
5#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-build")))]
6mod build;
7#[cfg(feature = "subcommand-build")]
8#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-build")))]
9pub use self::build::Build;
10
11#[cfg(feature = "subcommand-clippy")]
12#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-clippy")))]
13mod clippy;
14#[cfg(feature = "subcommand-clippy")]
15#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-clippy")))]
16pub use self::clippy::Clippy;
17
18#[cfg(feature = "subcommand-dist-archive")]
19#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-archive")))]
20mod dist_archive;
21#[cfg(feature = "subcommand-dist-archive")]
22#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-archive")))]
23pub use self::dist_archive::DistArchive;
24
25#[cfg(subcommand_dist_build)]
26#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-*")))]
27mod dist_build;
28#[cfg(subcommand_dist_build)]
29#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-*")))]
30pub use self::dist_build::DistBuild;
31
32#[cfg(feature = "subcommand-dist-build-bin")]
33#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-bin")))]
34mod dist_build_bin;
35#[cfg(feature = "subcommand-dist-build-bin")]
36#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-bin")))]
37pub use self::dist_build_bin::DistBuildBin;
38
39#[cfg(feature = "subcommand-dist-build-completion")]
40#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-completion")))]
41mod dist_build_completion;
42#[cfg(feature = "subcommand-dist-build-completion")]
43#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-completion")))]
44pub use self::dist_build_completion::DistBuildCompletion;
45
46#[cfg(feature = "subcommand-dist-build-doc")]
47#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-doc")))]
48mod dist_build_doc;
49#[cfg(feature = "subcommand-dist-build-doc")]
50#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-doc")))]
51pub use self::dist_build_doc::DistBuildDoc;
52
53#[cfg(feature = "subcommand-dist-build-license")]
54#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-license")))]
55mod dist_build_license;
56#[cfg(feature = "subcommand-dist-build-license")]
57#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-license")))]
58pub use self::dist_build_license::DistBuildLicense;
59
60#[cfg(feature = "subcommand-dist-build-man")]
61#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-man")))]
62mod dist_build_man;
63#[cfg(feature = "subcommand-dist-build-man")]
64#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-man")))]
65pub use self::dist_build_man::DistBuildMan;
66
67#[cfg(feature = "subcommand-dist-build-readme")]
68#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-readme")))]
69mod dist_build_readme;
70#[cfg(feature = "subcommand-dist-build-readme")]
71#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-readme")))]
72pub use self::dist_build_readme::DistBuildReadme;
73
74#[cfg(feature = "subcommand-dist-clean")]
75#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-clean")))]
76mod dist_clean;
77#[cfg(feature = "subcommand-dist-clean")]
78#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-clean")))]
79pub use self::dist_clean::DistClean;
80
81#[cfg(feature = "subcommand-dist")]
82#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist")))]
83mod dist;
84#[cfg(feature = "subcommand-dist")]
85#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist")))]
86pub use self::dist::Dist;
87
88#[cfg(feature = "subcommand-exec")]
89#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-exec")))]
90mod exec;
91#[cfg(feature = "subcommand-exec")]
92#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-exec")))]
93pub use self::exec::Exec;
94
95#[cfg(feature = "subcommand-doc")]
96#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-doc")))]
97mod doc;
98#[cfg(feature = "subcommand-doc")]
99#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-doc")))]
100pub use self::doc::Doc;
101
102#[cfg(feature = "subcommand-docsrs")]
103#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-docsrs")))]
104mod docsrs;
105#[cfg(feature = "subcommand-docsrs")]
106#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-docsrs")))]
107pub use self::docsrs::Docsrs;
108
109#[cfg(feature = "subcommand-fmt")]
110#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-fmt")))]
111mod fmt;
112#[cfg(feature = "subcommand-fmt")]
113#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-fmt")))]
114pub use self::fmt::Fmt;
115
116#[cfg(feature = "subcommand-lint")]
117#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-lint")))]
118mod lint;
119#[cfg(feature = "subcommand-lint")]
120#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-lint")))]
121pub use self::lint::Lint;
122
123#[cfg(feature = "subcommand-pre-release")]
124#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-pre-release")))]
125mod pre_release;
126#[cfg(feature = "subcommand-pre-release")]
127#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-pre-release")))]
128pub use self::pre_release::PreRelease;
129
130#[cfg(feature = "subcommand-sync-rdme")]
131#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-sync-rdme")))]
132mod sync_rdme;
133#[cfg(feature = "subcommand-sync-rdme")]
134#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-sync-rdme")))]
135pub use self::sync_rdme::SyncRdme;
136
137#[cfg(feature = "subcommand-test")]
138#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-test")))]
139mod test;
140#[cfg(feature = "subcommand-test")]
141#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-test")))]
142pub use self::test::Test;
143
144#[cfg(feature = "subcommand-tidy")]
145#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-tidy")))]
146mod tidy;
147#[cfg(feature = "subcommand-tidy")]
148#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-tidy")))]
149pub use self::tidy::Tidy;
150
151#[cfg(feature = "subcommand-udeps")]
152#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-udeps")))]
153mod udeps;
154#[cfg(feature = "subcommand-udeps")]
155#[cfg_attr(docsrs, doc(cfg(feature = "subcommand-udeps")))]
156pub use self::udeps::Udeps;
157
158/// Subcommand definition for cargo xtask command.
159#[cfg_attr(doc, doc = include_str!("../doc/cargo-xtask.md"))]
160///
161/// # Examples
162///
163/// You can use this struct to define a subcommand of your application:
164///
165/// ```rust
166/// use cli_xtask::{clap, config::Config, subcommand::Subcommand, Result};
167///
168/// #[derive(Debug, clap::Parser)]
169/// struct App {
170///     #[clap(subcommand)]
171///     subcommand: Subcommand,
172/// }
173///
174/// impl App {
175///     pub fn run(&self, config: &Config) -> Result<()> {
176///         self.subcommand.run(config)
177///     }
178/// }
179/// ```
180///
181/// You can mix the subcommands defined in this enum with your own subcommands:
182///
183/// ```rust
184/// use cli_xtask::{clap, config::Config, Result};
185///
186/// #[derive(Debug, clap::Parser)]
187/// struct App {
188///     #[clap(subcommand)]
189///     subcommand: YourOwnSubcommand,
190/// }
191///
192/// #[derive(Debug, clap::Subcommand)]
193/// enum YourOwnSubcommand {
194///     #[clap(flatten)]
195///     Predefined(cli_xtask::subcommand::Subcommand),
196///     Foo,
197///     Bar,
198/// }
199/// ```
200#[derive(Debug, clap::Subcommand)]
201#[clap(bin_name = "cargo xtask", about = "Rust project automation command", long_about = None)]
202#[non_exhaustive]
203pub enum Subcommand {
204    /// `cargo build` with options useful for testing and continuous
205    /// integration.
206    #[cfg(feature = "subcommand-build")]
207    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-build")))]
208    Build(Build),
209
210    /// `cargo clippy` with options useful for tesing and continuous
211    /// integration.
212    #[cfg(feature = "subcommand-clippy")]
213    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-clippy")))]
214    Clippy(Clippy),
215
216    /// Build the artifacs and create the archive file for distribution.
217    #[cfg(feature = "subcommand-dist")]
218    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist")))]
219    Dist(Dist),
220
221    /// Create the archive file for distribution.
222    #[cfg(feature = "subcommand-dist-archive")]
223    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-archive")))]
224    DistArchive(DistArchive),
225
226    /// Build all artifacts for distribution.
227    #[cfg(subcommand_dist_build)]
228    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-*")))]
229    DistBuild(DistBuild),
230
231    /// Build the release binaries for distribution.
232    #[cfg(feature = "subcommand-dist-build-bin")]
233    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-bin")))]
234    DistBuildBin(DistBuildBin),
235
236    /// Build the shell completion files for distribution.
237    #[cfg(feature = "subcommand-dist-build-completion")]
238    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-completion")))]
239    DistBuildCompletion(DistBuildCompletion),
240
241    /// Build the documentation for distribution.
242    #[cfg(feature = "subcommand-dist-build-doc")]
243    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-doc")))]
244    DistBuildDoc(DistBuildDoc),
245
246    /// Build the license files for distribution.
247    #[cfg(feature = "subcommand-dist-build-license")]
248    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-license")))]
249    DistBuildLicense(DistBuildLicense),
250
251    /// Build the man pages for distribution.
252    #[cfg(feature = "subcommand-dist-build-man")]
253    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-man")))]
254    DistBuildMan(DistBuildMan),
255
256    /// Build the readme files for distribution.
257    #[cfg(feature = "subcommand-dist-build-readme")]
258    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-build-readme")))]
259    DistBuildReadme(DistBuildReadme),
260
261    /// Remove the artifacts and archives for distribution.
262    #[cfg(feature = "subcommand-dist-clean")]
263    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-dist-clean")))]
264    DistClean(DistClean),
265
266    /// `cargo doc` with options useful for testing and continuous integration.
267    #[cfg(feature = "subcommand-doc")]
268    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-doc")))]
269    Doc(Doc),
270
271    /// `cargo doc` with docs.rs specific options.
272    #[cfg(feature = "subcommand-docsrs")]
273    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-docsrs")))]
274    Docsrs(Docsrs),
275
276    /// Run commands on all workspaces in the current directory and
277    /// subdirectories.
278    #[cfg(feature = "subcommand-exec")]
279    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-exec")))]
280    Exec(Exec),
281
282    /// `cargo fmt` with options useful for testing and continuous integration.
283    #[cfg(feature = "subcommand-fmt")]
284    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-fmt")))]
285    Fmt(Fmt),
286
287    /// Run lint commands at once.
288    #[cfg(feature = "subcommand-lint")]
289    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-lint")))]
290    Lint(Lint),
291
292    /// Run pre-release checks.
293    #[cfg(feature = "subcommand-pre-release")]
294    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-pre-release")))]
295    PreRelease(PreRelease),
296
297    /// `cargo sync-rdme` with options useful for testing and continuous
298    /// integration.
299    #[cfg(feature = "subcommand-sync-rdme")]
300    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-syncrdme")))]
301    SyncRdme(sync_rdme::SyncRdme),
302
303    /// `cargo test` with options useful for testing and continuous integration.
304    #[cfg(feature = "subcommand-test")]
305    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-test")))]
306    Test(Test),
307
308    /// Fix the package problems.
309    #[cfg(feature = "subcommand-tidy")]
310    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-tidy")))]
311    Tidy(Tidy),
312
313    /// `cargo udeps` with options useful for testing and continuous
314    /// integration.
315    #[cfg(feature = "subcommand-udeps")]
316    #[cfg_attr(docsrs, doc(cfg(feature = "subcommand-udeps")))]
317    Udeps(Udeps),
318}
319
320impl Run for Subcommand {
321    fn run(&self, config: &Config) -> Result<()> {
322        self.run(config)
323    }
324}
325
326impl Subcommand {
327    /// Returns the selected subcommand.
328    pub fn selected(&self) -> &dyn Run {
329        match self {
330            #[cfg(feature = "subcommand-build")]
331            Self::Build(args) => args,
332
333            #[cfg(feature = "subcommand-clippy")]
334            Self::Clippy(args) => args,
335
336            #[cfg(feature = "subcommand-dist")]
337            Self::Dist(args) => args,
338
339            #[cfg(feature = "subcommand-dist-archive")]
340            Self::DistArchive(args) => args,
341
342            #[cfg(subcommand_dist_build)]
343            Self::DistBuild(args) => args,
344
345            #[cfg(feature = "subcommand-dist-build-bin")]
346            Self::DistBuildBin(args) => args,
347
348            #[cfg(feature = "subcommand-dist-build-completion")]
349            Self::DistBuildCompletion(args) => args,
350
351            #[cfg(feature = "subcommand-dist-build-doc")]
352            Self::DistBuildDoc(args) => args,
353
354            #[cfg(feature = "subcommand-dist-build-license")]
355            Self::DistBuildLicense(args) => args,
356
357            #[cfg(feature = "subcommand-dist-build-man")]
358            Self::DistBuildMan(args) => args,
359
360            #[cfg(feature = "subcommand-dist-build-readme")]
361            Self::DistBuildReadme(args) => args,
362
363            #[cfg(feature = "subcommand-dist-clean")]
364            Self::DistClean(args) => args,
365
366            #[cfg(feature = "subcommand-doc")]
367            Self::Doc(args) => args,
368
369            #[cfg(feature = "subcommand-docsrs")]
370            Self::Docsrs(args) => args,
371
372            #[cfg(feature = "subcommand-exec")]
373            Self::Exec(args) => args,
374
375            #[cfg(feature = "subcommand-fmt")]
376            Self::Fmt(args) => args,
377
378            #[cfg(feature = "subcommand-lint")]
379            Self::Lint(args) => args,
380
381            #[cfg(feature = "subcommand-pre-release")]
382            Self::PreRelease(args) => args,
383
384            #[cfg(feature = "subcommand-sync-rdme")]
385            Self::SyncRdme(args) => args,
386
387            #[cfg(feature = "subcommand-test")]
388            Self::Test(args) => args,
389
390            #[cfg(feature = "subcommand-tidy")]
391            Self::Tidy(args) => args,
392
393            #[cfg(feature = "subcommand-udeps")]
394            Self::Udeps(args) => args,
395
396            #[cfg(not(subcommand))]
397            _ => unreachable!("no commands defined: {self:?}"),
398        }
399    }
400
401    /// Runs the subcommand specified by the command line arguments.
402    pub fn run(&self, config: &Config) -> Result<()> {
403        self.selected().run(config)
404    }
405}