Skip to content

Commit b65fec0

Browse files
committed
features: Differ optional dependencies and features
Store in database if feature comes from optional dependency. At the same time resolve rename as optional dependency might use same package multiple times under different name.
1 parent 6a81b64 commit b65fec0

File tree

6 files changed

+56
-19
lines changed

6 files changed

+56
-19
lines changed

src/db/add_package.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,19 @@ fn convert_dependencies(pkg: &MetadataPackage) -> Vec<(String, String, String)>
221221
fn get_features(pkg: &MetadataPackage) -> Vec<Feature> {
222222
let mut features = Vec::with_capacity(pkg.features.len());
223223
if let Some(subfeatures) = pkg.features.get("default") {
224-
features.push(Feature::new("default".into(), subfeatures.clone()));
224+
features.push(Feature::new(
225+
"default".into(),
226+
subfeatures.clone(),
227+
Some(false),
228+
));
225229
};
226230
features.extend(
227231
pkg.features
228232
.iter()
229233
.filter(|(name, _)| *name != "default")
230-
.map(|(name, subfeatures)| Feature::new(name.clone(), subfeatures.clone())),
234+
.map(|(name, subfeatures)| {
235+
Feature::new(name.clone(), subfeatures.clone(), Some(false))
236+
}),
231237
);
232238
features.extend(get_optional_dependencies(pkg));
233239
features
@@ -237,7 +243,14 @@ fn get_optional_dependencies(pkg: &MetadataPackage) -> Vec<Feature> {
237243
pkg.dependencies
238244
.iter()
239245
.filter(|dep| dep.optional)
240-
.map(|dep| Feature::new(dep.name.clone(), Vec::new()))
246+
.map(|dep| {
247+
let name = if let Some(rename) = &dep.rename {
248+
rename.clone()
249+
} else {
250+
dep.name.clone()
251+
};
252+
Feature::new(name, Vec::new(), Some(true))
253+
})
241254
.collect()
242255
}
243256

src/db/migrate.rs

+14
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,20 @@ pub fn migrate(version: Option<Version>, conn: &mut Client) -> CratesfyiResult<(
488488
"
489489
ALTER TABLE queue DROP COLUMN registry;
490490
"
491+
),
492+
migration!(
493+
context,
494+
21,
495+
// description
496+
"Add mark for features that are derived from optional dependencies",
497+
// upgrade query
498+
"
499+
ALTER TYPE feature ADD ATTRIBUTE optional_dependency BOOL;
500+
",
501+
// downgrade query
502+
"
503+
ALTER TYPE feature DROP ATTRIBUTE optional_dependency;
504+
"
491505
)
492506
];
493507

src/db/types.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@ use serde::Serialize;
66
pub struct Feature {
77
pub(crate) name: String,
88
pub(crate) subfeatures: Vec<String>,
9+
pub(crate) optional_dependency: Option<bool>,
910
}
1011

