Skip to content

Commit 56a587e

Browse files
committed
feat(complete): Added completion for --profile
- Added completion for `--profile` in `cargo build` - Loads the built in profile and custom profiles present in `Cargo.toml` and `.cargo/config.toml`
1 parent bc577dc commit 56a587e

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

src/cargo/core/profiles.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,11 @@ impl Profiles {
391391
.get(name)
392392
.ok_or_else(|| anyhow::format_err!("profile `{}` is not defined", name))
393393
}
394+
395+
/// Returns an iterator over all profile names known to Cargo.
396+
pub fn profile_names(&self) -> impl Iterator<Item = InternedString> + '_ {
397+
self.by_name.keys().copied()
398+
}
394399
}
395400

396401
/// An object used for handling the profile hierarchy.

src/cargo/util/command_prelude.rs

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::core::compiler::{
22
BuildConfig, CompileKind, MessageFormat, RustcTargetData, TimingOutput,
33
};
44
use crate::core::resolver::{CliFeatures, ForceAllTargets, HasDevUnits};
5-
use crate::core::{shell, Edition, Package, Target, TargetKind, Workspace};
5+
use crate::core::{profiles::Profiles, shell, Edition, Package, Target, TargetKind, Workspace};
66
use crate::ops::lockfile::LOCKFILE_NAME;
77
use crate::ops::registry::RegistryOrIndex;
88
use crate::ops::{self, CompileFilter, CompileOptions, NewOptions, Packages, VersionControl};
@@ -274,7 +274,11 @@ pub trait CommandExt: Sized {
274274
self._arg(
275275
opt("profile", profile)
276276
.value_name("PROFILE-NAME")
277-
.help_heading(heading::COMPILATION_OPTIONS),
277+
.help_heading(heading::COMPILATION_OPTIONS)
278+
.add(clap_complete::ArgValueCandidates::new(|| {
279+
let candidates = get_profile_candidates();
280+
candidates.unwrap_or_default()
281+
})),
278282
)
279283
}
280284

@@ -1106,6 +1110,53 @@ pub fn get_registry_candidates() -> CargoResult<Vec<clap_complete::CompletionCan
11061110
}
11071111
}
11081112

1113+
fn get_profile_candidates() -> Vec<clap_complete::CompletionCandidate> {
1114+
match get_workspace_profile_candidates() {
1115+
Ok(candidates) if !candidates.is_empty() => candidates,
1116+
// fallback to default profile candidates
1117+
_ => default_profile_candidates(),
1118+
}
1119+
}
1120+
1121+
fn get_workspace_profile_candidates() -> CargoResult<Vec<clap_complete::CompletionCandidate>> {
1122+
let gctx = new_gctx_for_completions()?;
1123+
let ws = Workspace::new(&find_root_manifest_for_wd(gctx.cwd())?, &gctx)?;
1124+
let profiles = Profiles::new(&ws, InternedString::new("dev"))?;
1125+
1126+
let mut candidates = Vec::new();
1127+
for name in profiles.profile_names() {
1128+
let Ok(profile_instance) = Profiles::new(&ws, name) else {
1129+
continue;
1130+
};
1131+
let base_profile = profile_instance.base_profile();
1132+
1133+
let mut description = String::from(if base_profile.opt_level.as_str() == "0" {
1134+
"unoptimized"
1135+
} else {
1136+
"optimized"
1137+
});
1138+
1139+
if base_profile.debuginfo.is_turned_on() {
1140+
description.push_str(" + debuginfo");
1141+
}
1142+
1143+
candidates
1144+
.push(clap_complete::CompletionCandidate::new(&name).help(Some(description.into())));
1145+
}
1146+
1147+
Ok(candidates)
1148+
}
1149+
1150+
fn default_profile_candidates() -> Vec<clap_complete::CompletionCandidate> {
1151+
vec![
1152+
clap_complete::CompletionCandidate::new("dev").help(Some("unoptimized + debuginfo".into())),
1153+
clap_complete::CompletionCandidate::new("release").help(Some("optimized".into())),
1154+
clap_complete::CompletionCandidate::new("test")
1155+
.help(Some("unoptimized + debuginfo".into())),
1156+
clap_complete::CompletionCandidate::new("bench").help(Some("optimized".into())),
1157+
]
1158+
}
1159+
11091160
fn get_example_candidates() -> Vec<clap_complete::CompletionCandidate> {
11101161
get_targets_from_metadata()
11111162
.unwrap_or_default()

0 commit comments

Comments
 (0)