Skip to main content

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}