1112
impl Feature {
12-
pub fn new(name: String, subfeatures: Vec<String>) -> Self {
13-
Feature { name, subfeatures }
13+
pub fn new(name: String, subfeatures: Vec<String>, optional_dependency: Option<bool>) -> Self {
14+
Feature {
15+
name,
16+
subfeatures,
17+
optional_dependency,
18+
}
1419
}
1520

1621
pub fn is_private(&self) -> bool {

src/test/fakes.rs

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ impl<'a> FakeRelease<'a> {
4949
name: "fake-dependency".into(),
5050
req: "^1.0.0".into(),
5151
kind: None,
52+
rename: None,
5253
optional: false,
5354
}],
5455
targets: vec![Target::dummy_lib("fake_package".into(), None)],

src/utils/cargo_metadata.rs

+1
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ pub(crate) struct Dependency {
132132
pub(crate) name: String,
133133
pub(crate) req: String,
134134
pub(crate) kind: Option<String>,
135+
pub(crate) rename: Option<String>,
135136
pub(crate) optional: bool,
136137
}
137138

src/web/features.rs

+17-14
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ mod tests {
107107

108108
#[test]
109109
fn test_feature_map_filters_private() {
110-
let private1 = Feature::new("_private1".into(), vec!["feature1".into()]);
111-
let feature2 = Feature::new("feature2".into(), Vec::new());
110+
let private1 = Feature::new("_private1".into(), vec!["feature1".into()], Some(false));
111+
let feature2 = Feature::new("feature2".into(), Vec::new(), Some(false));
112112

113113
let raw = vec![private1.clone(), feature2.clone()];
114114
let feature_map = get_feature_map(raw);
@@ -120,14 +120,15 @@ mod tests {
120120

121121
#[test]
122122
fn test_default_tree_structure_with_nested_default() {
123-
let default = Feature::new(DEFAULT_NAME.into(), vec!["feature1".into()]);
124-
let non_default = Feature::new("non-default".into(), Vec::new());
123+
let default = Feature::new(DEFAULT_NAME.into(), vec!["feature1".into()], Some(false));
124+
let non_default = Feature::new("non-default".into(), Vec::new(), Some(false));
125125
let feature1 = Feature::new(
126126
"feature1".into(),
127127
vec!["feature2".into(), "feature3".into()],
128+
Some(false),
128129
);
129-
let feature2 = Feature::new("feature2".into(), Vec::new());
130-
let feature3 = Feature::new("feature3".into(), Vec::new());
130+
let feature2 = Feature::new("feature2".into(), Vec::new(), Some(false));
131+
let feature3 = Feature::new("feature3".into(), Vec::new(), Some(false));
131132

132133
let raw = vec![
133134
default.clone(),
@@ -154,9 +155,10 @@ mod tests {
154155
let feature1 = Feature::new(
155156
"feature1".into(),
156157
vec!["feature2".into(), "feature3".into()],
158+
Some(false),
157159
);
158-
let feature2 = Feature::new("feature2".into(), Vec::new());
159-
let feature3 = Feature::new("feature3".into(), Vec::new());
160+
let feature2 = Feature::new("feature2".into(), Vec::new(), Some(false));
161+
let feature3 = Feature::new("feature3".into(), Vec::new(), Some(false));
160162

161163
let raw = vec![feature3.clone(), feature2.clone(), feature1.clone()];
162164
let mut feature_map = get_feature_map(raw);
@@ -171,8 +173,8 @@ mod tests {
171173

172174
#[test]
173175
fn test_default_tree_structure_single_default() {
174-
let default = Feature::new(DEFAULT_NAME.into(), Vec::new());
175-
let non_default = Feature::new("non-default".into(), Vec::new());
176+
let default = Feature::new(DEFAULT_NAME.into(), Vec::new(), Some(false));
177+
let non_default = Feature::new("non-default".into(), Vec::new(), Some(false));
176178

177179
let raw = vec![default.clone(), non_default.clone()];
178180
let mut feature_map = get_feature_map(raw);
@@ -190,9 +192,10 @@ mod tests {
190192
let feature1 = Feature::new(
191193
"feature1".into(),
192194
vec!["feature10".into(), "feature11".into()],
195+
Some(false),
193196
);
194-
let feature2 = Feature::new("feature2".into(), vec!["feature20".into()]);
195-
let feature3 = Feature::new("feature3".into(), Vec::new());
197+
let feature2 = Feature::new("feature2".into(), vec!["feature20".into()], Some(false));
198+
let feature3 = Feature::new("feature3".into(), Vec::new(), Some(false));
196199

197200
let raw = vec![feature3.clone(), feature2.clone(), feature1.clone()];
198201
let (features, default_len) = order_features_and_count_default_len(raw);
@@ -206,8 +209,8 @@ mod tests {
206209

207210
#[test]
208211
fn test_order_features_and_get_len_single_default() {
209-
let default = Feature::new(DEFAULT_NAME.into(), Vec::new());
210-
let non_default = Feature::new("non-default".into(), Vec::new());
212+
let default = Feature::new(DEFAULT_NAME.into(), Vec::new(), Some(false));
213+
let non_default = Feature::new("non-default".into(), Vec::new(), Some(false));
211214

212215
let raw = vec![default.clone(), non_default.clone()];
213216
let (features, default_len) = order_features_and_count_default_len(raw);

0 commit comments

Comments
 (0)