]> git.proxmox.com Git - cargo.git/commitdiff
Upload badge metadata specified in the manifest
authorJake Goulding <jake.goulding@integer32.com>
Sun, 1 Jan 2017 20:14:34 +0000 (15:14 -0500)
committerCarol (Nichols || Goulding) <carol.nichols@gmail.com>
Tue, 17 Jan 2017 21:39:49 +0000 (16:39 -0500)
src/cargo/core/manifest.rs
src/cargo/ops/registry.rs
src/cargo/util/toml.rs
src/crates-io/lib.rs
src/doc/manifest.md

index d03cf688b9374c2007952f8cca67526ef6a80e6b..1d7d4fbda20298e0fc7342dbb03e05251d251534 100644 (file)
@@ -1,3 +1,4 @@
+use std::collections::HashMap;
 use std::fmt;
 use std::path::{PathBuf, Path};
 
@@ -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)]
index 2397f8204a9e527214afd65694fe7770755b169f..f3c8de934155aad898aba5527694fc48bcc5362c 100644 (file)
@@ -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))?),
@@ -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 {
@@ -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())),
index 8abbaa2f1839281a420d5655019f4473ee0658f0..7f04d5875fd647756f3995f5daa6de0626e8e72a 100644 (file)
@@ -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)]
@@ -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(),
index 00637be3dc29cd9ffb6802adc63573159f177198..915f44363a3bbd3c366628d7d5a3c07c73e2c64c 100644 (file)
@@ -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)]
@@ -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 }
@@ -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"])
@@ -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)> {
index 09fa5e04e9f8f53673bb4e9e85568bd55a7f93a6..facaff5b093521b97c759ef9b284618bed7b5e9b 100644 (file)
@@ -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