Skip to content

Commit 27609e5

Browse files
committed
Auto merge of #3546 - integer32llc:badgers, r=alexcrichton
Upload Travis CI and Appveyor badge metadata specified in the manifest This goes with rust-lang/crates.io#504. This has cargo upload badge metadata to crates.io on publish, and will print any warnings it gets back from crates.io about unknown badges or missing required badge attributes! This will definitely cause some merge conflicts with #3301, I'll watch and fix whichever one gets merged 2nd :)
2 parents 7ba2012 + f5f4c41 commit 27609e5

File tree

5 files changed

+46
-2
lines changed

5 files changed

+46
-2
lines changed

src/cargo/core/manifest.rs

+2
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

+14-1
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

+2
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

+18-1
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

+10
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)