Skip to content

Commit f5f4c41

Browse files
shepmastercarols10cents
authored andcommitted
Upload badge metadata specified in the manifest
1 parent 7ba2012 commit f5f4c41

File tree

5 files changed

+46
-2
lines changed

5 files changed

+46
-2
lines changed

src/cargo/core/manifest.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::collections::HashMap;
12
use std::fmt;
23
use std::path::{PathBuf, Path};
34

@@ -55,6 +56,7 @@ pub struct ManifestMetadata {
5556
pub homepage: Option<String>, // url
5657
pub repository: Option<String>, // url
5758
pub documentation: Option<String>, // url
59+
pub badges: HashMap<String, HashMap<String, String>>,
5860
}
5961

6062
#[derive(Debug, Clone, PartialEq, Eq, Hash)]

src/cargo/ops/registry.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ fn transmit(config: &Config,
113113
let ManifestMetadata {
114114
ref authors, ref description, ref homepage, ref documentation,
115115
ref keywords, ref readme, ref repository, ref license, ref license_file,
116-
ref categories,
116+
ref categories, ref badges,
117117
} = *manifest.metadata();
118118
let readme = match *readme {
119119
Some(ref readme) => Some(paths::read(&pkg.root().join(readme))?),
@@ -149,6 +149,7 @@ fn transmit(config: &Config,
149149
repository: repository.clone(),
150150
license: license.clone(),
151151
license_file: license_file.clone(),
152+
badges: badges.clone(),
152153
}, tarball);
153154

154155
match publish {
@@ -161,6 +162,18 @@ fn transmit(config: &Config,
161162
", warnings.invalid_categories.join(", "));
162163
config.shell().warn(&msg)?;
163164
}
165+
166+
if !warnings.invalid_badges.is_empty() {
167+
let msg = format!("\
168+
the following are not valid badges and were ignored: {}. \
169+
Either the badge type specified is unknown or a required \
170+
attribute is missing. Please see \
171+
http://doc.crates.io/manifest.html#package-metadata \
172+
for valid badge types and their required attributes.",
173+
warnings.invalid_badges.join(", "));
174+
config.shell().warn(&msg)?;
175+
}
176+
164177
Ok(())
165178
},
166179
Err(e) => Err(human(e.to_string())),

src/cargo/util/toml.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ pub struct TomlManifest {
246246
target: Option<HashMap<String, TomlPlatform>>,
247247
replace: Option<HashMap<String, TomlDependency>>,
248248
workspace: Option<TomlWorkspace>,
249+
badges: Option<HashMap<String, HashMap<String, String>>>,
249250
}
250251

251252
#[derive(RustcDecodable, Clone, Default)]
@@ -656,6 +657,7 @@ impl TomlManifest {
656657
repository: project.repository.clone(),
657658
keywords: project.keywords.clone().unwrap_or(Vec::new()),
658659
categories: project.categories.clone().unwrap_or(Vec::new()),
660+
badges: self.badges.clone().unwrap_or_else(HashMap::new),
659661
};
660662

661663
let workspace_config = match (self.workspace.as_ref(),

src/crates-io/lib.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ pub struct NewCrate {
8989
pub license: Option<String>,
9090
pub license_file: Option<String>,
9191
pub repository: Option<String>,
92+
pub badges: HashMap<String, HashMap<String, String>>,
9293
}
9394

9495
#[derive(RustcEncodable)]
@@ -113,6 +114,7 @@ pub struct User {
113114

114115
pub struct Warnings {
115116
pub invalid_categories: Vec<String>,
117+
pub invalid_badges: Vec<String>,
116118
}
117119

118120
#[derive(RustcDecodable)] struct R { ok: bool }
@@ -205,12 +207,14 @@ impl Registry {
205207
let body = handle(&mut self.handle, &mut |buf| {
206208
body.read(buf).unwrap_or(0)
207209
})?;
210+
208211
// Can't derive RustcDecodable because JSON has a key named "crate" :(
209212
let response = if body.len() > 0 {
210213
Json::from_str(&body)?
211214
} else {
212215
Json::from_str("{}")?
213216
};
217+
214218
let invalid_categories: Vec<String> =
215219
response
216220
.find_path(&["warnings", "invalid_categories"])
@@ -219,7 +223,20 @@ impl Registry {
219223
x.iter().flat_map(Json::as_string).map(Into::into).collect()
220224
})
221225
.unwrap_or_else(Vec::new);
222-
Ok(Warnings { invalid_categories: invalid_categories })
226+
227+
let invalid_badges: Vec<String> =
228+
response
229+
.find_path(&["warnings", "invalid_badges"])
230+
.and_then(Json::as_array)
231+
.map(|x| {
232+
x.iter().flat_map(Json::as_string).map(Into::into).collect()
233+
})
234+
.unwrap_or_else(Vec::new);
235+
236+
Ok(Warnings {
237+
invalid_categories: invalid_categories,
238+
invalid_badges: invalid_badges,
239+
})
223240
}
224241

225242
pub fn search(&mut self, query: &str, limit: u8) -> Result<(Vec<Crate>, u32)> {

src/doc/manifest.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,16 @@ license = "..."
138138
# lieu of the above key and must point to a file relative to this manifest
139139
# (similar to the readme key).
140140
license-file = "..."
141+
142+
# Optional specificaion of badges to be displayed on crates.io. The badges
143+
# currently available are Travis CI and Appveyor latest build status, specified
144+
# using the following parameters:
145+
[badges]
146+
# Travis CI: `repository` is required. `branch` is optional; default is `master`
147+
travis-ci = { repository = "...", branch = "master" }
148+
# Appveyor: `repository` is required. `branch` is optional; default is `master`
149+
# `service` is optional; valid values are `github` (default) and `bitbucket`
150+
appveyor = { repository = "...", branch = "master", service = "github" }
141151
```
142152

143153
The [crates.io](https://crates.io) registry will render the description, display

0 commit comments

Comments
 (0)