diff --git a/assets/badges/outdated.svg b/assets/badges/outdated.svg
new file mode 100644
index 0000000..69434ff
--- /dev/null
+++ b/assets/badges/outdated.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/badges/up-to-date.svg b/assets/badges/up-to-date.svg
new file mode 100644
index 0000000..42c1200
--- /dev/null
+++ b/assets/badges/up-to-date.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/api.rs b/src/api.rs
index 75bc957..08a9ac9 100644
--- a/src/api.rs
+++ b/src/api.rs
@@ -10,11 +10,13 @@ use serde_json;
use slog::Logger;
use tokio_service::Service;
-use ::models::repo::RepoPath;
+use ::assets;
use ::engine::Engine;
+use ::models::repo::RepoPath;
enum Route {
- AnalyzeDependencies
+ StatusJson,
+ StatusSvg
}
#[derive(Clone)]
@@ -26,7 +28,8 @@ pub struct Api {
impl Api {
pub fn new(engine: Engine) -> Api {
let mut router = Router::new();
- router.add("/repo/:site/:qual/:name/dependencies.json", Route::AnalyzeDependencies);
+ router.add("/repo/:site/:qual/:name/status.json", Route::StatusJson);
+ router.add("/repo/:site/:qual/:name/status.svg", Route::StatusSvg);
Api { engine, router: Arc::new(router) }
}
@@ -62,9 +65,14 @@ impl Service for Api {
fn call(&self, req: Request) -> Self::Future {
if let Ok(route_match) = self.router.recognize(req.uri().path()) {
match route_match.handler {
- &Route::AnalyzeDependencies => {
+ &Route::StatusJson => {
if *req.method() == Method::Get {
- return Box::new(self.analyze_dependencies(req, route_match.params));
+ return Box::new(self.status_json(req, route_match.params));
+ }
+ },
+ &Route::StatusSvg => {
+ if *req.method() == Method::Get {
+ return Box::new(self.status_svg(req, route_match.params));
}
}
}
@@ -77,7 +85,7 @@ impl Service for Api {
}
impl Api {
- fn analyze_dependencies<'r>(&self, _req: Request, params: Params) -> impl Future- {
+ fn status_json<'r>(&self, _req: Request, params: Params) -> impl Future
- {
let engine = self.engine.clone();
let site = params.find("site").expect("route param 'site' not found");
@@ -136,4 +144,45 @@ impl Api {
}
})
}
+
+ fn status_svg<'r>(&self, _req: Request, params: Params) -> impl Future
- {
+ let engine = self.engine.clone();
+
+ let site = params.find("site").expect("route param 'site' not found");
+ let qual = params.find("qual").expect("route param 'qual' not found");
+ let name = params.find("name").expect("route param 'name' not found");
+
+ RepoPath::from_parts(site, qual, name).into_future().then(move |repo_path_result| {
+ match repo_path_result {
+ Err(err) => {
+ let mut response = Response::new();
+ response.set_status(StatusCode::BadRequest);
+ response.set_body(format!("{:?}", err));
+ future::Either::A(future::ok(response))
+ },
+ Ok(repo_path) => {
+ future::Either::B(engine.analyze_dependencies(repo_path).then(|analyze_result| {
+ match analyze_result {
+ Err(err) => {
+ let mut response = Response::new();
+ response.set_status(StatusCode::InternalServerError);
+ response.set_body(format!("{:?}", err));
+ future::Either::A(future::ok(response))
+ },
+ Ok(analysis_outcome) => {
+ let mut response = Response::new()
+ .with_header(ContentType("image/svg+xml;charset=utf-8".parse().unwrap()));
+ if analysis_outcome.deps.any_outdated() {
+ response.set_body(assets::BADGE_OUTDATED_SVG.to_vec());
+ } else {
+ response.set_body(assets::BADGE_UPTODATE_SVG.to_vec());
+ }
+ future::Either::B(future::ok(response))
+ }
+ }
+ }))
+ }
+ }
+ })
+ }
}
\ No newline at end of file
diff --git a/src/assets.rs b/src/assets.rs
new file mode 100644
index 0000000..6d23242
--- /dev/null
+++ b/src/assets.rs
@@ -0,0 +1,4 @@
+pub static BADGE_UPTODATE_SVG: &'static [u8; 978] =
+ include_bytes!("../assets/badges/up-to-date.svg");
+pub static BADGE_OUTDATED_SVG: &'static [u8; 974] =
+ include_bytes!("../assets/badges/outdated.svg");
diff --git a/src/main.rs b/src/main.rs
index 91a473d..2457794 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -19,6 +19,7 @@ mod models;
mod parsers;
mod interactors;
mod engine;
+mod assets;
mod api;
use std::net::SocketAddr;
diff --git a/src/models/crates.rs b/src/models/crates.rs
index 03a4a37..7b5a1b9 100644
--- a/src/models/crates.rs
+++ b/src/models/crates.rs
@@ -92,6 +92,16 @@ impl AnalyzedDependencies {
}).collect();
AnalyzedDependencies { main, dev, build }
}
+
+ pub fn any_outdated(&self) -> bool {
+ let main_any_outdated = self.main.iter()
+ .any(|(_, dep)| dep.is_outdated());
+ let dev_any_outdated = self.dev.iter()
+ .any(|(_, dep)| dep.is_outdated());
+ let build_any_outdated = self.build.iter()
+ .any(|(_, dep)| dep.is_outdated());
+ main_any_outdated || dev_any_outdated || build_any_outdated
+ }
}
#[derive(Debug)]