Views: Removed global open of Tyxml.Html and switched to prefix -
.. there are too many common names in this modules scope, and code gets easier to understand .. also I don't think global open is a good idea in general for this kind of module, so better to fix this style now than be sorry later
This commit is contained in:
parent
ae5c5cb67d
commit
f8b17e6b17
1 changed files with 228 additions and 219 deletions
447
lib/views.ml
447
lib/views.ml
|
@ -1,26 +1,26 @@
|
||||||
open Tyxml.Html
|
module H = Tyxml.Html
|
||||||
|
|
||||||
let pp_ptime ppf ptime =
|
let pp_ptime ppf ptime =
|
||||||
let (y, m, d), ((hh, mm, ss), _) = Ptime.to_date_time ptime in
|
let (y, m, d), ((hh, mm, ss), _) = Ptime.to_date_time ptime in
|
||||||
Fmt.pf ppf "%04d-%02d-%02d %02d:%02d:%02dZ" y m d hh mm ss
|
Fmt.pf ppf "%04d-%02d-%02d %02d:%02d:%02dZ" y m d hh mm ss
|
||||||
|
|
||||||
let txtf fmt = Fmt.kstr txt fmt
|
let txtf fmt = Fmt.kstr H.txt fmt
|
||||||
let a_titlef fmt = Fmt.kstr a_title fmt
|
let a_titlef fmt = Fmt.kstr H.a_title fmt
|
||||||
|
|
||||||
let check_icon result =
|
let check_icon result =
|
||||||
match result with
|
match result with
|
||||||
| Builder.Exited 0 ->
|
| Builder.Exited 0 ->
|
||||||
span ~a:[
|
H.span ~a:H.[
|
||||||
a_style "color: green; cursor: pointer;";
|
a_style "color: green; cursor: pointer;";
|
||||||
a_titlef "%a" Builder.pp_execution_result result;
|
a_titlef "%a" Builder.pp_execution_result result;
|
||||||
]
|
]
|
||||||
[txt "☑"]
|
[H.txt "☑"]
|
||||||
| _ ->
|
| _ ->
|
||||||
span ~a:[
|
H.span ~a:H.[
|
||||||
a_style "color: red; cursor: pointer;";
|
a_style "color: red; cursor: pointer;";
|
||||||
a_titlef "%a" Builder.pp_execution_result result;
|
a_titlef "%a" Builder.pp_execution_result result;
|
||||||
]
|
]
|
||||||
[txt "☒"]
|
[H.txt "☒"]
|
||||||
|
|
||||||
type nav = [
|
type nav = [
|
||||||
| `Default
|
| `Default
|
||||||
|
@ -80,19 +80,22 @@ h1,h2,h3{line-height:1.2}
|
||||||
}
|
}
|
||||||
|}
|
|}
|
||||||
|
|
||||||
let layout ?include_static_css ?nav:(nav_=`Default) ~title:title_ body_ =
|
let layout ?include_static_css ?(nav=`Default) ~title body =
|
||||||
let breadcrumb =
|
let breadcrumb =
|
||||||
let to_nav kvs =
|
let to_nav kvs =
|
||||||
nav [ ul (List.map (fun (desc, href) ->
|
H.nav [
|
||||||
li [a ~a:[a_href href] [desc]])
|
H.ul (
|
||||||
kvs) ]
|
List.map (fun (desc, href) ->
|
||||||
|
H.li [H.a ~a:H.[a_href href] [desc]]
|
||||||
|
) kvs
|
||||||
|
)]
|
||||||
in
|
in
|
||||||
match nav_ with
|
match nav with
|
||||||
| `Default ->
|
| `Default ->
|
||||||
to_nav [txt "Home", "/"]
|
to_nav [H.txt "Home", "/"]
|
||||||
| `Job (job_name, platform) ->
|
| `Job (job_name, platform) ->
|
||||||
to_nav [
|
to_nav [
|
||||||
txt "Home", "/";
|
H.txt "Home", "/";
|
||||||
txtf "Job %s" job_name, Fmt.str "/job/%s/" job_name ;
|
txtf "Job %s" job_name, Fmt.str "/job/%s/" job_name ;
|
||||||
(
|
(
|
||||||
txtf "%a" pp_platform platform,
|
txtf "%a" pp_platform platform,
|
||||||
|
@ -101,7 +104,7 @@ let layout ?include_static_css ?nav:(nav_=`Default) ~title:title_ body_ =
|
||||||
]
|
]
|
||||||
| `Build (job_name, build) ->
|
| `Build (job_name, build) ->
|
||||||
to_nav [
|
to_nav [
|
||||||
txt "Home", "/";
|
H.txt "Home", "/";
|
||||||
txtf "Job %s" job_name, Fmt.str "/job/%s/" job_name;
|
txtf "Job %s" job_name, Fmt.str "/job/%s/" job_name;
|
||||||
(
|
(
|
||||||
txtf "%a" pp_platform (Some build.Builder_db.Build.platform),
|
txtf "%a" pp_platform (Some build.Builder_db.Build.platform),
|
||||||
|
@ -116,7 +119,7 @@ let layout ?include_static_css ?nav:(nav_=`Default) ~title:title_ body_ =
|
||||||
]
|
]
|
||||||
| `Comparison ((job_left, build_left), (job_right, build_right)) ->
|
| `Comparison ((job_left, build_left), (job_right, build_right)) ->
|
||||||
to_nav [
|
to_nav [
|
||||||
txt "Home", "/";
|
H.txt "Home", "/";
|
||||||
txtf "Comparison between %s@%a and %s@%a"
|
txtf "Comparison between %s@%a and %s@%a"
|
||||||
job_left pp_ptime build_left.Builder_db.Build.start
|
job_left pp_ptime build_left.Builder_db.Build.start
|
||||||
job_right pp_ptime build_right.Builder_db.Build.start,
|
job_right pp_ptime build_right.Builder_db.Build.start,
|
||||||
|
@ -128,32 +131,32 @@ let layout ?include_static_css ?nav:(nav_=`Default) ~title:title_ body_ =
|
||||||
(*> Note: Last declared CSS wins - so one can override here*)
|
(*> Note: Last declared CSS wins - so one can override here*)
|
||||||
let static_css = static_css :: Option.to_list include_static_css
|
let static_css = static_css :: Option.to_list include_static_css
|
||||||
in
|
in
|
||||||
html
|
H.html
|
||||||
(head (title (txt title_))
|
(H.head (H.title (H.txt title))
|
||||||
[style ~a:[a_mime_type "text/css"] static_css])
|
[H.style ~a:H.[a_mime_type "text/css"] static_css])
|
||||||
|
|
||||||
(body [
|
(H.body [
|
||||||
breadcrumb;
|
breadcrumb;
|
||||||
main body_
|
H.main body
|
||||||
])
|
])
|
||||||
|
|
||||||
let toggleable ?(hidden=true) id description content =
|
let toggleable ?(hidden=true) id description content =
|
||||||
let checked = if hidden then [] else [a_checked ()] in
|
let checked = if hidden then [] else H.[a_checked ()] in
|
||||||
div [
|
H.div [
|
||||||
label
|
H.label
|
||||||
~a:[
|
~a:H.[
|
||||||
a_label_for id;
|
a_label_for id;
|
||||||
a_class ["toggleable-descr"];
|
a_class ["toggleable-descr"];
|
||||||
]
|
]
|
||||||
[txt description];
|
[H.txt description];
|
||||||
input
|
H.input
|
||||||
~a:(checked @ [
|
~a:(checked @ H.[
|
||||||
a_input_type `Checkbox;
|
a_input_type `Checkbox;
|
||||||
a_id id;
|
a_id id;
|
||||||
a_style "display: none;";
|
a_style "display: none;";
|
||||||
]) ();
|
]) ();
|
||||||
div
|
H.div
|
||||||
~a:[
|
~a:H.[
|
||||||
a_class ["toggleable"]
|
a_class ["toggleable"]
|
||||||
]
|
]
|
||||||
content;
|
content;
|
||||||
|
@ -172,13 +175,13 @@ let artifact
|
||||||
Fpath.pp filepath
|
Fpath.pp filepath
|
||||||
in
|
in
|
||||||
[
|
[
|
||||||
a ~a:[a_href artifact_link]
|
H.a ~a:H.[a_href artifact_link]
|
||||||
[
|
[
|
||||||
if basename then txt (Fpath.basename filepath)
|
if basename then H.txt (Fpath.basename filepath)
|
||||||
else txtf "%a" Fpath.pp filepath
|
else txtf "%a" Fpath.pp filepath
|
||||||
];
|
];
|
||||||
txt " ";
|
H.txt " ";
|
||||||
code [txtf "SHA256:%a" Hex.pp (Hex.of_cstruct sha256)];
|
H.code [txtf "SHA256:%a" Hex.pp (Hex.of_cstruct sha256)];
|
||||||
txtf " (%a)" Fmt.byte_size size;
|
txtf " (%a)" Fmt.byte_size size;
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -187,34 +190,37 @@ module Builds = struct
|
||||||
let make section_job_map =
|
let make section_job_map =
|
||||||
layout ~title:"Reproducible OPAM builds"
|
layout ~title:"Reproducible OPAM builds"
|
||||||
([
|
([
|
||||||
h1 [txt "Reproducible OPAM builds"];
|
H.h1 [ H.txt "Reproducible OPAM builds" ];
|
||||||
p [ txt "This website offers binary MirageOS unikernels and \
|
H.p [ H.txt "This website offers binary MirageOS unikernels and \
|
||||||
supplementary OS packages." ];
|
supplementary OS packages." ];
|
||||||
p [ txt "Following is a list of jobs that are built daily. A \
|
H.p [
|
||||||
|
H.txt "Following is a list of jobs that are built daily. A \
|
||||||
persistent link to the latest successful build is available \
|
persistent link to the latest successful build is available \
|
||||||
as /job/*jobname*/build/latest/. All builds can be \
|
as /job/*jobname*/build/latest/. All builds can be \
|
||||||
reproduced with ";
|
reproduced with ";
|
||||||
a ~a:[a_href "https://github.com/roburio/orb/"] [txt "orb"];
|
H.a ~a:H.[a_href "https://github.com/roburio/orb/"]
|
||||||
txt ". The builds are scheduled and executed by ";
|
[H.txt "orb"];
|
||||||
a ~a:[a_href "https://github.com/roburio/builder/"] [txt "builder"];
|
H.txt ". The builds are scheduled and executed by ";
|
||||||
txt ". The web interface is ";
|
H.a ~a:H.[a_href "https://github.com/roburio/builder/"]
|
||||||
a ~a:[a_href "https://git.robur.io/robur/builder-web/"]
|
[H.txt "builder"];
|
||||||
[txt "builder-web"];
|
H.txt ". The web interface is ";
|
||||||
txt ". Contact team@robur.coop if you have any questions or \
|
H.a ~a:H.[a_href "https://git.robur.io/robur/builder-web/"]
|
||||||
|
[H.txt "builder-web"];
|
||||||
|
H.txt ". Contact team@robur.coop if you have any questions or \
|
||||||
suggestions.";
|
suggestions.";
|
||||||
];
|
];
|
||||||
form ~a:[a_action "/hash"; a_method `Get]
|
H.form ~a:H.[a_action "/hash"; a_method `Get]
|
||||||
[
|
[
|
||||||
label [
|
H.label [
|
||||||
txt "Search artifact by SHA256";
|
H.txt "Search artifact by SHA256";
|
||||||
br ();
|
H.br ();
|
||||||
input ~a:[
|
H.input ~a:H.[
|
||||||
a_input_type `Search;
|
a_input_type `Search;
|
||||||
a_id "sha256";
|
a_id "sha256";
|
||||||
a_name "sha256";
|
a_name "sha256";
|
||||||
] ();
|
] ();
|
||||||
];
|
];
|
||||||
input ~a:[
|
H.input ~a:H.[
|
||||||
a_input_type `Submit;
|
a_input_type `Submit;
|
||||||
a_value "Search";
|
a_value "Search";
|
||||||
] ();
|
] ();
|
||||||
|
@ -222,36 +228,37 @@ module Builds = struct
|
||||||
] @
|
] @
|
||||||
Utils.String_map.fold (fun section jobs acc ->
|
Utils.String_map.fold (fun section jobs acc ->
|
||||||
acc @ [
|
acc @ [
|
||||||
h2 [ txt section ];
|
H.h2 [ H.txt section ];
|
||||||
ul (List.map (fun (job_name, synopsis, platform_builds) ->
|
H.ul (List.map (fun (job_name, synopsis, platform_builds) ->
|
||||||
li ([
|
H.li ([
|
||||||
a ~a:[a_href ("job/" ^ job_name ^ "/")] [txt job_name];
|
H.a ~a:H.[a_href ("job/" ^ job_name ^ "/")]
|
||||||
br ();
|
[H.txt job_name];
|
||||||
txt (Option.value ~default:"" synopsis);
|
H.br ();
|
||||||
br ()
|
H.txt (Option.value ~default:"" synopsis);
|
||||||
|
H.br ()
|
||||||
] @ List.concat_map (fun (platform, latest_build, latest_artifact) ->
|
] @ List.concat_map (fun (platform, latest_build, latest_artifact) ->
|
||||||
[
|
[
|
||||||
check_icon latest_build.Builder_db.Build.result;
|
check_icon latest_build.Builder_db.Build.result;
|
||||||
txt " ";
|
H.txt " ";
|
||||||
a ~a:[
|
H.a ~a:[
|
||||||
Fmt.kstr a_href "job/%s/%a"
|
Fmt.kstr H.a_href "job/%s/%a"
|
||||||
job_name
|
job_name
|
||||||
pp_platform_query (Some platform)]
|
pp_platform_query (Some platform)]
|
||||||
[txt platform];
|
[H.txt platform];
|
||||||
txt " ";
|
H.txt " ";
|
||||||
a ~a:[
|
H.a ~a:[
|
||||||
Fmt.kstr a_href "job/%s/build/%a/"
|
Fmt.kstr H.a_href "job/%s/build/%a/"
|
||||||
job_name
|
job_name
|
||||||
Uuidm.pp latest_build.Builder_db.Build.uuid]
|
Uuidm.pp latest_build.Builder_db.Build.uuid]
|
||||||
[txtf "%a" pp_ptime latest_build.Builder_db.Build.start];
|
[txtf "%a" pp_ptime latest_build.Builder_db.Build.start];
|
||||||
txt " ";
|
H.txt " ";
|
||||||
] @ (match latest_artifact with
|
] @ (match latest_artifact with
|
||||||
| Some main_binary ->
|
| Some main_binary ->
|
||||||
artifact ~basename:true job_name latest_build main_binary
|
artifact ~basename:true job_name latest_build main_binary
|
||||||
| None ->
|
| None ->
|
||||||
[ txtf "Build failure: %a" Builder.pp_execution_result
|
[ txtf "Build failure: %a" Builder.pp_execution_result
|
||||||
latest_build.Builder_db.Build.result ]
|
latest_build.Builder_db.Build.result ]
|
||||||
) @ [ br () ]
|
) @ [ H.br () ]
|
||||||
)
|
)
|
||||||
platform_builds)
|
platform_builds)
|
||||||
)
|
)
|
||||||
|
@ -259,11 +266,11 @@ module Builds = struct
|
||||||
])
|
])
|
||||||
section_job_map
|
section_job_map
|
||||||
[] @
|
[] @
|
||||||
[ p [
|
[ H.p [
|
||||||
txt "View the latest failed builds ";
|
H.txt "View the latest failed builds ";
|
||||||
a ~a:[a_href "/failed-builds/"]
|
H.a ~a:H.[a_href "/failed-builds/"]
|
||||||
[txt "here"];
|
[H.txt "here"];
|
||||||
txt "."
|
H.txt "."
|
||||||
]])
|
]])
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -274,30 +281,30 @@ module Job = struct
|
||||||
layout
|
layout
|
||||||
~nav:(`Job (name, platform))
|
~nav:(`Job (name, platform))
|
||||||
~title:(Fmt.str "Job %s %a" name pp_platform platform)
|
~title:(Fmt.str "Job %s %a" name pp_platform platform)
|
||||||
((h1 [txtf "Job %s %a" name pp_platform platform] ::
|
((H.h1 [txtf "Job %s %a" name pp_platform platform] ::
|
||||||
(match readme with
|
(match readme with
|
||||||
| None -> []
|
| None -> []
|
||||||
| Some data ->
|
| Some data ->
|
||||||
[
|
[
|
||||||
h2 ~a:[a_id "readme"] [txt "README"];
|
H.h2 ~a:H.[a_id "readme"] [H.txt "README"];
|
||||||
a ~a:[a_href "#builds"] [txt "Skip to builds"];
|
H.a ~a:H.[a_href "#builds"] [H.txt "Skip to builds"];
|
||||||
Unsafe.data (Utils.Omd.html_of_string data)
|
H.Unsafe.data (Utils.Omd.html_of_string data)
|
||||||
])) @
|
])) @
|
||||||
[
|
[
|
||||||
h2 ~a:[a_id "builds"] [txt "Builds"];
|
H.h2 ~a:H.[a_id "builds"] [H.txt "Builds"];
|
||||||
a ~a:[a_href "#readme"] [txt "Back to readme"];
|
H.a ~a:H.[a_href "#readme"] [H.txt "Back to readme"];
|
||||||
ul (List.map (fun (build, main_binary) ->
|
H.ul (List.map (fun (build, main_binary) ->
|
||||||
li ([
|
H.li ([
|
||||||
check_icon build.Builder_db.Build.result;
|
check_icon build.Builder_db.Build.result;
|
||||||
txtf " %s " build.platform;
|
txtf " %s " build.platform;
|
||||||
a ~a:[
|
H.a ~a:H.[
|
||||||
Fmt.kstr a_href "/job/%s/build/%a/"
|
Fmt.kstr a_href "/job/%s/build/%a/"
|
||||||
name
|
name
|
||||||
Uuidm.pp build.Builder_db.Build.uuid ]
|
Uuidm.pp build.Builder_db.Build.uuid ]
|
||||||
[
|
[
|
||||||
txtf "%a" pp_ptime build.Builder_db.Build.start;
|
txtf "%a" pp_ptime build.Builder_db.Build.start;
|
||||||
];
|
];
|
||||||
txt " ";
|
H.txt " ";
|
||||||
] @ match main_binary with
|
] @ match main_binary with
|
||||||
| Some main_binary ->
|
| Some main_binary ->
|
||||||
artifact ~basename:true name build main_binary
|
artifact ~basename:true name build main_binary
|
||||||
|
@ -306,15 +313,15 @@ module Job = struct
|
||||||
build.Builder_db.Build.result ]))
|
build.Builder_db.Build.result ]))
|
||||||
builds);
|
builds);
|
||||||
if failed then
|
if failed then
|
||||||
p [
|
H.p [
|
||||||
txt "Excluding failed builds " ;
|
H.txt "Excluding failed builds " ;
|
||||||
a ~a:[a_href "../"] [txt "here"] ;
|
H.a ~a:H.[a_href "../"] [H.txt "here"] ;
|
||||||
txt "." ]
|
H.txt "." ]
|
||||||
else
|
else
|
||||||
p [
|
H.p [
|
||||||
txt "Including failed builds " ;
|
H.txt "Including failed builds " ;
|
||||||
a ~a:[a_href "failed/"] [txt "here"] ;
|
H.a ~a:H.[a_href "failed/"] [H.txt "here"] ;
|
||||||
txt "." ]
|
H.txt "." ]
|
||||||
])
|
])
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -338,48 +345,48 @@ module Job_build = struct
|
||||||
~latest ~next ~previous
|
~latest ~next ~previous
|
||||||
=
|
=
|
||||||
[
|
[
|
||||||
h2 ~a:[a_id "build"] [txtf "Build %a" pp_ptime build.start];
|
H.h2 ~a:H.[a_id "build"] [txtf "Build %a" pp_ptime build.start];
|
||||||
p [txtf "Built on platform %s" build.platform ];
|
H.p [txtf "Built on platform %s" build.platform ];
|
||||||
p [txtf "Build took %a." Ptime.Span.pp delta ];
|
H.p [txtf "Build took %a." Ptime.Span.pp delta ];
|
||||||
p [txtf "Execution result: %a." Builder.pp_execution_result build.result];
|
H.p [txtf "Execution result: %a." Builder.pp_execution_result build.result];
|
||||||
h3 [txt "Build info"];
|
H.h3 [H.txt "Build info"];
|
||||||
ul [
|
H.ul [
|
||||||
li [ a ~a:[Fmt.kstr a_href "/job/%s/build/%a/console" name Uuidm.pp build.uuid]
|
H.li [ H.a ~a:H.[Fmt.kstr a_href "/job/%s/build/%a/console" name Uuidm.pp build.uuid]
|
||||||
[txt "Console output"];
|
[H.txt "Console output"];
|
||||||
];
|
];
|
||||||
li [ a ~a:[Fmt.kstr a_href "/job/%s/build/%a/script" name Uuidm.pp build.uuid]
|
H.li [ H.a ~a:H.[Fmt.kstr a_href "/job/%s/build/%a/script" name Uuidm.pp build.uuid]
|
||||||
[txt "Build script"];
|
[H.txt "Build script"];
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
h3 [txt "Build artifacts"];
|
H.h3 [H.txt "Build artifacts"];
|
||||||
dl (List.concat_map
|
H.dl (List.concat_map
|
||||||
(fun { Builder_db.filepath; localpath=_; sha256; size } ->
|
(fun { Builder_db.filepath; localpath=_; sha256; size } ->
|
||||||
let (`Hex sha256_hex) = Hex.of_cstruct sha256 in
|
let (`Hex sha256_hex) = Hex.of_cstruct sha256 in
|
||||||
[
|
[
|
||||||
dt [a
|
H.dt [H.a
|
||||||
~a:[Fmt.kstr a_href "f/%a" Fpath.pp filepath]
|
~a:H.[Fmt.kstr a_href "f/%a" Fpath.pp filepath]
|
||||||
[code [txtf "%a" Fpath.pp filepath]]];
|
[H.code [txtf "%a" Fpath.pp filepath]]];
|
||||||
dd [
|
H.dd [
|
||||||
code [txt "SHA256:"; txt sha256_hex];
|
H.code [H.txt "SHA256:"; H.txt sha256_hex];
|
||||||
txtf " (%a)" Fmt.byte_size size;
|
txtf " (%a)" Fmt.byte_size size;
|
||||||
];
|
];
|
||||||
])
|
])
|
||||||
artifacts);
|
artifacts);
|
||||||
h3 [
|
H.h3 [
|
||||||
txtf "Reproduced by %d builds"
|
txtf "Reproduced by %d builds"
|
||||||
(List.length (same_input_same_output @ different_input_same_output))] ;
|
(List.length (same_input_same_output @ different_input_same_output))] ;
|
||||||
ul
|
H.ul
|
||||||
((List.map (fun { Builder_db.Build.start ; uuid ; platform ; _ } ->
|
((List.map (fun { Builder_db.Build.start ; uuid ; platform ; _ } ->
|
||||||
li [
|
H.li [
|
||||||
txtf "on %s, same input, " platform;
|
txtf "on %s, same input, " platform;
|
||||||
a ~a:[Fmt.kstr a_href "/job/%s/build/%a/" name Uuidm.pp uuid]
|
H.a ~a:H.[Fmt.kstr a_href "/job/%s/build/%a/" name Uuidm.pp uuid]
|
||||||
[txtf "%a" pp_ptime start]
|
[txtf "%a" pp_ptime start]
|
||||||
])
|
])
|
||||||
same_input_same_output) @
|
same_input_same_output) @
|
||||||
List.map (fun { Builder_db.Build.start ; uuid = other_uuid ; platform ; _ } ->
|
List.map (fun { Builder_db.Build.start ; uuid = other_uuid ; platform ; _ } ->
|
||||||
li [
|
H.li [
|
||||||
txtf "on %s, different input, " platform;
|
txtf "on %s, different input, " platform;
|
||||||
a ~a:[
|
H.a ~a:H.[
|
||||||
Fmt.kstr a_href "/compare/%a/%a/"
|
Fmt.kstr a_href "/compare/%a/%a/"
|
||||||
Uuidm.pp other_uuid
|
Uuidm.pp other_uuid
|
||||||
Uuidm.pp build.uuid]
|
Uuidm.pp build.uuid]
|
||||||
|
@ -390,12 +397,12 @@ module Job_build = struct
|
||||||
@ (if same_input_different_output = [] then
|
@ (if same_input_different_output = [] then
|
||||||
[]
|
[]
|
||||||
else
|
else
|
||||||
[ h3 [txt "Same input, different output (not reproducible!)"];
|
[ H.h3 [H.txt "Same input, different output (not reproducible!)"];
|
||||||
ul (
|
H.ul (
|
||||||
List.map (fun { Builder_db.Build.start ; uuid = other_uuid ; platform ; _ } ->
|
List.map (fun { Builder_db.Build.start ; uuid = other_uuid ; platform ; _ } ->
|
||||||
li [
|
H.li [
|
||||||
txtf "on %s, " platform ;
|
txtf "on %s, " platform ;
|
||||||
a ~a:[
|
H.a ~a:H.[
|
||||||
Fmt.kstr a_href "/compare/%a/%a/"
|
Fmt.kstr a_href "/compare/%a/%a/"
|
||||||
Uuidm.pp other_uuid
|
Uuidm.pp other_uuid
|
||||||
Uuidm.pp build.uuid]
|
Uuidm.pp build.uuid]
|
||||||
|
@ -405,18 +412,20 @@ module Job_build = struct
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@ [
|
@ [
|
||||||
h3 [txt "Comparisons with other builds on the same platform"];
|
H.h3 [H.txt "Comparisons with other builds on the same platform"];
|
||||||
let opt_build (ctx, build') =
|
let opt_build (ctx, build') =
|
||||||
match build' with
|
match build' with
|
||||||
| Some b when not (Uuidm.equal build.uuid b.Builder_db.Build.uuid) ->
|
| Some b when not (Uuidm.equal build.uuid b.Builder_db.Build.uuid) ->
|
||||||
[ li [ txt ctx;
|
[ H.li [ H.txt ctx;
|
||||||
a ~a:[Fmt.kstr a_href "/compare/%a/%a/"
|
H.a ~a:[
|
||||||
Uuidm.pp b.uuid Uuidm.pp build.uuid]
|
Fmt.kstr H.a_href "/compare/%a/%a/"
|
||||||
|
Uuidm.pp b.uuid
|
||||||
|
Uuidm.pp build.uuid ]
|
||||||
[txtf "%a" pp_ptime b.start]]
|
[txtf "%a" pp_ptime b.start]]
|
||||||
]
|
]
|
||||||
| _ -> []
|
| _ -> []
|
||||||
in
|
in
|
||||||
ul
|
H.ul
|
||||||
(List.concat_map opt_build
|
(List.concat_map opt_build
|
||||||
[ ("Latest build ", latest) ;
|
[ ("Latest build ", latest) ;
|
||||||
("Later build with different output ", next) ;
|
("Later build with different output ", next) ;
|
||||||
|
@ -443,19 +452,19 @@ module Job_build = struct
|
||||||
|
|
||||||
let make_viz_section ~name ~artifacts ~uuid =
|
let make_viz_section ~name ~artifacts ~uuid =
|
||||||
[
|
[
|
||||||
(* [ h3 [txt "Analysis"] ]; *)
|
(* [ H.h3 [txt "Analysis"] ]; *)
|
||||||
[ p [
|
[ H.p [
|
||||||
let src = Fmt.str "/job/%s/build/%a/vizdependencies" name Uuidm.pp uuid in
|
let src = Fmt.str "/job/%s/build/%a/vizdependencies" name Uuidm.pp uuid in
|
||||||
iframe ~a:[
|
H.iframe ~a:H.[
|
||||||
a_src src;
|
a_src src;
|
||||||
a_title "Opam dependencies";
|
a_title "Opam dependencies";
|
||||||
a_style viz_style_deps
|
a_style viz_style_deps
|
||||||
] []
|
] []
|
||||||
]];
|
]];
|
||||||
if not @@ contains_debug_bin artifacts then [] else [
|
if not @@ contains_debug_bin artifacts then [] else [
|
||||||
p [
|
H.p [
|
||||||
let src = Fmt.str "/job/%s/build/%a/viztreemap" name Uuidm.pp uuid in
|
let src = Fmt.str "/job/%s/build/%a/viztreemap" name Uuidm.pp uuid in
|
||||||
iframe ~a:[
|
H.iframe ~a:H.[
|
||||||
a_src src;
|
a_src src;
|
||||||
a_title "Binary dissection";
|
a_title "Binary dissection";
|
||||||
a_style viz_style_treemap
|
a_style viz_style_treemap
|
||||||
|
@ -485,26 +494,26 @@ module Job_build = struct
|
||||||
~same_input_different_output
|
~same_input_different_output
|
||||||
~latest ~next ~previous
|
~latest ~next ~previous
|
||||||
in
|
in
|
||||||
let style_grid = a_style "display: flex; " in
|
let style_grid = H.a_style "display: flex; " in
|
||||||
let style_grid_container = a_style "\
|
let style_grid_container = H.a_style "\
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
min-width: 83em;
|
min-width: 83em;
|
||||||
"
|
"
|
||||||
in
|
in
|
||||||
let style_col_container = a_style "" in
|
let style_col_container = H.a_style "" in
|
||||||
let style_col_left =
|
let style_col_left =
|
||||||
a_style "width: 45em; min-width: 43em; padding-left: 2%" in
|
H.a_style "width: 45em; min-width: 43em; padding-left: 2%" in
|
||||||
let style_col_right = a_style "width: 50%" in
|
let style_col_right = H.a_style "width: 50%" in
|
||||||
let body = [
|
let body = [
|
||||||
div ~a:[ style_grid_container ] [
|
H.div~a:[ style_grid_container ] [
|
||||||
div ~a:[ style_col_container ] [
|
H.div~a:[ style_col_container ] [
|
||||||
h1 [txtf "Job %s" name];
|
H.h1 [txtf "Job %s" name];
|
||||||
div ~a:[ style_grid ] [
|
H.div~a:[ style_grid ] [
|
||||||
(* div ~a:[ style_col_padding ] []; *)
|
(* H.div~a:H.[ style_col_padding ] []; *)
|
||||||
div ~a:[ style_col_left ] left_column;
|
H.div~a:[ style_col_left ] left_column;
|
||||||
div ~a:[ style_col_right ] right_column
|
H.div~a:[ style_col_right ] right_column
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -518,53 +527,53 @@ module Job_build = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
let key_values xs =
|
let key_values xs =
|
||||||
List.concat_map (fun (k, v) -> [ txtf "%s %s" k v ; br () ]) xs
|
List.concat_map (fun (k, v) -> [ txtf "%s %s" k v ; H.br () ]) xs
|
||||||
|
|
||||||
let key_value_changes xs =
|
let key_value_changes xs =
|
||||||
List.concat_map (fun (k, v, v') -> [ txtf "%s %s->%s" k v v' ; br () ]) xs
|
List.concat_map (fun (k, v, v') -> [ txtf "%s %s->%s" k v v' ; H.br () ]) xs
|
||||||
|
|
||||||
let packages packages =
|
let packages packages =
|
||||||
OpamPackage.Set.elements packages
|
OpamPackage.Set.elements packages
|
||||||
|> List.concat_map (fun p -> [
|
|> List.concat_map (fun p -> [
|
||||||
txtf "%a" Opamdiff.pp_opampackage p;
|
txtf "%a" Opamdiff.pp_opampackage p;
|
||||||
br ();
|
H.br ();
|
||||||
])
|
])
|
||||||
|
|
||||||
let package_diffs diffs =
|
let package_diffs diffs =
|
||||||
List.concat_map (fun pd -> [
|
List.concat_map (fun pd -> [
|
||||||
txtf "%a" Opamdiff.pp_version_diff pd;
|
txtf "%a" Opamdiff.pp_version_diff pd;
|
||||||
br ();
|
H.br ();
|
||||||
])
|
])
|
||||||
diffs
|
diffs
|
||||||
|
|
||||||
let opam_diffs diffs =
|
let opam_diffs diffs =
|
||||||
List.concat_map (fun pd ->
|
List.concat_map (fun pd ->
|
||||||
h4 [ txtf "%a" Opamdiff.pp_opam_diff pd ] ::
|
H.h4 [ txtf "%a" Opamdiff.pp_opam_diff pd ] ::
|
||||||
(match pd.Opamdiff.build with None -> [] | Some a ->
|
(match pd.Opamdiff.build with None -> [] | Some a ->
|
||||||
let l, r = Opamdiff.commands_to_strings a in
|
let l, r = Opamdiff.commands_to_strings a in
|
||||||
[
|
[
|
||||||
h5 [ txt "build instruction (without common prefix) modifications, old:" ] ;
|
H.h5 [ H.txt "build instruction (without common prefix) modifications, old:" ] ;
|
||||||
code (List.concat_map (fun s -> [ txt s ; br () ]) l) ;
|
H.code (List.concat_map (fun s -> [ H.txt s ; H.br () ]) l) ;
|
||||||
h5 [ txt "new" ] ;
|
H.h5 [ H.txt "new" ] ;
|
||||||
code (List.concat_map (fun s -> [ txt s ; br () ]) r)
|
H.code (List.concat_map (fun s -> [ H.txt s ; H.br () ]) r)
|
||||||
]) @
|
]) @
|
||||||
(match pd.Opamdiff.install with None -> [] | Some a ->
|
(match pd.Opamdiff.install with None -> [] | Some a ->
|
||||||
let l, r = Opamdiff.commands_to_strings a in
|
let l, r = Opamdiff.commands_to_strings a in
|
||||||
[
|
[
|
||||||
h5 [ txt "install instruction (without common prefix) modifications, old:" ] ;
|
H.h5 [ H.txt "install instruction (without common prefix) modifications, old:" ] ;
|
||||||
code (List.concat_map (fun s -> [ txt s ; br () ]) l) ;
|
H.code (List.concat_map (fun s -> [ H.txt s ; H.br () ]) l) ;
|
||||||
h5 [ txt "new" ] ;
|
H.h5 [ H.txt "new" ] ;
|
||||||
code (List.concat_map (fun s -> [ txt s ; br () ]) r)
|
H.code (List.concat_map (fun s -> [ H.txt s ; H.br () ]) r)
|
||||||
]) @
|
]) @
|
||||||
(match pd.Opamdiff.url with None -> [] | Some a ->
|
(match pd.Opamdiff.url with None -> [] | Some a ->
|
||||||
let l, r = Opamdiff.opt_url_to_string a in
|
let l, r = Opamdiff.opt_url_to_string a in
|
||||||
[
|
[
|
||||||
h5 [ txt "URL" ] ;
|
H.h5 [ H.txt "URL" ] ;
|
||||||
txtf "old: %s" l;
|
txtf "old: %s" l;
|
||||||
br ();
|
H.br ();
|
||||||
txtf "new: %s" r
|
txtf "new: %s" r
|
||||||
]) @
|
]) @
|
||||||
[ br () ])
|
[ H.br () ])
|
||||||
diffs
|
diffs
|
||||||
|
|
||||||
let compare_builds job_left job_right
|
let compare_builds job_left job_right
|
||||||
|
@ -577,10 +586,10 @@ let compare_builds job_left job_right
|
||||||
~title:(Fmt.str "Comparing builds %a and %a"
|
~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"];
|
H.h1 [H.txt "Comparing builds"];
|
||||||
h2 [
|
H.h2 [
|
||||||
txt "Builds ";
|
H.txt "Builds ";
|
||||||
a ~a:[a_href
|
H.a ~a:H.[a_href
|
||||||
(Fmt.str "/job/%s/build/%a/"
|
(Fmt.str "/job/%s/build/%a/"
|
||||||
job_left
|
job_left
|
||||||
Uuidm.pp build_left.uuid)]
|
Uuidm.pp build_left.uuid)]
|
||||||
|
@ -588,8 +597,8 @@ let compare_builds job_left job_right
|
||||||
job_left
|
job_left
|
||||||
pp_ptime build_left.start
|
pp_ptime build_left.start
|
||||||
pp_platform (Some build_left.platform)];
|
pp_platform (Some build_left.platform)];
|
||||||
txt " and ";
|
H.txt " and ";
|
||||||
a ~a:[a_href
|
H.a ~a:H.[a_href
|
||||||
(Fmt.str "/job/%s/build/%a/"
|
(Fmt.str "/job/%s/build/%a/"
|
||||||
job_right
|
job_right
|
||||||
Uuidm.pp build_right.uuid)]
|
Uuidm.pp build_right.uuid)]
|
||||||
|
@ -598,110 +607,110 @@ let compare_builds job_left job_right
|
||||||
pp_ptime build_right.start
|
pp_ptime build_right.start
|
||||||
pp_platform (Some build_right.platform)];
|
pp_platform (Some build_right.platform)];
|
||||||
];
|
];
|
||||||
h3 [ a ~a:[
|
H.h3 [ H.a ~a:H.[
|
||||||
Fmt.kstr a_href "/compare/%a/%a/"
|
Fmt.kstr a_href "/compare/%a/%a/"
|
||||||
Uuidm.pp build_right.uuid
|
Uuidm.pp build_right.uuid
|
||||||
Uuidm.pp build_left.uuid ]
|
Uuidm.pp build_left.uuid ]
|
||||||
[txt "Compare in reverse direction"]] ;
|
[H.txt "Compare in reverse direction"]] ;
|
||||||
ul [
|
H.ul [
|
||||||
li [
|
H.li [
|
||||||
a ~a:[a_href "#opam-packages-removed"]
|
H.a ~a:H.[a_href "#opam-packages-removed"]
|
||||||
[txtf "%d opam packages removed"
|
[txtf "%d opam packages removed"
|
||||||
(OpamPackage.Set.cardinal left)]
|
(OpamPackage.Set.cardinal left)]
|
||||||
];
|
];
|
||||||
li [
|
H.li [
|
||||||
a ~a:[a_href "#opam-packages-installed"]
|
H.a ~a:H.[a_href "#opam-packages-installed"]
|
||||||
[txtf "%d new opam packages installed"
|
[txtf "%d new opam packages installed"
|
||||||
(OpamPackage.Set.cardinal right)]
|
(OpamPackage.Set.cardinal right)]
|
||||||
];
|
];
|
||||||
li [
|
H.li [
|
||||||
a ~a:[a_href "#opam-packages-version-diff"]
|
H.a ~a:H.[a_href "#opam-packages-version-diff"]
|
||||||
[txtf "%d opam packages with version changes"
|
[txtf "%d opam packages with version changes"
|
||||||
(List.length version_diff)]
|
(List.length version_diff)]
|
||||||
];
|
];
|
||||||
li [
|
H.li [
|
||||||
a ~a:[a_href "#opam-packages-opam-diff"]
|
H.a ~a:H.[a_href "#opam-packages-opam-diff"]
|
||||||
[txtf "%d opam packages with changes in their opam file"
|
[txtf "%d opam packages with changes in their opam file"
|
||||||
(List.length opam_diff)]
|
(List.length opam_diff)]
|
||||||
];
|
];
|
||||||
li [
|
H.li [
|
||||||
a ~a:[a_href "#opam-packages-unchanged"]
|
H.a ~a:H.[a_href "#opam-packages-unchanged"]
|
||||||
[txtf "%d opam packages unchanged" (OpamPackage.Set.cardinal same)]
|
[txtf "%d opam packages unchanged" (OpamPackage.Set.cardinal same)]
|
||||||
];
|
];
|
||||||
li [
|
H.li [
|
||||||
a ~a:[a_href "#env-added"]
|
H.a ~a:H.[a_href "#env-added"]
|
||||||
[ txtf "%d environment variables added" (List.length added_env)]
|
[ txtf "%d environment variables added" (List.length added_env)]
|
||||||
];
|
];
|
||||||
li [
|
H.li [
|
||||||
a ~a:[a_href "#env-removed"]
|
H.a ~a:H.[a_href "#env-removed"]
|
||||||
[ txtf "%d environment variables removed" (List.length removed_env)]
|
[ txtf "%d environment variables removed" (List.length removed_env)]
|
||||||
];
|
];
|
||||||
li [
|
H.li [
|
||||||
a ~a:[a_href "#env-changed"]
|
H.a ~a:H.[a_href "#env-changed"]
|
||||||
[ txtf "%d environment variables changed" (List.length changed_env)]
|
[ txtf "%d environment variables changed" (List.length changed_env)]
|
||||||
];
|
];
|
||||||
li [
|
H.li [
|
||||||
a ~a:[a_href "#pkgs-added"]
|
H.a ~a:H.[a_href "#pkgs-added"]
|
||||||
[ txtf "%d system packages added" (List.length added_pkgs)]
|
[ txtf "%d system packages added" (List.length added_pkgs)]
|
||||||
];
|
];
|
||||||
li [
|
H.li [
|
||||||
a ~a:[a_href "#pkgs-removed"]
|
H.a ~a:H.[a_href "#pkgs-removed"]
|
||||||
[ txtf "%d system packages removed" (List.length removed_pkgs)]
|
[ txtf "%d system packages removed" (List.length removed_pkgs)]
|
||||||
];
|
];
|
||||||
li [
|
H.li [
|
||||||
a ~a:[a_href "#pkgs-changed"]
|
H.a ~a:H.[a_href "#pkgs-changed"]
|
||||||
[ txtf "%d system packages changed" (List.length changed_pkgs)]
|
[ txtf "%d system packages changed" (List.length changed_pkgs)]
|
||||||
];
|
];
|
||||||
];
|
];
|
||||||
h3 ~a:[a_id "opam-packages-removed"]
|
H.h3 ~a:H.[a_id "opam-packages-removed"]
|
||||||
[txt "Opam packages removed"];
|
[H.txt "Opam packages removed"];
|
||||||
code (packages left);
|
H.code (packages left);
|
||||||
h3 ~a:[a_id "opam-packages-installed"]
|
H.h3 ~a:H.[a_id "opam-packages-installed"]
|
||||||
[txt "New opam packages installed"];
|
[H.txt "New opam packages installed"];
|
||||||
code (packages right);
|
H.code (packages right);
|
||||||
h3 ~a:[a_id "opam-packages-version-diff"]
|
H.h3 ~a:H.[a_id "opam-packages-version-diff"]
|
||||||
[txt "Opam packages with version changes"];
|
[H.txt "Opam packages with version changes"];
|
||||||
code (package_diffs version_diff);
|
H.code (package_diffs version_diff);
|
||||||
h3 ~a:[a_id "opam-packages-opam-diff"]
|
H.h3 ~a:H.[a_id "opam-packages-opam-diff"]
|
||||||
[txt "Opam packages with changes in their opam file"]] @
|
[H.txt "Opam packages with changes in their opam file"]] @
|
||||||
opam_diffs opam_diff @ [
|
opam_diffs opam_diff @ [
|
||||||
h3 ~a:[a_id "opam-packages-unchanged"]
|
H.h3 ~a:H.[a_id "opam-packages-unchanged"]
|
||||||
[txt "Unchanged opam packages"];
|
[H.txt "Unchanged opam packages"];
|
||||||
code (packages same);
|
H.code (packages same);
|
||||||
h3 ~a:[a_id "env-added"] [txt "Environment variables added"];
|
H.h3 ~a:H.[a_id "env-added"] [H.txt "Environment variables added"];
|
||||||
code (key_values added_env);
|
H.code (key_values added_env);
|
||||||
h3 ~a:[a_id "env-removed"] [txt "Environment variables removed"];
|
H.h3 ~a:H.[a_id "env-removed"] [H.txt "Environment variables removed"];
|
||||||
code (key_values removed_env);
|
H.code (key_values removed_env);
|
||||||
h3 ~a:[a_id "env-changed"] [txt "Environment variables changed"];
|
H.h3 ~a:H.[a_id "env-changed"] [H.txt "Environment variables changed"];
|
||||||
code (key_value_changes changed_env);
|
H.code (key_value_changes changed_env);
|
||||||
h3 ~a:[a_id "pkgs-added"] [txt "System packages added"];
|
H.h3 ~a:H.[a_id "pkgs-added"] [H.txt "System packages added"];
|
||||||
code (key_values added_pkgs);
|
H.code (key_values added_pkgs);
|
||||||
h3 ~a:[a_id "pkgs-removed"] [txt "System packages removed"];
|
H.h3 ~a:H.[a_id "pkgs-removed"] [H.txt "System packages removed"];
|
||||||
code (key_values removed_pkgs);
|
H.code (key_values removed_pkgs);
|
||||||
h3 ~a:[a_id "pkgs-changed"] [txt "System packages changed"];
|
H.h3 ~a:H.[a_id "pkgs-changed"] [H.txt "System packages changed"];
|
||||||
code (key_value_changes changed_pkgs);
|
H.code (key_value_changes changed_pkgs);
|
||||||
])
|
])
|
||||||
|
|
||||||
let failed_builds ~start ~count builds =
|
let failed_builds ~start ~count builds =
|
||||||
let build (job_name, build) =
|
let build (job_name, build) =
|
||||||
li [
|
H.li [
|
||||||
check_icon build.Builder_db.Build.result;
|
check_icon build.Builder_db.Build.result;
|
||||||
txtf " %s %a " job_name pp_platform (Some build.platform);
|
txtf " %s %a " job_name pp_platform (Some build.platform);
|
||||||
a ~a:[Fmt.kstr a_href "/job/%s/build/%a/" job_name Uuidm.pp build.uuid]
|
H.a ~a:H.[Fmt.kstr a_href "/job/%s/build/%a/" job_name Uuidm.pp build.uuid]
|
||||||
[txtf "%a" pp_ptime build.start];
|
[txtf "%a" pp_ptime build.start];
|
||||||
txtf " %a" Builder.pp_execution_result build.result;
|
txtf " %a" Builder.pp_execution_result build.result;
|
||||||
]
|
]
|
||||||
in
|
in
|
||||||
layout ~title:"Failed builds"
|
layout ~title:"Failed builds"
|
||||||
([
|
([
|
||||||
h1 [txt "Failed builds"];
|
H.h1 [H.txt "Failed builds"];
|
||||||
ul (List.map build builds);
|
H.ul (List.map build builds);
|
||||||
p [ txtf "View the next %d failed builds " count;
|
H.p [ txtf "View the next %d failed builds " count;
|
||||||
a ~a:[
|
H.a ~a:H.[
|
||||||
Fmt.kstr a_href "/failed-builds/?count=%d&start=%d"
|
Fmt.kstr a_href "/failed-builds/?count=%d&start=%d"
|
||||||
count (start + count) ]
|
count (start + count) ]
|
||||||
[ txt "here"];
|
[ H.txt "here"];
|
||||||
txt ".";
|
H.txt ".";
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue