Skip to content

Commit

Permalink
Upload badge metadata specified in the manifest
Browse files Browse the repository at this point in the history
  • Loading branch information
shepmaster authored and carols10cents committed Jan 17, 2017
1 parent 7ba2012 commit f5f4c41
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/cargo/core/manifest.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::fmt;
use std::path::{PathBuf, Path};

Expand Down Expand Up @@ -55,6 +56,7 @@ pub struct ManifestMetadata {
pub homepage: Option<String>, // url
pub repository: Option<String>, // url
pub documentation: Option<String>, // url
pub badges: HashMap<String, HashMap<String, String>>,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
Expand Down
15 changes: 14 additions & 1 deletion src/cargo/ops/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ fn transmit(config: &Config,
let ManifestMetadata {
ref authors, ref description, ref homepage, ref documentation,
ref keywords, ref readme, ref repository, ref license, ref license_file,
ref categories,
ref categories, ref badges,
} = *manifest.metadata();
let readme = match *readme {
Some(ref readme) => Some(paths::read(&pkg.root().join(readme))?),
Expand Down Expand Up @@ -149,6 +149,7 @@ fn transmit(config: &Config,
repository: repository.clone(),
license: license.clone(),
license_file: license_file.clone(),
badges: badges.clone(),
}, tarball);

match publish {
Expand All @@ -161,6 +162,18 @@ fn transmit(config: &Config,
", warnings.invalid_categories.join(", "));
config.shell().warn(&msg)?;
}

if !warnings.invalid_badges.is_empty() {
let msg = format!("\
the following are not valid badges and were ignored: {}. \
Either the badge type specified is unknown or a required \
attribute is missing. Please see \
http://doc.crates.io/manifest.html#package-metadata \
for valid badge types and their required attributes.",
warnings.invalid_badges.join(", "));
config.shell().warn(&msg)?;
}

Ok(())
},
Err(e) => Err(human(e.to_string())),
Expand Down
2 changes: 2 additions & 0 deletions src/cargo/util/toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ pub struct TomlManifest {
target: Option<HashMap<String, TomlPlatform>>,
replace: Option<HashMap<String, TomlDependency>>,
workspace: Option<TomlWorkspace>,
badges: Option<HashMap<String, HashMap<String, String>>>,
}

#[derive(RustcDecodable, Clone, Default)]
Expand Down Expand Up @@ -656,6 +657,7 @@ impl TomlManifest {
repository: project.repository.clone(),
keywords: project.keywords.clone().unwrap_or(Vec::new()),
categories: project.categories.clone().unwrap_or(Vec::new()),
badges: self.badges.clone().unwrap_or_else(HashMap::new),
};

let workspace_config = match (self.workspace.as_ref(),
Expand Down
19 changes: 18 additions & 1 deletion src/crates-io/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ pub struct NewCrate {
pub license: Option<String>,
pub license_file: Option<String>,
pub repository: Option<String>,
pub badges: HashMap<String, HashMap<String, String>>,
}

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

pub struct Warnings {
pub invalid_categories: Vec<String>,
pub invalid_badges: Vec<String>,
}

#[derive(RustcDecodable)] struct R { ok: bool }
Expand Down Expand Up @@ -205,12 +207,14 @@ impl Registry {
let body = handle(&mut self.handle, &mut |buf| {
body.read(buf).unwrap_or(0)
})?;

// Can't derive RustcDecodable because JSON has a key named "crate" :(
let response = if body.len() > 0 {
Json::from_str(&body)?
} else {
Json::from_str("{}")?
};

let invalid_categories: Vec<String> =
response
.find_path(&["warnings", "invalid_categories"])
Expand All @@ -219,7 +223,20 @@ impl Registry {
x.iter().flat_map(Json::as_string).map(Into::into).collect()
})
.unwrap_or_else(Vec::new);
Ok(Warnings { invalid_categories: invalid_categories })

let invalid_badges: Vec<String> =
response
.find_path(&["warnings", "invalid_badges"])
.and_then(Json::as_array)
.map(|x| {
x.iter().flat_map(Json::as_string).map(Into::into).collect()
})
.unwrap_or_else(Vec::new);

Ok(Warnings {
invalid_categories: invalid_categories,
invalid_badges: invalid_badges,
})
}

pub fn search(&mut self, query: &str, limit: u8) -> Result<(Vec<Crate>, u32)> {
Expand Down
10 changes: 10 additions & 0 deletions src/doc/manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@ license = "..."
# lieu of the above key and must point to a file relative to this manifest
# (similar to the readme key).
license-file = "..."

# Optional specificaion of badges to be displayed on crates.io. The badges
# currently available are Travis CI and Appveyor latest build status, specified
# using the following parameters:
[badges]
# Travis CI: `repository` is required. `branch` is optional; default is `master`
travis-ci = { repository = "...", branch = "master" }
# Appveyor: `repository` is required. `branch` is optional; default is `master`
# `service` is optional; valid values are `github` (default) and `bitbucket`
appveyor = { repository = "...", branch = "master", service = "github" }
```

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

0 comments on commit f5f4c41

Please sign in to comment.