Skip to content

Commit b96ed5c

Browse files
authored
publish: Read keywords metadata from embedded Cargo.toml file (#7214)
... instead of the metadata JSON blob
1 parent 408545c commit b96ed5c

7 files changed

+24
-52
lines changed

src/controllers/krate/publish.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,25 @@ pub async fn publish(app: AppState, req: BytesRequest) -> AppResult<Json<GoodCra
157157
validate_url(documentation.as_deref(), "documentation")?;
158158
validate_url(repository.as_deref(), "repository")?;
159159

160+
let keywords = package
161+
.keywords
162+
.map(|it| it.as_local().unwrap())
163+
.unwrap_or_default();
164+
165+
if keywords.len() > 5 {
166+
return Err(cargo_err("expected at most 5 keywords per crate"));
167+
}
168+
169+
for keyword in keywords.iter() {
170+
if keyword.len() > 20 {
171+
return Err(cargo_err(&format!(
172+
"\"{keyword}\" is an invalid keyword (keywords must have less than 20 characters)"
173+
)));
174+
} else if !Keyword::valid_name(keyword) {
175+
return Err(cargo_err(&format!("\"{keyword}\" is an invalid keyword")));
176+
}
177+
}
178+
160179
let categories = package
161180
.categories
162181
.map(|it| it.as_local().unwrap())
@@ -176,11 +195,7 @@ pub async fn publish(app: AppState, req: BytesRequest) -> AppResult<Json<GoodCra
176195
.into_iter()
177196
.map(|(k, v)| (k.0, v.into_iter().map(|v| v.0).collect()))
178197
.collect();
179-
let keywords = metadata
180-
.keywords
181-
.iter()
182-
.map(|s| s.as_str())
183-
.collect::<Vec<_>>();
198+
let keywords = keywords.iter().map(|s| s.as_str()).collect::<Vec<_>>();
184199
let categories = categories.iter().map(|s| s.as_str()).collect::<Vec<_>>();
185200

186201
// Persist the new crate, if it doesn't already exist

src/tests/builders/publish.rs

-7
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,6 @@ impl PublishBuilder {
144144
deps: self.deps.clone(),
145145
readme: self.readme,
146146
readme_file: None,
147-
keywords: u::EncodableKeywordList(
148-
self.keywords
149-
.clone()
150-
.into_iter()
151-
.map(u::EncodableKeyword)
152-
.collect(),
153-
),
154147
};
155148

156149
let mut tarball_builder = TarballBuilder::new();

src/tests/krate/publish/snapshots/all__krate__publish__keywords__bad_keywords-2.snap

+1-1
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 keyword specifier at line 1 column 113"
8+
"detail": "\"?@?%\" is an invalid keyword"
99
}
1010
]
1111
}

src/tests/krate/publish/snapshots/all__krate__publish__keywords__bad_keywords-3.snap

+1-1
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 \"áccênts\", expected a valid keyword specifier at line 1 column 118"
8+
"detail": "\"áccênts\" is an invalid keyword"
99
}
1010
]
1111
}

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

+1-1
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 length 29, expected a keyword with less than 20 characters at line 1 column 138"
8+
"detail": "\"super-long-keyword-name-oh-no\" is an invalid keyword (keywords must have less than 20 characters)"
99
}
1010
]
1111
}

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

+1-1
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 length 6, expected at most 5 keywords per crate at line 1 column 139"
8+
"detail": "expected at most 5 keywords per crate"
99
}
1010
]
1111
}

src/views/krate_publish.rs

-36
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use crate::models::krate::MAX_NAME_LENGTH;
1313

1414
use crate::models::Crate;
1515
use crate::models::DependencyKind;
16-
use crate::models::Keyword as CrateKeyword;
1716

1817
#[derive(Deserialize, Serialize, Debug)]
1918
pub struct PublishMetadata {
@@ -23,8 +22,6 @@ pub struct PublishMetadata {
2322
pub features: BTreeMap<EncodableFeatureName, Vec<EncodableFeature>>,
2423
pub readme: Option<String>,
2524
pub readme_file: Option<String>,
26-
#[serde(default)]
27-
pub keywords: EncodableKeywordList,
2825
}
2926

3027
#[derive(Serialize, Deserialize, Clone, Debug)]
@@ -87,25 +84,6 @@ impl<'de> Deserialize<'de> for EncodableDependencyName {
8784
}
8885
}
8986

90-
#[derive(Serialize, Debug, Deref)]
91-
pub struct EncodableKeyword(pub String);
92-
93-
impl<'de> Deserialize<'de> for EncodableKeyword {
94-
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<EncodableKeyword, D::Error> {
95-
let s = String::deserialize(d)?;
96-
if s.len() > 20 {
97-
let expected = "a keyword with less than 20 characters";
98-
Err(de::Error::invalid_length(s.len(), &expected))
99-
} else if !CrateKeyword::valid_name(&s) {
100-
let value = de::Unexpected::Str(&s);
101-
let expected = "a valid keyword specifier";
102-
Err(de::Error::invalid_value(value, &expected))
103-
} else {
104-
Ok(EncodableKeyword(s))
105-
}
106-
}
107-
}
108-
10987
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Clone, Debug, Deref)]
11088
pub struct EncodableFeatureName(pub String);
11189

@@ -179,20 +157,6 @@ impl<'de> Deserialize<'de> for EncodableCrateVersionReq {
179157
}
180158
}
181159

182-
#[derive(Serialize, Debug, Deref, Default)]
183-
pub struct EncodableKeywordList(pub Vec<EncodableKeyword>);
184-
185-
impl<'de> Deserialize<'de> for EncodableKeywordList {
186-
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<EncodableKeywordList, D::Error> {
187-
let inner = <Vec<EncodableKeyword> as Deserialize<'de>>::deserialize(d)?;
188-
if inner.len() > 5 {
189-
let expected = "at most 5 keywords per crate";
190-
return Err(de::Error::invalid_length(inner.len(), &expected));
191-
}
192-
Ok(EncodableKeywordList(inner))
193-
}
194-
}
195-
196160
#[test]
197161
fn feature_deserializes_for_valid_features() {
198162
use serde_json as json;

0 commit comments

Comments
 (0)