Skip to content

Commit 3401647

Browse files
committed
publish: Move feature name validation to validate_dependencies() fn
1 parent ddde0a8 commit 3401647

File tree

5 files changed

+12
-55
lines changed

5 files changed

+12
-55
lines changed

src/controllers/krate/publish.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,14 @@ pub fn validate_dependencies(deps: &[EncodableCrateDependency]) -> AppResult<()>
443443
)));
444444
}
445445

446+
for feature in &dep.features {
447+
if !Crate::valid_feature(feature) {
448+
return Err(cargo_err(&format_args!(
449+
"\"{feature}\" is an invalid feature name",
450+
)));
451+
}
452+
}
453+
446454
if let Some(registry) = &dep.registry {
447455
if !registry.is_empty() {
448456
return Err(cargo_err(&format_args!("Dependency `{}` is hosted on another registry. Cross-registry dependencies are not permitted on crates.io.", dep.name)));

src/tests/builders/dependency.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crates_io::views::krate_publish as u;
2-
use crates_io::views::krate_publish::EncodableFeature;
32

43
/// A builder for constructing a dependency of another crate.
54
pub struct DependencyBuilder {
@@ -53,17 +52,11 @@ impl DependencyBuilder {
5352
/// Consume this builder to create a `u::CrateDependency`. If the dependent crate doesn't
5453
/// already exist, publishing a crate with this dependency will fail.
5554
pub fn build(self) -> u::EncodableCrateDependency {
56-
let features = self
57-
.features
58-
.into_iter()
59-
.map(|d| EncodableFeature(d))
60-
.collect();
61-
6255
u::EncodableCrateDependency {
6356
name: self.name,
6457
optional: false,
6558
default_features: true,
66-
features,
59+
features: self.features,
6760
version_req: self.version_req,
6861
target: None,
6962
kind: None,

src/tests/builders/publish.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -236,17 +236,10 @@ fn convert_dependency(
236236
),
237237
};
238238

239-
let features = encoded
240-
.features
241-
.iter()
242-
.map(|f| f.to_string())
243-
.collect::<Vec<_>>()
244-
.none_or_filled();
245-
246239
let dependency = DependencyDetail {
247240
version: Some(encoded.version_req.to_string()),
248241
registry: encoded.registry.clone(),
249-
features,
242+
features: encoded.features.clone().none_or_filled(),
250243
optional: match encoded.optional {
251244
true => Some(true),
252245
false => None,

src/tests/krate/publish/snapshots/all__krate__publish__dependencies__invalid_feature_name.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ expression: response.into_json()
55
{
66
"errors": [
77
{
8-
"detail": "invalid upload request: invalid value: string \"🍺\", expected a valid feature name at line 1 column 111"
8+
"detail": "\"🍺\" is an invalid feature name"
99
}
1010
]
1111
}

src/views/krate_publish.rs

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
//! to and from structs. The serializing is only utilised in
44
//! integration tests.
55
6-
use diesel::pg::Pg;
7-
use diesel::serialize::{self, Output, ToSql};
8-
use diesel::sql_types::Text;
96
use serde::{de, Deserialize, Deserializer, Serialize};
107

118
use crate::models::krate::MAX_NAME_LENGTH;
@@ -27,7 +24,7 @@ pub struct EncodableCrateDependency {
2724
pub optional: bool,
2825
pub default_features: bool,
2926
pub name: String,
30-
pub features: Vec<EncodableFeature>,
27+
pub features: Vec<String>,
3128
pub version_req: EncodableCrateVersionReq,
3229
pub target: Option<String>,
3330
pub kind: Option<DependencyKind>,
@@ -73,28 +70,6 @@ impl<'de> Deserialize<'de> for EncodableDependencyName {
7370
}
7471
}
7572

76-
#[derive(Serialize, Clone, Debug, Deref)]
77-
pub struct EncodableFeature(pub String);
78-
79-
impl<'de> Deserialize<'de> for EncodableFeature {
80-
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<EncodableFeature, D::Error> {
81-
let s = String::deserialize(d)?;
82-
if !Crate::valid_feature(&s) {
83-
let value = de::Unexpected::Str(&s);
84-
let expected = "a valid feature name";
85-
Err(de::Error::invalid_value(value, &expected))
86-
} else {
87-
Ok(EncodableFeature(s))
88-
}
89-
}
90-
}
91-
92-
impl ToSql<Text, Pg> for EncodableFeature {
93-
fn to_sql(&self, out: &mut Output<'_, '_, Pg>) -> serialize::Result {
94-
ToSql::<Text, Pg>::to_sql(&**self, &mut out.reborrow())
95-
}
96-
}
97-
9873
#[derive(Serialize, Debug, Deref)]
9974
pub struct EncodableCrateVersion(pub semver::Version);
10075

@@ -128,15 +103,3 @@ impl<'de> Deserialize<'de> for EncodableCrateVersionReq {
128103
}
129104
}
130105
}
131-
132-
#[test]
133-
fn feature_deserializes_for_valid_features() {
134-
use serde_json as json;
135-
136-
assert_ok!(json::from_str::<EncodableFeature>("\"foo\""));
137-
assert_err!(json::from_str::<EncodableFeature>("\"\""));
138-
assert_err!(json::from_str::<EncodableFeature>("\"/\""));
139-
assert_err!(json::from_str::<EncodableFeature>("\"%/%\""));
140-
assert_ok!(json::from_str::<EncodableFeature>("\"a/a\""));
141-
assert_ok!(json::from_str::<EncodableFeature>("\"32-column-tables\""));
142-
}

0 commit comments

Comments
 (0)