diff --git a/lib/views.ml b/lib/views.ml index 2394483..1e0f837 100644 --- a/lib/views.ml +++ b/lib/views.ml @@ -29,8 +29,10 @@ type nav = [ | `Comparison of (string * Builder_db.Build.t) * (string * Builder_db.Build.t) ] -let pp_platform = Fmt.(option ~none:(any "") (append (any "on ") string)) -let pp_platform_query = Fmt.(option ~none:(any "") (append (any "?platform=") string)) +let pp_platform = + Fmt.(option ~none:(any "") (append (any "on ") string)) +let pp_platform_query = + Fmt.(option ~none:(any "") (append (any "?platform=") string)) let static_css = Tyxml.Html.Unsafe.data {| body { @@ -89,14 +91,28 @@ let layout ?include_static_css ?nav:(nav_=`Default) ~title:title_ body_ = | `Default -> to_nav [txt "Home", "/"] | `Job (job_name, platform) -> - to_nav [txt "Home", "/"; txtf "Job %s" job_name, Fmt.str "/job/%s/" job_name ; txtf "%a" pp_platform platform, Fmt.str "/job/%s/%a" job_name pp_platform_query platform ] + to_nav [ + txt "Home", "/"; + txtf "Job %s" job_name, Fmt.str "/job/%s/" job_name ; + ( + txtf "%a" pp_platform platform, + Fmt.str "/job/%s/%a" job_name pp_platform_query platform + ) + ] | `Build (job_name, build) -> to_nav [ txt "Home", "/"; txtf "Job %s" job_name, Fmt.str "/job/%s/" job_name; - txtf "%a" pp_platform (Some build.Builder_db.Build.platform), Fmt.str "/job/%s/%a" job_name pp_platform_query (Some build.Builder_db.Build.platform); + ( + txtf "%a" pp_platform (Some build.Builder_db.Build.platform), + Fmt.str "/job/%s/%a" + job_name + pp_platform_query (Some build.Builder_db.Build.platform) + ); txtf "Build %a" pp_ptime build.Builder_db.Build.start, - Fmt.str "/job/%s/build/%a/" job_name Uuidm.pp build.Builder_db.Build.uuid; + Fmt.str "/job/%s/build/%a/" + job_name + Uuidm.pp build.Builder_db.Build.uuid; ] | `Comparison ((job_left, build_left), (job_right, build_right)) -> to_nav [ @@ -104,7 +120,9 @@ let layout ?include_static_css ?nav:(nav_=`Default) ~title:title_ body_ = txtf "Comparison between %s@%a and %s@%a" job_left pp_ptime build_left.Builder_db.Build.start job_right pp_ptime build_right.Builder_db.Build.start, - Fmt.str "/compare/%a/%a/" Uuidm.pp build_left.uuid Uuidm.pp build_right.uuid; + Fmt.str "/compare/%a/%a/" + Uuidm.pp build_left.uuid + Uuidm.pp build_right.uuid; ] in (*> Note: Last declared CSS wins - so one can override here*) @@ -112,7 +130,7 @@ let layout ?include_static_css ?nav:(nav_=`Default) ~title:title_ body_ = in html (head (title (txt title_)) - [style ~a:[a_mime_type "text/css"] static_css]) + [style ~a:[a_mime_type "text/css"] static_css]) (body [ breadcrumb; @@ -130,10 +148,10 @@ let toggleable ?(hidden=true) id description content = [txt description]; input ~a:(checked @ [ - a_input_type `Checkbox; - a_id id; - a_style "display: none;"; - ]) (); + a_input_type `Checkbox; + a_id id; + a_style "display: none;"; + ]) (); div ~a:[ a_class ["toggleable"] @@ -141,15 +159,24 @@ let toggleable ?(hidden=true) id description content = content; ] -let artifact ?(basename=false) job_name build { Builder_db.filepath; localpath = _; sha256; size } = +let artifact + ?(basename=false) + job_name + build + { Builder_db.filepath; localpath = _; sha256; size } + = + let artifact_link = + Fmt.str "/job/%s/build/%a/f/%a" + job_name + Uuidm.pp build.Builder_db.Build.uuid + Fpath.pp filepath + in [ - a ~a:[a_href (Fmt.str "/job/%s/build/%a/f/%a" - job_name - Uuidm.pp build.Builder_db.Build.uuid - Fpath.pp filepath)] - [if basename - then txt (Fpath.basename filepath) - else txtf "%a" Fpath.pp filepath]; + a ~a:[a_href artifact_link] + [ + if basename then txt (Fpath.basename filepath) + else txtf "%a" Fpath.pp filepath + ]; txt " "; code [txtf "SHA256:%a" Hex.pp (Hex.of_cstruct sha256)]; txtf " (%a)" Fmt.byte_size size; @@ -159,33 +186,40 @@ module Builds = struct let make section_job_map = layout ~title:"Reproducible OPAM builds" - ([ h1 [txt "Reproducible OPAM builds"]; - p [ txt "This website offers binary MirageOS unikernels and supplementary OS packages." ]; - p [ txt {|Following is a list of jobs that are built daily. A persistent link to the latest successful build is available as /job/*jobname*/build/latest/. All builds can be reproduced with |} ; - a ~a:[a_href "https://github.com/roburio/orb/"] [txt "orb"]; - txt ". The builds are scheduled and executed by "; - a ~a:[a_href "https://github.com/roburio/builder/"] [txt "builder"]; - txt ". The web interface is "; - a ~a:[a_href "https://git.robur.io/robur/builder-web/"] [txt "builder-web"]; - txt ". Contact team@robur.coop if you have any questions or suggestions."; - ]; - form ~a:[a_action "/hash"; a_method `Get] - [ - label [ - txt "Search artifact by SHA256"; - br (); - input ~a:[ - a_input_type `Search; - a_id "sha256"; - a_name "sha256"; - ] (); - ]; + ([ + h1 [txt "Reproducible OPAM builds"]; + p [ txt "This website offers binary MirageOS unikernels and \ + supplementary OS packages." ]; + p [ txt "Following is a list of jobs that are built daily. A \ + persistent link to the latest successful build is available \ + as /job/*jobname*/build/latest/. All builds can be \ + reproduced with "; + a ~a:[a_href "https://github.com/roburio/orb/"] [txt "orb"]; + txt ". The builds are scheduled and executed by "; + a ~a:[a_href "https://github.com/roburio/builder/"] [txt "builder"]; + txt ". The web interface is "; + a ~a:[a_href "https://git.robur.io/robur/builder-web/"] + [txt "builder-web"]; + txt ". Contact team@robur.coop if you have any questions or \ + suggestions."; + ]; + form ~a:[a_action "/hash"; a_method `Get] + [ + label [ + txt "Search artifact by SHA256"; + br (); input ~a:[ - a_input_type `Submit; - a_value "Search"; + a_input_type `Search; + a_id "sha256"; + a_name "sha256"; ] (); ]; - ] @ + input ~a:[ + a_input_type `Submit; + a_value "Search"; + ] (); + ]; + ] @ Utils.String_map.fold (fun section jobs acc -> acc @ [ h2 [ txt section ]; @@ -195,27 +229,32 @@ module Builds = struct br (); txt (Option.value ~default:"" synopsis); br () - ] @ - List.flatten - (List.map (fun (platform, latest_build, latest_artifact) -> - [ - check_icon latest_build.Builder_db.Build.result; - txt " "; - a ~a:[Fmt.kstr a_href "job/%s/%a" job_name pp_platform_query (Some platform)][txt platform]; - txt " "; - a ~a:[Fmt.kstr a_href "job/%s/build/%a/" job_name Uuidm.pp - latest_build.Builder_db.Build.uuid] - [txtf "%a" pp_ptime latest_build.Builder_db.Build.start]; - txt " "; - ] @ (match latest_artifact with - | Some main_binary -> - artifact ~basename:true job_name latest_build main_binary - | None -> - [ txtf "Build failure: %a" Builder.pp_execution_result - latest_build.Builder_db.Build.result ] - ) @ [ br () ]) - platform_builds) - )) + ] @ List.concat_map (fun (platform, latest_build, latest_artifact) -> + [ + check_icon latest_build.Builder_db.Build.result; + txt " "; + a ~a:[ + Fmt.kstr a_href "job/%s/%a" + job_name + pp_platform_query (Some platform)] + [txt platform]; + txt " "; + a ~a:[ + Fmt.kstr a_href "job/%s/build/%a/" + job_name + Uuidm.pp latest_build.Builder_db.Build.uuid] + [txtf "%a" pp_ptime latest_build.Builder_db.Build.start]; + txt " "; + ] @ (match latest_artifact with + | Some main_binary -> + artifact ~basename:true job_name latest_build main_binary + | None -> + [ txtf "Build failure: %a" Builder.pp_execution_result + latest_build.Builder_db.Build.result ] + ) @ [ br () ] + ) + platform_builds) + ) jobs) ]) section_job_map @@ -232,7 +271,9 @@ end module Job = struct let make ~failed name platform readme builds = - layout ~nav:(`Job (name, platform)) ~title:(Fmt.str "Job %s %a" name pp_platform platform) + layout + ~nav:(`Job (name, platform)) + ~title:(Fmt.str "Job %s %a" name pp_platform platform) ((h1 [txtf "Job %s %a" name pp_platform platform] :: (match readme with | None -> [] @@ -249,7 +290,10 @@ module Job = struct li ([ check_icon build.Builder_db.Build.result; txtf " %s " build.platform; - a ~a:[Fmt.kstr a_href "/job/%s/build/%a/" name Uuidm.pp build.Builder_db.Build.uuid] + a ~a:[ + Fmt.kstr a_href "/job/%s/build/%a/" + name + Uuidm.pp build.Builder_db.Build.uuid ] [ txtf "%a" pp_ptime build.Builder_db.Build.start; ]; @@ -262,9 +306,15 @@ module Job = struct build.Builder_db.Build.result ])) builds); if failed then - p [ txt "Excluding failed builds " ; a ~a:[a_href "../"] [txt "here"] ; txt "." ] + p [ + txt "Excluding failed builds " ; + a ~a:[a_href "../"] [txt "here"] ; + txt "." ] else - p [ txt "Including failed builds " ; a ~a:[a_href "failed/"] [txt "here"] ; txt "." ] + p [ + txt "Including failed builds " ; + a ~a:[a_href "failed/"] [txt "here"] ; + txt "." ] ]) end @@ -315,7 +365,9 @@ module Job_build = struct ]; ]) artifacts); - h3 [ txtf "Reproduced by %d builds" (List.length (same_input_same_output @ different_input_same_output))] ; + h3 [ + txtf "Reproduced by %d builds" + (List.length (same_input_same_output @ different_input_same_output))] ; ul ((List.map (fun { Builder_db.Build.start ; uuid ; platform ; _ } -> li [ @@ -327,8 +379,10 @@ module Job_build = struct List.map (fun { Builder_db.Build.start ; uuid = other_uuid ; platform ; _ } -> li [ txtf "on %s, different input, " platform; - a ~a:[Fmt.kstr a_href "/compare/%a/%a/" - Uuidm.pp other_uuid Uuidm.pp build.uuid] + a ~a:[ + Fmt.kstr a_href "/compare/%a/%a/" + Uuidm.pp other_uuid + Uuidm.pp build.uuid] [txtf "%a" pp_ptime start] ]) different_input_same_output) @@ -341,7 +395,10 @@ module Job_build = struct List.map (fun { Builder_db.Build.start ; uuid = other_uuid ; platform ; _ } -> li [ txtf "on %s, " platform ; - a ~a:[Fmt.kstr a_href "/compare/%a/%a/" Uuidm.pp other_uuid Uuidm.pp build.uuid] + a ~a:[ + Fmt.kstr a_href "/compare/%a/%a/" + Uuidm.pp other_uuid + Uuidm.pp build.uuid] [txtf "%a" pp_ptime start] ]) same_input_different_output) @@ -437,7 +494,8 @@ module Job_build = struct " in let style_col_container = a_style "" in - let style_col_left = a_style "width: 45em; min-width: 43em; padding-left: 2%" in + let style_col_left = + a_style "width: 45em; min-width: 43em; padding-left: 2%" in let style_col_right = a_style "width: 50%" in let body = [ div ~a:[ style_grid_container ] [ @@ -468,45 +526,45 @@ let key_value_changes xs = let packages packages = OpamPackage.Set.elements packages |> List.concat_map (fun p -> [ - txtf "%a" Opamdiff.pp_opampackage p; - br (); - ]) + txtf "%a" Opamdiff.pp_opampackage p; + br (); + ]) let package_diffs diffs = List.concat_map (fun pd -> [ - txtf "%a" Opamdiff.pp_version_diff pd; - br (); - ]) + txtf "%a" Opamdiff.pp_version_diff pd; + br (); + ]) diffs let opam_diffs diffs = List.concat_map (fun pd -> - h4 [ txtf "%a" Opamdiff.pp_opam_diff pd ] :: - (match pd.Opamdiff.build with None -> [] | Some a -> - let l, r = Opamdiff.commands_to_strings a in - [ - h5 [ txt "build instruction (without common prefix) modifications, old:" ] ; - code (List.concat_map (fun s -> [ txt s ; br () ]) l) ; - h5 [ txt "new" ] ; - code (List.concat_map (fun s -> [ txt s ; br () ]) r) - ]) @ - (match pd.Opamdiff.install with None -> [] | Some a -> - let l, r = Opamdiff.commands_to_strings a in - [ - h5 [ txt "install instruction (without common prefix) modifications, old:" ] ; - code (List.concat_map (fun s -> [ txt s ; br () ]) l) ; - h5 [ txt "new" ] ; - code (List.concat_map (fun s -> [ txt s ; br () ]) r) - ]) @ - (match pd.Opamdiff.url with None -> [] | Some a -> - let l, r = Opamdiff.opt_url_to_string a in - [ - h5 [ txt "URL" ] ; - txtf "old: %s" l; - br (); - txtf "new: %s" r - ]) @ - [ br () ]) + h4 [ txtf "%a" Opamdiff.pp_opam_diff pd ] :: + (match pd.Opamdiff.build with None -> [] | Some a -> + let l, r = Opamdiff.commands_to_strings a in + [ + h5 [ txt "build instruction (without common prefix) modifications, old:" ] ; + code (List.concat_map (fun s -> [ txt s ; br () ]) l) ; + h5 [ txt "new" ] ; + code (List.concat_map (fun s -> [ txt s ; br () ]) r) + ]) @ + (match pd.Opamdiff.install with None -> [] | Some a -> + let l, r = Opamdiff.commands_to_strings a in + [ + h5 [ txt "install instruction (without common prefix) modifications, old:" ] ; + code (List.concat_map (fun s -> [ txt s ; br () ]) l) ; + h5 [ txt "new" ] ; + code (List.concat_map (fun s -> [ txt s ; br () ]) r) + ]) @ + (match pd.Opamdiff.url with None -> [] | Some a -> + let l, r = Opamdiff.opt_url_to_string a in + [ + h5 [ txt "URL" ] ; + txtf "old: %s" l; + br (); + txtf "new: %s" r + ]) @ + [ br () ]) diffs let compare_builds job_left job_right @@ -517,68 +575,81 @@ let compare_builds job_left job_right layout ~nav:(`Comparison ((job_left, build_left), (job_right, build_right))) ~title:(Fmt.str "Comparing builds %a and %a" - Uuidm.pp build_left.uuid Uuidm.pp build_right.uuid) + Uuidm.pp build_left.uuid Uuidm.pp build_right.uuid) ([ h1 [txt "Comparing builds"]; h2 [ txt "Builds "; a ~a:[a_href - (Fmt.str "/job/%s/build/%a/" - job_left - Uuidm.pp build_left.uuid)] - [txtf "%s@%a %a" job_left pp_ptime build_left.start pp_platform (Some build_left.platform)]; + (Fmt.str "/job/%s/build/%a/" + job_left + Uuidm.pp build_left.uuid)] + [ txtf "%s@%a %a" + job_left + pp_ptime build_left.start + pp_platform (Some build_left.platform)]; txt " and "; a ~a:[a_href - (Fmt.str "/job/%s/build/%a/" - job_right - Uuidm.pp build_right.uuid)] - [txtf "%s@%a %a" job_right pp_ptime build_right.start pp_platform (Some build_right.platform)]; + (Fmt.str "/job/%s/build/%a/" + job_right + Uuidm.pp build_right.uuid)] + [ txtf "%s@%a %a" + job_right + pp_ptime build_right.start + pp_platform (Some build_right.platform)]; ]; - h3 [ a ~a:[Fmt.kstr a_href "/compare/%a/%a/" Uuidm.pp build_right.uuid Uuidm.pp build_left.uuid] - [txt "Compare in reverse direction"]] ; + h3 [ a ~a:[ + Fmt.kstr a_href "/compare/%a/%a/" + Uuidm.pp build_right.uuid + Uuidm.pp build_left.uuid ] + [txt "Compare in reverse direction"]] ; ul [ li [ a ~a:[a_href "#opam-packages-removed"] - [txtf "%d opam packages removed" (OpamPackage.Set.cardinal left)] + [txtf "%d opam packages removed" + (OpamPackage.Set.cardinal left)] ]; li [ a ~a:[a_href "#opam-packages-installed"] - [txtf "%d new opam packages installed" (OpamPackage.Set.cardinal right)] + [txtf "%d new opam packages installed" + (OpamPackage.Set.cardinal right)] ]; li [ a ~a:[a_href "#opam-packages-version-diff"] - [txtf "%d opam packages with version changes" (List.length version_diff)] + [txtf "%d opam packages with version changes" + (List.length version_diff)] ]; li [ a ~a:[a_href "#opam-packages-opam-diff"] - [txtf "%d opam packages with changes in their opam file" (List.length opam_diff)] + [txtf "%d opam packages with changes in their opam file" + (List.length opam_diff)] ]; li [ a ~a:[a_href "#opam-packages-unchanged"] [txtf "%d opam packages unchanged" (OpamPackage.Set.cardinal same)] ]; li [ - a ~a:[a_href "#env-added"] + a ~a:[a_href "#env-added"] [ txtf "%d environment variables added" (List.length added_env)] ]; li [ - a ~a:[a_href "#env-removed"] + a ~a:[a_href "#env-removed"] [ txtf "%d environment variables removed" (List.length removed_env)] ]; li [ - a ~a:[a_href "#env-changed"] + a ~a:[a_href "#env-changed"] [ txtf "%d environment variables changed" (List.length changed_env)] ]; li [ - a ~a:[a_href "#pkgs-added"] + a ~a:[a_href "#pkgs-added"] [ txtf "%d system packages added" (List.length added_pkgs)] ]; li [ - a ~a:[a_href "#pkgs-removed"] + a ~a:[a_href "#pkgs-removed"] [ txtf "%d system packages removed" (List.length removed_pkgs)] ]; li [ - a ~a:[a_href "#pkgs-changed"] + a ~a:[a_href "#pkgs-changed"] [ txtf "%d system packages changed" (List.length changed_pkgs)] ]; ]; @@ -593,23 +664,23 @@ let compare_builds job_left job_right code (package_diffs version_diff); h3 ~a:[a_id "opam-packages-opam-diff"] [txt "Opam packages with changes in their opam file"]] @ - opam_diffs opam_diff @ [ - h3 ~a:[a_id "opam-packages-unchanged"] - [txt "Unchanged opam packages"]; - code (packages same); - h3 ~a:[a_id "env-added"] [txt "Environment variables added"]; - code (key_values added_env); - h3 ~a:[a_id "env-removed"] [txt "Environment variables removed"]; - code (key_values removed_env); - h3 ~a:[a_id "env-changed"] [txt "Environment variables changed"]; - code (key_value_changes changed_env); - h3 ~a:[a_id "pkgs-added"] [txt "System packages added"]; - code (key_values added_pkgs); - h3 ~a:[a_id "pkgs-removed"] [txt "System packages removed"]; - code (key_values removed_pkgs); - h3 ~a:[a_id "pkgs-changed"] [txt "System packages changed"]; - code (key_value_changes changed_pkgs); - ]) + opam_diffs opam_diff @ [ + h3 ~a:[a_id "opam-packages-unchanged"] + [txt "Unchanged opam packages"]; + code (packages same); + h3 ~a:[a_id "env-added"] [txt "Environment variables added"]; + code (key_values added_env); + h3 ~a:[a_id "env-removed"] [txt "Environment variables removed"]; + code (key_values removed_env); + h3 ~a:[a_id "env-changed"] [txt "Environment variables changed"]; + code (key_value_changes changed_env); + h3 ~a:[a_id "pkgs-added"] [txt "System packages added"]; + code (key_values added_pkgs); + h3 ~a:[a_id "pkgs-removed"] [txt "System packages removed"]; + code (key_values removed_pkgs); + h3 ~a:[a_id "pkgs-changed"] [txt "System packages changed"]; + code (key_value_changes changed_pkgs); + ]) let failed_builds ~start ~count builds = let build (job_name, build) = @@ -622,12 +693,15 @@ let failed_builds ~start ~count builds = ] in layout ~title:"Failed builds" - ([ h1 [txt "Failed builds"]; - ul (List.map build builds); - p [ txtf "View the next %d failed builds " count; - a ~a:[Fmt.kstr a_href "/failed-builds/?count=%d&start=%d" count (start + count)] - [ txt "here"]; - txt "."; - ] + ([ + h1 [txt "Failed builds"]; + ul (List.map build builds); + p [ txtf "View the next %d failed builds " count; + a ~a:[ + Fmt.kstr a_href "/failed-builds/?count=%d&start=%d" + count (start + count) ] + [ txt "here"]; + txt "."; + ] ])