diff --git a/app/components/badge-gitlab.js b/app/components/badge-gitlab.js
new file mode 100644
index 00000000000..0977a1d6b2f
--- /dev/null
+++ b/app/components/badge-gitlab.js
@@ -0,0 +1,13 @@
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+ tagName: 'span',
+ classNames: ['badge'],
+ repository: Ember.computed.alias('badge.attributes.repository'),
+ branch: Ember.computed('badge.attributes.branch', function() {
+ return this.get('badge.attributes.branch') || 'master';
+ }),
+ text: Ember.computed('badge', function() {
+ return `Gitlab build status for the ${ this.get('branch') } branch`;
+ })
+});
diff --git a/app/mirage/fixtures/search.js b/app/mirage/fixtures/search.js
index 1a9b0826927..97905c0e420 100644
--- a/app/mirage/fixtures/search.js
+++ b/app/mirage/fixtures/search.js
@@ -32,6 +32,13 @@ export default {
"repository": "huonw/external_mixin"
},
"badge_type": "travis-ci"
+ },
+ {
+ "attributes": {
+ "branch": "master",
+ "repository": "huonw/external_mixin"
+ },
+ "badge_type": "gitlab"
}
],
"versions": null
diff --git a/app/templates/components/badge-gitlab.hbs b/app/templates/components/badge-gitlab.hbs
new file mode 100644
index 00000000000..bc8b58453f0
--- /dev/null
+++ b/app/templates/components/badge-gitlab.hbs
@@ -0,0 +1,6 @@
+
+
+
diff --git a/src/badge.rs b/src/badge.rs
index 7a94847d9ed..3d12321b0ad 100644
--- a/src/badge.rs
+++ b/src/badge.rs
@@ -15,6 +15,9 @@ pub enum Badge {
Appveyor {
repository: String, branch: Option, service: Option,
},
+ Gitlab {
+ repository: String, branch: Option,
+ },
}
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
@@ -58,6 +61,19 @@ impl Model for Badge {
database"),
}
},
+ "gitlab" => {
+ Badge::Gitlab {
+ branch: attributes.get("branch")
+ .and_then(Json::as_string)
+ .map(str::to_string),
+ repository: attributes.get("repository")
+ .and_then(Json::as_string)
+ .map(str::to_string)
+ .expect("Invalid Gitlab badge \
+ without repository in the \
+ database"),
+ }
+ },
_ => {
panic!("Unknown badge type {} in the database", badge_type);
},
@@ -84,6 +100,7 @@ impl Badge {
match *self {
Badge::TravisCi {..} => "travis-ci",
Badge::Appveyor {..} => "appveyor",
+ Badge::Gitlab{..} => "gitlab",
}
}
@@ -120,7 +137,16 @@ impl Badge {
service
);
}
- }
+ },
+ Badge::Gitlab { branch, repository } => {
+ attributes.insert(String::from("repository"), repository);
+ if let Some(branch) = branch {
+ attributes.insert(
+ String::from("branch"),
+ branch
+ );
+ }
+ },
}
attributes
@@ -156,7 +182,19 @@ impl Badge {
},
None => Err(badge_type.to_string()),
}
- },
+ },
+ "gitlab" => {
+ match attributes.get("repository") {
+ Some(repository) => {
+ Ok(Badge::Gitlab {
+ repository: repository.to_string(),
+ branch: attributes.get("branch")
+ .map(String::to_string),
+ })
+ },
+ None => Err(badge_type.to_string()),
+ }
+ },
_ => Err(badge_type.to_string()),
}
}
diff --git a/src/tests/badge.rs b/src/tests/badge.rs
index 43c5618b989..d31dc037107 100644
--- a/src/tests/badge.rs
+++ b/src/tests/badge.rs
@@ -45,6 +45,20 @@ fn update_crate() {
String::from("rust-lang/rust")
);
+ let gitlab = Badge::Gitlab {
+ branch: Some(String::from("beta")),
+ repository: String::from("rust-lang/rust"),
+ };
+ let mut badge_attributes_gitlab = HashMap::new();
+ badge_attributes_gitlab.insert(
+ String::from("branch"),
+ String::from("beta")
+ );
+ badge_attributes_gitlab.insert(
+ String::from("repository"),
+ String::from("rust-lang/rust")
+ );
+
let mut badges = HashMap::new();
// Updating with no badges has no effect
@@ -68,6 +82,15 @@ fn update_crate() {
Badge::update_crate(tx(&req), &krate, badges.clone()).unwrap();
assert_eq!(krate.badges(tx(&req)).unwrap(), vec![travis_ci.clone()]);
+ // Replacing one badge with another (again)
+ badges.clear();
+ badges.insert(
+ String::from("gitlab"),
+ badge_attributes_gitlab.clone()
+ );
+ Badge::update_crate(tx(&req), &krate, badges.clone()).unwrap();
+ assert_eq!(krate.badges(tx(&req)).unwrap(), vec![gitlab.clone()]);
+
// Updating badge attributes
let travis_ci2 = Badge::TravisCi {
branch: None,
@@ -83,14 +106,14 @@ fn update_crate() {
badge_attributes_travis_ci2.clone()
);
Badge::update_crate(tx(&req), &krate, badges.clone()).unwrap();
- assert_eq!(krate.badges(tx(&req)).unwrap(), vec![travis_ci2.clone()]);
+ assert_eq!(krate.badges(tx(&req)).unwrap(), vec![gitlab.clone(), travis_ci2.clone()]);
// Removing one badge
badges.clear();
Badge::update_crate(tx(&req), &krate, badges.clone()).unwrap();
assert_eq!(krate.badges(tx(&req)).unwrap(), vec![]);
- // Adding 2 badges
+ // Adding 3 badges
badges.insert(
String::from("appveyor"),
badge_attributes_appveyor.clone()
@@ -99,22 +122,28 @@ fn update_crate() {
String::from("travis-ci"),
badge_attributes_travis_ci.clone()
);
+ badges.insert(
+ String::from("gitlab"),
+ badge_attributes_gitlab.clone()
+ );
Badge::update_crate(
tx(&req), &krate, badges.clone()
).unwrap();
let current_badges = krate.badges(tx(&req)).unwrap();
- assert_eq!(current_badges.len(), 2);
+ assert_eq!(current_badges.len(), 3);
assert!(current_badges.contains(&appveyor));
assert!(current_badges.contains(&travis_ci));
+ assert!(current_badges.contains(&gitlab));
// Removing all badges
badges.clear();
Badge::update_crate(tx(&req), &krate, badges.clone()).unwrap();
assert_eq!(krate.badges(tx(&req)).unwrap(), vec![]);
- // Attempting to add one valid badge (appveyor) and two invalid badges
- // (travis-ci without a required attribute and an unknown badge type)
+ // Attempting to add one valid badge (appveyor) and three invalid badges
+ // (travis-ci and gitlab without a required attribute and an unknown badge
+ // type)
// Extra invalid keys are fine, we'll just ignore those
badge_attributes_appveyor.insert(
@@ -133,6 +162,13 @@ fn update_crate() {
badge_attributes_travis_ci.clone()
);
+ // Repository is a required key
+ badge_attributes_gitlab.remove("repository");
+ badges.insert(
+ String::from("gitlab"),
+ badge_attributes_gitlab.clone()
+ );
+
// This is not a badge that crates.io knows about
let mut invalid_attributes = HashMap::new();
invalid_attributes.insert(
@@ -147,8 +183,9 @@ fn update_crate() {
let invalid_badges = Badge::update_crate(
tx(&req), &krate, badges.clone()
).unwrap();
- assert_eq!(invalid_badges.len(), 2);
+ assert_eq!(invalid_badges.len(), 3);
assert!(invalid_badges.contains(&String::from("travis-ci")));
+ assert!(invalid_badges.contains(&String::from("gitlab")));
assert!(invalid_badges.contains(&String::from("not-a-badge")));
assert_eq!(krate.badges(tx(&req)).unwrap(), vec![appveyor.clone()]);
}
diff --git a/tests/acceptance/search-test.js b/tests/acceptance/search-test.js
index 7bfa0b9dcc9..151e67a00a5 100644
--- a/tests/acceptance/search-test.js
+++ b/tests/acceptance/search-test.js
@@ -24,8 +24,12 @@ test('searching for "rust"', function(assert) {
hasText(assert, '#crates .row:first .desc .info', 'rust_mixin');
findWithAssert('#crates .row:first .desc .info .vers img[alt="0.0.1"]');
+ findWithAssert('#crates .row:first .desc .info .badge:first a[href="https://ci.appveyor.com/project/huonw/external_mixin"]');
findWithAssert('#crates .row:first .desc .info .badge:first a img[src="https://ci.appveyor.com/api/projects/status/github/huonw/external_mixin?svg=true&branch=master"]');
- findWithAssert('#crates .row:first .desc .info .badge:eq(1) a img[src="https://travis-ci.org/huonw/external_mixin.svg?branch=master"]');
+ findWithAssert('#crates .row:first .desc .info .badge:eq(1) a[href="https://gitlab.com/huonw/external_mixin/pipelines"]');
+ findWithAssert('#crates .row:first .desc .info .badge:eq(1) a img[src="https://gitlab.com/huonw/external_mixin/badges/master/build.svg"]');
+ findWithAssert('#crates .row:first .desc .info .badge:eq(2) a[href="https://travis-ci.org/huonw/external_mixin"]');
+ findWithAssert('#crates .row:first .desc .info .badge:eq(2) a img[src="https://travis-ci.org/huonw/external_mixin.svg?branch=master"]');
hasText(assert, '#crates .row:first .desc .summary', 'Yo dawg, use Rust to generate Rust, right in your Rust. (See `external_mixin` to use scripting languages.)');
hasText(assert, '#crates .row:first .downloads', '477');