Skip to content

Commit b615137

Browse files
committed
feat: Collect features from all workspaces
1 parent 3138b5d commit b615137

File tree

1 file changed

+11
-33
lines changed

1 file changed

+11
-33
lines changed

src/cargo/util/command_prelude.rs

+11-33
Original file line numberDiff line numberDiff line change
@@ -1124,63 +1124,41 @@ fn get_feature_candidates() -> CargoResult<Vec<clap_complete::CompletionCandidat
11241124
Err(_) => return Ok(Vec::new()),
11251125
};
11261126

1127-
let current_dir = std::env::current_dir()?;
1128-
1129-
let current_pkg = ws
1130-
.members()
1131-
.find(|pkg| current_dir.starts_with(pkg.root()))
1132-
.or_else(|| ws.members().next())
1133-
.cloned();
1134-
11351127
let mut features = HashSet::new();
11361128

1137-
if let Some(package) = current_pkg {
1129+
// Process all packages in the workspace, collect features from all packages since --package could be used to select any of them
1130+
for package in ws.members() {
11381131
for feature_name in package.summary().features().keys() {
11391132
features.insert(feature_name.as_str().to_string());
11401133
}
11411134

1135+
// Add optional dependencies as they can be enabled as features, these might not be in the features map if they are not explicitly referenced
11421136
for dep in package.dependencies() {
11431137
if dep.is_optional() {
11441138
features.insert(dep.name_in_toml().to_string());
11451139
}
11461140
}
11471141

1148-
let mut package_features = std::collections::HashMap::new();
1149-
1150-
for pkg in ws.members() {
1151-
let pkg_name = pkg.name().as_str().to_string();
1152-
let pkg_features: Vec<String> = pkg
1153-
.summary()
1154-
.features()
1155-
.keys()
1156-
.map(|k| k.as_str().to_string())
1157-
.collect();
1158-
1159-
package_features.insert(pkg_name, pkg_features);
1160-
}
1161-
1142+
// Add qualified features for dependencies
11621143
for dep in package.dependencies() {
11631144
let dep_name = dep.package_name().as_str().to_string();
11641145

1165-
if let Some(dep_features) = package_features.get(&dep_name) {
1166-
for feat in dep_features {
1146+
// try to find this dependency in the workspace
1147+
if let Some(dep_pkg) = ws.members().find(|p| p.name().as_str() == dep_name) {
1148+
for feat in dep_pkg.summary().features().keys() {
11671149
features.insert(format!("{}/{}", dep_name, feat));
11681150
}
11691151
}
11701152
}
1171-
} else {
1172-
// If we couldn't determine the current package, collect features from all workspace members
1173-
for pkg in ws.members() {
1174-
for feature_name in pkg.summary().features().keys() {
1175-
features.insert(feature_name.as_str().to_string());
1176-
}
1177-
}
11781153
}
11791154

11801155
// always include the default feature
11811156
features.insert("default".to_string());
11821157

1183-
Ok(features
1158+
let mut sorted_features: Vec<_> = features.into_iter().collect();
1159+
sorted_features.sort();
1160+
1161+
Ok(sorted_features
11841162
.into_iter()
11851163
.map(|name| clap_complete::CompletionCandidate::new(name))
11861164
.collect())

0 commit comments

Comments
 (0)