-
Notifications
You must be signed in to change notification settings - Fork 611
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #504 from integer32llc/ci-badge
Add support for showing Travis and Appveyor current build status badges
- Loading branch information
Showing
24 changed files
with
646 additions
and
20 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
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'; | ||
}), | ||
service: Ember.computed('badge.attributes.service', function() { | ||
return this.get('badge.attributes.service') || 'github'; | ||
}), | ||
text: Ember.computed('badge', function() { | ||
return `Appveyor build status for the ${ this.get('branch') } branch`; | ||
}) | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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('branch', function() { | ||
return `Travis CI build status for the ${ this.get('branch') } branch`; | ||
}) | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -119,9 +119,6 @@ | |
} | ||
.vers { | ||
margin-left: 10px; | ||
img { | ||
margin-bottom: -4px; | ||
} | ||
} | ||
|
||
.stats { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<a href="https://ci.appveyor.com/project/{{ repository }}"> | ||
<img | ||
src="https://ci.appveyor.com/api/projects/status/{{ service }}/{{ repository }}?svg=true&branch={{ branch }}" | ||
alt="{{ text }}" | ||
title="{{ text }}" /> | ||
</a> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<a href="https://travis-ci.org/{{ repository }}"> | ||
<img | ||
src="https://travis-ci.org/{{ repository }}.svg?branch={{ branch }}" | ||
alt="{{ text }}" | ||
title="{{ text }}" /> | ||
</a> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
use util::CargoResult; | ||
use krate::Crate; | ||
use Model; | ||
|
||
use std::collections::HashMap; | ||
use pg::GenericConnection; | ||
use pg::rows::Row; | ||
use rustc_serialize::json::Json; | ||
|
||
#[derive(Debug, PartialEq, Clone)] | ||
pub enum Badge { | ||
TravisCi { | ||
repository: String, branch: Option<String>, | ||
}, | ||
Appveyor { | ||
repository: String, branch: Option<String>, service: Option<String>, | ||
}, | ||
} | ||
|
||
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] | ||
pub struct EncodableBadge { | ||
pub badge_type: String, | ||
pub attributes: HashMap<String, String>, | ||
} | ||
|
||
impl Model for Badge { | ||
fn from_row(row: &Row) -> Badge { | ||
let attributes: Json = row.get("attributes"); | ||
if let Json::Object(attributes) = attributes { | ||
let badge_type: String = row.get("badge_type"); | ||
match badge_type.as_str() { | ||
"travis-ci" => { | ||
Badge::TravisCi { | ||
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 TravisCi badge \ | ||
without repository in the \ | ||
database"), | ||
} | ||
}, | ||
"appveyor" => { | ||
Badge::Appveyor { | ||
service: attributes.get("service") | ||
.and_then(Json::as_string) | ||
.map(str::to_string), | ||
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 Appveyor badge \ | ||
without repository in the \ | ||
database"), | ||
} | ||
}, | ||
_ => { | ||
panic!("Unknown badge type {} in the database", badge_type); | ||
}, | ||
} | ||
} else { | ||
panic!( | ||
"badge attributes {:?} in the database was not a JSON object", | ||
attributes | ||
); | ||
} | ||
} | ||
fn table_name(_: Option<Badge>) -> &'static str { "badges" } | ||
} | ||
|
||
impl Badge { | ||
pub fn encodable(self) -> EncodableBadge { | ||
EncodableBadge { | ||
badge_type: self.badge_type().to_string(), | ||
attributes: self.attributes(), | ||
} | ||
} | ||
|
||
pub fn badge_type(&self) -> &'static str { | ||
match *self { | ||
Badge::TravisCi {..} => "travis-ci", | ||
Badge::Appveyor {..} => "appveyor", | ||
} | ||
} | ||
|
||
pub fn json_attributes(self) -> Json { | ||
Json::Object(self.attributes().into_iter().map(|(k, v)| { | ||
(k, Json::String(v)) | ||
}).collect()) | ||
} | ||
|
||
fn attributes(self) -> HashMap<String, String> { | ||
let mut attributes = HashMap::new(); | ||
|
||
match self { | ||
Badge::TravisCi { branch, repository } => { | ||
attributes.insert(String::from("repository"), repository); | ||
if let Some(branch) = branch { | ||
attributes.insert( | ||
String::from("branch"), | ||
branch | ||
); | ||
} | ||
}, | ||
Badge::Appveyor { service, branch, repository } => { | ||
attributes.insert(String::from("repository"), repository); | ||
if let Some(branch) = branch { | ||
attributes.insert( | ||
String::from("branch"), | ||
branch | ||
); | ||
} | ||
if let Some(service) = service { | ||
attributes.insert( | ||
String::from("service"), | ||
service | ||
); | ||
} | ||
} | ||
} | ||
|
||
attributes | ||
} | ||
|
||
fn from_attributes(badge_type: &str, | ||
attributes: &HashMap<String, String>) | ||
-> Result<Badge, String> { | ||
match badge_type { | ||
"travis-ci" => { | ||
match attributes.get("repository") { | ||
Some(repository) => { | ||
Ok(Badge::TravisCi { | ||
repository: repository.to_string(), | ||
branch: attributes.get("branch") | ||
.map(String::to_string), | ||
}) | ||
}, | ||
None => Err(badge_type.to_string()), | ||
} | ||
}, | ||
"appveyor" => { | ||
match attributes.get("repository") { | ||
Some(repository) => { | ||
Ok(Badge::Appveyor { | ||
repository: repository.to_string(), | ||
branch: attributes.get("branch") | ||
.map(String::to_string), | ||
service: attributes.get("service") | ||
.map(String::to_string), | ||
|
||
}) | ||
}, | ||
None => Err(badge_type.to_string()), | ||
} | ||
}, | ||
_ => Err(badge_type.to_string()), | ||
} | ||
} | ||
|
||
pub fn update_crate(conn: &GenericConnection, | ||
krate: &Crate, | ||
badges: HashMap<String, HashMap<String, String>>) | ||
-> CargoResult<Vec<String>> { | ||
|
||
let mut invalid_badges = vec![]; | ||
|
||
let badges: Vec<_> = badges.iter().filter_map(|(k, v)| { | ||
Badge::from_attributes(k, v).map_err(|invalid_badge| { | ||
invalid_badges.push(invalid_badge) | ||
}).ok() | ||
}).collect(); | ||
|
||
conn.execute("\ | ||
DELETE FROM badges \ | ||
WHERE crate_id = $1;", | ||
&[&krate.id] | ||
)?; | ||
|
||
for badge in badges { | ||
conn.execute("\ | ||
INSERT INTO badges (crate_id, badge_type, attributes) \ | ||
VALUES ($1, $2, $3) \ | ||
ON CONFLICT (crate_id, badge_type) DO UPDATE \ | ||
SET attributes = EXCLUDED.attributes;", | ||
&[&krate.id, &badge.badge_type(), &badge.json_attributes()] | ||
)?; | ||
} | ||
Ok(invalid_badges) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.