cargo_samply/cli.rs
1//! Command-line interface configuration for cargo-samply.
2//!
3//! This module defines the CLI structure using `clap` with support for both
4//! direct execution (`cargo-samply`) and cargo subcommand usage (`cargo samply`).
5//!
6//! # Examples
7//!
8//! ```no_run
9//! use cargo_samply::cli::{CargoCli, Config};
10//! use clap::Parser;
11//!
12//! // Parse command-line arguments
13//! let CargoCli::Samply(config) = CargoCli::parse();
14//! println!("Profile: {}", config.profile);
15//! ```
16
17use clap::Parser;
18
19/// The main cargo CLI enum that wraps the samply subcommand.
20///
21/// This enum is designed to work with cargo's subcommand protocol,
22/// allowing the tool to be called as both `cargo samply` and `cargo-samply`.
23#[derive(Parser)] // requires `derive` feature
24#[command(name = "cargo")]
25#[command(bin_name = "cargo")]
26#[command(styles = CLAP_STYLING)]
27pub enum CargoCli {
28 /// The samply subcommand
29 Samply(Config),
30}
31
32// See also `clap_cargo::style::CLAP_STYLING`
33pub const CLAP_STYLING: clap::builder::styling::Styles = clap::builder::styling::Styles::styled()
34 .header(clap_cargo::style::HEADER)
35 .usage(clap_cargo::style::USAGE)
36 .literal(clap_cargo::style::LITERAL)
37 .placeholder(clap_cargo::style::PLACEHOLDER)
38 .error(clap_cargo::style::ERROR)
39 .valid(clap_cargo::style::VALID)
40 .invalid(clap_cargo::style::INVALID);
41
42/// Configuration structure for the cargo-samply command.
43///
44/// This struct contains all the command-line options and arguments
45/// that can be passed to cargo-samply.
46///
47/// # Examples
48///
49/// ```no_run
50/// use cargo_samply::cli::Config;
51///
52/// let config = Config {
53/// args: vec!["--help".to_string()],
54/// profile: "samply".to_string(),
55/// package: None,
56/// bin: Some("my-binary".to_string()),
57/// example: None,
58/// bench: None,
59/// test: None,
60/// features: vec!["feature1".to_string(), "feature2".to_string()],
61/// no_default_features: false,
62/// verbose: false,
63/// quiet: false,
64/// no_samply: false,
65/// dry_run: false,
66/// no_profile_inject: false,
67/// bench_flag: "--bench".to_string(),
68/// samply_args: None,
69/// list_targets: false,
70/// };
71/// ```
72#[derive(clap::Args)]
73#[command(author, version, about, long_about = None)]
74pub struct Config {
75 /// Trailing arguments passed to the binary being profiled
76 #[arg(name = "TRAILING_ARGUMENTS")]
77 pub args: Vec<String>,
78
79 /// Build with the specified profile
80 #[arg(long, default_value = "samply")]
81 pub profile: String,
82
83 /// Package to profile (in a workspace)
84 #[arg(short = 'p', long)]
85 pub package: Option<String>,
86
87 /// Binary to run
88 #[arg(short, long)]
89 pub bin: Option<String>,
90
91 /// Example to run
92 #[arg(short, long)]
93 pub example: Option<String>,
94
95 /// Benchmark target to run (e.g. `cargo samply --bench throughput`)
96 #[arg(long)]
97 pub bench: Option<String>,
98
99 /// Test target to run (e.g. `cargo samply --test integration_test`)
100 #[arg(long)]
101 pub test: Option<String>,
102
103 /// The flag to use when running the benchmark target
104 #[arg(long, default_value = "--bench")]
105 pub bench_flag: String,
106
107 /// Arguments to pass to samply (e.g. `--samply-args="--rate 2000"`).
108 /// Use `=` so the full string is parsed as the value of `--samply-args`,
109 /// even when it starts with `--`.
110 #[arg(long)]
111 pub samply_args: Option<String>,
112
113 /// Build features to enable
114 #[arg(short, long)]
115 pub features: Vec<String>,
116
117 /// Disable default features
118 #[arg(long)]
119 pub no_default_features: bool,
120
121 /// Print extra output to help debug problems
122 #[arg(short, long, default_value_t = false)]
123 pub verbose: bool,
124
125 /// Suppress all output except errors
126 #[arg(short, long, default_value_t = false)]
127 pub quiet: bool,
128
129 /// Disable the automatic samply start
130 #[arg(short, long, default_value_t = false)]
131 pub no_samply: bool,
132
133 /// Print the build and run commands without executing them
134 #[arg(long, default_value_t = false)]
135 pub dry_run: bool,
136
137 /// Do not modify Cargo.toml to add the samply profile
138 #[arg(long, default_value_t = false)]
139 pub no_profile_inject: bool,
140
141 /// List all available targets in the workspace and exit
142 #[arg(long, default_value_t = false)]
143 pub list_targets: bool,
144}