Skip to content

Commit 154cc0a

Browse files
committed
Warn when crates.io sends back invalid category slugs
1 parent 0f01d9b commit 154cc0a

File tree

2 files changed

+40
-9
lines changed

2 files changed

+40
-9
lines changed

src/cargo/ops/registry.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ fn transmit(config: &Config,
133133
return Ok(());
134134
}
135135

136-
registry.publish(&NewCrate {
136+
let publish = registry.publish(&NewCrate {
137137
name: pkg.name().to_string(),
138138
vers: pkg.version().to_string(),
139139
deps: deps,
@@ -148,9 +148,22 @@ fn transmit(config: &Config,
148148
repository: repository.clone(),
149149
license: license.clone(),
150150
license_file: license_file.clone(),
151-
}, tarball).map_err(|e| {
152-
human(e.to_string())
153-
})
151+
}, tarball);
152+
153+
match publish {
154+
Ok(invalid_categories) => {
155+
if !invalid_categories.is_empty() {
156+
let msg = format!("\
157+
the following are not valid category slugs and were \
158+
ignored: {}. Please see https://crates.io/category_slugs \
159+
for the list of all category slugs. \
160+
", invalid_categories.join(", "));
161+
config.shell().warn(&msg)?;
162+
}
163+
Ok(())
164+
},
165+
Err(e) => Err(human(e.to_string())),
166+
}
154167
}
155168

156169
pub fn registry_configuration(config: &Config) -> CargoResult<RegistryConfig> {

src/crates-io/lib.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::io::{self, Cursor};
1010
use std::result;
1111

1212
use curl::easy::{Easy, List};
13-
use rustc_serialize::json;
13+
use rustc_serialize::json::{self, Json};
1414

1515
use url::percent_encoding::{percent_encode, QUERY_ENCODE_SET};
1616

@@ -39,6 +39,7 @@ pub enum Error {
3939
NotFound,
4040
JsonEncodeError(json::EncoderError),
4141
JsonDecodeError(json::DecoderError),
42+
JsonParseError(json::ParserError),
4243
}
4344

4445
impl From<json::EncoderError> for Error {
@@ -53,6 +54,12 @@ impl From<json::DecoderError> for Error {
5354
}
5455
}
5556

57+
impl From<json::ParserError> for Error {
58+
fn from(err: json::ParserError) -> Error {
59+
Error::JsonParseError(err)
60+
}
61+
}
62+
5663
impl From<curl::Error> for Error {
5764
fn from(err: curl::Error) -> Error {
5865
Error::Curl(err)
@@ -111,7 +118,6 @@ pub struct User {
111118
#[derive(RustcDecodable)] struct Users { users: Vec<User> }
112119
#[derive(RustcDecodable)] struct TotalCrates { total: u32 }
113120
#[derive(RustcDecodable)] struct Crates { crates: Vec<Crate>, meta: TotalCrates }
114-
115121
impl Registry {
116122
pub fn new(host: String, token: Option<String>) -> Registry {
117123
Registry::new_handle(host, token, Easy::new())
@@ -148,7 +154,8 @@ impl Registry {
148154
Ok(json::decode::<Users>(&body)?.users)
149155
}
150156

151-
pub fn publish(&mut self, krate: &NewCrate, tarball: &File) -> Result<()> {
157+
pub fn publish(&mut self, krate: &NewCrate, tarball: &File)
158+
-> Result<Vec<String>> {
152159
let json = json::encode(krate)?;
153160
// Prepare the body. The format of the upload request is:
154161
//
@@ -191,10 +198,20 @@ impl Registry {
191198
headers.append(&format!("Authorization: {}", token))?;
192199
self.handle.http_headers(headers)?;
193200

194-
let _body = handle(&mut self.handle, &mut |buf| {
201+
let body = handle(&mut self.handle, &mut |buf| {
195202
body.read(buf).unwrap_or(0)
196203
})?;
197-
Ok(())
204+
// Can't derive RustcDecodable because JSON has a key named "crate" :(
205+
let response = Json::from_str(&body)?;
206+
let invalid_categories: Vec<String> =
207+
response
208+
.find_path(&["warnings", "invalid_categories"])
209+
.and_then(Json::as_array)
210+
.map(|x| {
211+
x.iter().flat_map(Json::as_string).map(Into::into).collect()
212+
})
213+
.unwrap_or_else(Vec::new);
214+
Ok(invalid_categories)
198215
}
199216

200217
pub fn search(&mut self, query: &str, limit: u8) -> Result<(Vec<Crate>, u32)> {
@@ -329,6 +346,7 @@ impl fmt::Display for Error {
329346
Error::NotFound => write!(f, "cannot find crate"),
330347
Error::JsonEncodeError(ref e) => write!(f, "json encode error: {}", e),
331348
Error::JsonDecodeError(ref e) => write!(f, "json decode error: {}", e),
349+
Error::JsonParseError(ref e) => write!(f, "json parse error: {}", e),
332350
}
333351
}
334352
}

0 commit comments

Comments
 (0)