From ca367f54bb0379937f70131426436372bb650a2a Mon Sep 17 00:00:00 2001 From: Sam Rijs Date: Sun, 11 Feb 2018 17:22:00 +1100 Subject: [PATCH] polish error state for dependency report fixes #10 --- src/server/mod.rs | 24 ++++--------- src/server/views/html/status.rs | 43 +++++++++++++++++++--- src/server/views/mod.rs | 3 -- src/server/views/status_json.rs | 63 --------------------------------- 4 files changed, 46 insertions(+), 87 deletions(-) delete mode 100644 src/server/views/status_json.rs diff --git a/src/server/mod.rs b/src/server/mod.rs index 6491386..87bd300 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -16,7 +16,6 @@ use ::models::repo::RepoPath; #[derive(Clone, Copy, PartialEq)] enum StatusFormat { Html, - Json, Svg } @@ -49,7 +48,6 @@ impl Server { router.add("/static/favicon.png", Route::Static(StaticFile::FaviconPng)); router.add("/repo/:site/:qual/:name", Route::Status(StatusFormat::Html)); - router.add("/repo/:site/:qual/:name/status.json", Route::Status(StatusFormat::Json)); router.add("/repo/:site/:qual/:name/status.svg", Route::Status(StatusFormat::Svg)); Server { logger, engine, router: Arc::new(router) } @@ -131,19 +129,13 @@ impl Server { future::Either::B(server.engine.analyze_dependencies(repo_path.clone()).then(move |analyze_result| { match analyze_result { Err(err) => { - if format != StatusFormat::Svg { - error!(logger, "error: {}", err); - let mut response = views::html::error::render("Failed to analyze repository", - "The repository you requested might be structured in an uncommon way that is not yet supported."); - response.set_status(StatusCode::InternalServerError); - future::Either::A(future::ok(response)) - } else { - future::Either::A(future::ok(views::status_svg(None))) - } + error!(logger, "error: {}", err); + let response = Server::status_format_analysis(None, format, repo_path); + future::ok(response) }, Ok(analysis_outcome) => { - let response = Server::status_format_analysis(analysis_outcome, format, repo_path); - future::Either::B(future::ok(response)) + let response = Server::status_format_analysis(Some(analysis_outcome), format, repo_path); + future::ok(response) } } })) @@ -152,12 +144,10 @@ impl Server { }) } - fn status_format_analysis(analysis_outcome: AnalyzeDependenciesOutcome, format: StatusFormat, repo_path: RepoPath) -> Response { + fn status_format_analysis(analysis_outcome: Option, format: StatusFormat, repo_path: RepoPath) -> Response { match format { - StatusFormat::Json => - views::status_json(analysis_outcome), StatusFormat::Svg => - views::status_svg(Some(analysis_outcome)), + views::status_svg(analysis_outcome), StatusFormat::Html => views::html::status::render(analysis_outcome, repo_path) } diff --git a/src/server/views/html/status.rs b/src/server/views/html/status.rs index 0094bc5..4801355 100644 --- a/src/server/views/html/status.rs +++ b/src/server/views/html/status.rs @@ -85,10 +85,35 @@ fn dependency_table(title: &str, deps: BTreeMap) } } -pub fn render(analysis_outcome: AnalyzeDependenciesOutcome, repo_path: RepoPath) -> Response { +fn render_failure(repo_path: RepoPath) -> Markup { + html! { + section class="hero is-light" { + div class="hero-head" (super::render_navbar()) + div class="hero-body" { + div class="container" { + h1 class="title is-1" { + a href=(format!("{}/{}/{}", repo_path.site.to_base_uri(), repo_path.qual.as_ref(), repo_path.name.as_ref())) { + i class="fa fa-github" "" + (format!(" {} / {}", repo_path.qual.as_ref(), repo_path.name.as_ref())) + } + } + } + } + } + section class="section" { + div class="container" { + div class="notification is-danger" { + h2 class="title is-3" "Failed to analyze repository" + p "The repository you requested might be structured in an uncommon way that is not yet supported." + } + } + } + } +} + +fn render_success(analysis_outcome: AnalyzeDependenciesOutcome, repo_path: RepoPath) -> Markup { let self_path = format!("repo/{}/{}/{}", repo_path.site.as_ref(), repo_path.qual.as_ref(), repo_path.name.as_ref()); let status_base_url = format!("{}/{}", &super::SELF_BASE_URL as &str, self_path); - let title = format!("{} / {}", repo_path.qual.as_ref(), repo_path.name.as_ref()); let (hero_class, status_asset) = if analysis_outcome.any_outdated() { ("is-warning", assets::BADGE_OUTDATED_SVG.as_ref()) @@ -98,7 +123,7 @@ pub fn render(analysis_outcome: AnalyzeDependenciesOutcome, repo_path: RepoPath) let status_data_url = format!("data:image/svg+xml;base64,{}", Base64Display::standard(status_asset)); - super::render_html(&title, html! { + html! { section class=(format!("hero {}", hero_class)) { div class="hero-head" (super::render_navbar()) div class="hero-body" { @@ -128,5 +153,15 @@ pub fn render(analysis_outcome: AnalyzeDependenciesOutcome, repo_path: RepoPath) } } } - }) + } +} + +pub fn render(analysis_outcome: Option, repo_path: RepoPath) -> Response { + let title = format!("{} / {}", repo_path.qual.as_ref(), repo_path.name.as_ref()); + + if let Some(outcome) = analysis_outcome { + super::render_html(&title, render_success(outcome, repo_path)) + } else { + super::render_html(&title, render_failure(repo_path)) + } } diff --git a/src/server/views/mod.rs b/src/server/views/mod.rs index e965c6d..d399361 100644 --- a/src/server/views/mod.rs +++ b/src/server/views/mod.rs @@ -1,7 +1,4 @@ pub mod html; -mod status_json; -pub use self::status_json::status_json; - mod status_svg; pub use self::status_svg::status_svg; diff --git a/src/server/views/status_json.rs b/src/server/views/status_json.rs deleted file mode 100644 index 9d0a897..0000000 --- a/src/server/views/status_json.rs +++ /dev/null @@ -1,63 +0,0 @@ -use std::collections::BTreeMap; - -use hyper::Response; -use hyper::header::ContentType; -use semver::{Version, VersionReq}; -use serde_json; - -use ::engine::AnalyzeDependenciesOutcome; - -#[derive(Debug, Serialize)] -struct AnalyzeDependenciesResponseDetail { - required: VersionReq, - latest: Option, - outdated: bool -} - -#[derive(Debug, Serialize)] -struct AnalyzeDependenciesResponseSingle { - dependencies: BTreeMap, - #[serde(rename="dev-dependencies")] - dev_dependencies: BTreeMap, - #[serde(rename="build-dependencies")] - build_dependencies: BTreeMap -} - -#[derive(Debug, Serialize)] -struct AnalyzeDependenciesResponse { - crates: BTreeMap -} - -pub fn status_json(analysis_outcome: AnalyzeDependenciesOutcome) -> Response { - let crates = analysis_outcome.crates.into_iter().map(|(crate_name, analyzed_deps)| { - let single = AnalyzeDependenciesResponseSingle { - dependencies: analyzed_deps.main.into_iter() - .map(|(name, analyzed)| (name.into(), AnalyzeDependenciesResponseDetail { - outdated: analyzed.is_outdated(), - required: analyzed.required, - latest: analyzed.latest - })).collect(), - dev_dependencies: analyzed_deps.dev.into_iter() - .map(|(name, analyzed)| (name.into(), AnalyzeDependenciesResponseDetail { - outdated: analyzed.is_outdated(), - required: analyzed.required, - latest: analyzed.latest - })).collect(), - build_dependencies: analyzed_deps.build.into_iter() - .map(|(name, analyzed)| (name.into(), AnalyzeDependenciesResponseDetail { - outdated: analyzed.is_outdated(), - required: analyzed.required, - latest: analyzed.latest - })).collect() - }; - (crate_name.into(), single) - }); - - let multi = AnalyzeDependenciesResponse { - crates: crates.collect() - }; - - Response::new() - .with_header(ContentType::json()) - .with_body(serde_json::to_string(&multi).unwrap()) -}