|
1 |
| -import {STATUS_DATA_URL} from "../urls"; |
2 |
| - |
3 |
| -import {getJson} from "../utils/requests"; |
4 |
| - |
5 |
| -interface Commit { |
6 |
| - sha: string; |
7 |
| - date: string; |
8 |
| - type: "Try" | "Master"; |
9 |
| -} |
10 |
| - |
11 |
| -interface BenchmarkStatus { |
12 |
| - name: string; |
13 |
| - error: string; |
14 |
| -} |
15 |
| - |
16 |
| -interface Step { |
17 |
| - step: string; |
18 |
| - is_done: boolean; |
19 |
| - expected_duration: number; |
20 |
| - current_progress: number; |
21 |
| -} |
22 |
| - |
23 |
| -/** |
24 |
| - * The `any` types in the interface below were chosen because the types are quite complex |
25 |
| - * on the Rust side (they are modeled with enums encoded in a way that is not so simple to model in |
26 |
| - * TS). |
27 |
| - */ |
28 |
| -interface CurrentState { |
29 |
| - artifact: any; |
30 |
| - progress: Step[]; |
31 |
| -} |
32 |
| - |
33 |
| -interface StatusResponse { |
34 |
| - last_commit: Commit | null; |
35 |
| - benchmarks: BenchmarkStatus[]; |
36 |
| - missing: Array<[Commit, any]>; |
37 |
| - current: CurrentState | null; |
38 |
| - most_recent_end: number | null; |
39 |
| -} |
40 |
| - |
41 |
| -function populate_data(data: StatusResponse) { |
42 |
| - let state_div = document.querySelector("#benchmark-state"); |
43 |
| - if (data.last_commit !== null) { |
44 |
| - let element = document.createElement("p"); |
45 |
| - element.innerHTML = `SHA: ${data.last_commit.sha}, date: ${data.last_commit.date}`; |
46 |
| - state_div.appendChild(element); |
47 |
| - } |
48 |
| - for (let benchmark of data.benchmarks) { |
49 |
| - let element = document.createElement("div"); |
50 |
| - element.innerHTML = `<details open> |
51 |
| - <summary>${benchmark.name} - error</summary> |
52 |
| - <pre class="benchmark-error"></pre> |
53 |
| - </details>`; |
54 |
| - element.querySelector<HTMLElement>(".benchmark-error").innerText = |
55 |
| - benchmark.error; |
56 |
| - state_div.appendChild(element); |
57 |
| - } |
58 |
| - let missing_div = document.querySelector("#data-insert-js"); |
59 |
| - if (data.current !== null) { |
60 |
| - let table = document.createElement("table"); |
61 |
| - let tr = document.createElement("tr"); |
62 |
| - let th = document.createElement("th"); |
63 |
| - th.innerText = "Step"; |
64 |
| - tr.appendChild(th); |
65 |
| - th = document.createElement("th"); |
66 |
| - tr.appendChild(th); |
67 |
| - th = document.createElement("th"); |
68 |
| - th.innerText = "Took"; |
69 |
| - tr.appendChild(th); |
70 |
| - th = document.createElement("th"); |
71 |
| - th.innerText = "Expected"; |
72 |
| - tr.appendChild(th); |
73 |
| - table.appendChild(tr); |
74 |
| - |
75 |
| - let left = 0; |
76 |
| - for (let step of data.current.progress) { |
77 |
| - let tr = document.createElement("tr"); |
78 |
| - let td = document.createElement("td"); |
79 |
| - td.innerText = step.step; |
80 |
| - tr.appendChild(td); |
81 |
| - td = document.createElement("td"); |
82 |
| - let progress = document.createElement("progress"); |
83 |
| - progress.setAttribute("max", step.expected_duration.toString()); |
84 |
| - progress.setAttribute( |
85 |
| - "value", |
86 |
| - (step.is_done |
87 |
| - ? step.expected_duration |
88 |
| - : step.current_progress |
89 |
| - ).toString() |
90 |
| - ); |
91 |
| - td.appendChild(progress); |
92 |
| - tr.appendChild(td); |
93 |
| - td = document.createElement("td"); |
94 |
| - td.innerHTML = |
95 |
| - step.current_progress == 0 |
96 |
| - ? "" |
97 |
| - : format_duration(step.current_progress); |
98 |
| - td.style.textAlign = "right"; |
99 |
| - tr.appendChild(td); |
100 |
| - td = document.createElement("td"); |
101 |
| - td.innerHTML = format_duration(step.expected_duration); |
102 |
| - td.style.textAlign = "right"; |
103 |
| - tr.appendChild(td); |
104 |
| - if (!step.is_done) { |
105 |
| - left += step.expected_duration - step.current_progress; |
106 |
| - } |
107 |
| - table.appendChild(tr); |
108 |
| - } |
109 |
| - let element = document.createElement("p"); |
110 |
| - let artifact_desc = ""; |
111 |
| - if (data.current.artifact.Commit) { |
112 |
| - artifact_desc = commit_url(data.current.artifact.Commit); |
113 |
| - } else { |
114 |
| - artifact_desc = data.current.artifact.Tag; |
115 |
| - } |
116 |
| - element.innerHTML = `Currently benchmarking: ${artifact_desc}. |
117 |
| - <br>Time left: ${format_duration(left)}`; |
118 |
| - missing_div.appendChild(element); |
119 |
| - missing_div.appendChild(table); |
120 |
| - } else { |
121 |
| - let element = document.createElement("p"); |
122 |
| - if (data.most_recent_end) { |
123 |
| - let end = new Date(data.most_recent_end * 1000); |
124 |
| - element.innerHTML = `No current collection in progress. Last one |
125 |
| - finished at ${end.toLocaleString()} local time, |
126 |
| - ${format_duration( |
127 |
| - Math.trunc((Date.now() - end.getTime()) / 1000) |
128 |
| - )} ago.`; |
129 |
| - } else { |
130 |
| - element.innerHTML = "No current collection in progress."; |
131 |
| - } |
132 |
| - missing_div.appendChild(element); |
133 |
| - } |
134 |
| - { |
135 |
| - let element = document.createElement("p"); |
136 |
| - element.innerHTML = `Queue (${data.missing.length} total):<br> Times are local.`; |
137 |
| - missing_div.appendChild(element); |
138 |
| - } |
139 |
| - let table = document.createElement("table"); |
140 |
| - table.id = "missing-commits"; |
141 |
| - { |
142 |
| - let row = document.createElement("tr"); |
143 |
| - row.innerHTML = `<th>Commit Date</th><th>SHA</th><th>Reason</th>`; |
144 |
| - table.appendChild(row); |
145 |
| - } |
146 |
| - for (let [commit, reason] of data.missing) { |
147 |
| - let row = document.createElement("tr"); |
148 |
| - { |
149 |
| - let date = new Date(commit.date); |
150 |
| - let element = document.createElement("td"); |
151 |
| - if (date.getUTCFullYear() == 2001) { |
152 |
| - element.innerHTML = "try commit"; |
153 |
| - element.style.textAlign = "center"; |
154 |
| - } else { |
155 |
| - element.innerHTML = new Date(commit.date).toLocaleString(); |
156 |
| - } |
157 |
| - row.appendChild(element); |
158 |
| - } |
159 |
| - { |
160 |
| - let element = document.createElement("td"); |
161 |
| - element.innerHTML = commit_url(commit); |
162 |
| - row.appendChild(element); |
163 |
| - } |
164 |
| - { |
165 |
| - let element = document.createElement("td"); |
166 |
| - element.innerHTML = reason_to_string(reason); |
167 |
| - row.appendChild(element); |
168 |
| - } |
169 |
| - table.appendChild(row); |
170 |
| - } |
171 |
| - missing_div.appendChild(table); |
172 |
| -} |
173 |
| - |
174 |
| -function reason_to_string(reason) { |
175 |
| - if (typeof reason == "string") { |
176 |
| - return reason; |
177 |
| - } else if (reason.InProgress) { |
178 |
| - return `${reason_to_string(reason.InProgress)} - in progress`; |
179 |
| - } else if (reason["Master"] != undefined && reason.Master.pr) { |
180 |
| - return `<a href="https://github.com/rust-lang/rust/pull/${ |
181 |
| - reason["Master"].pr |
182 |
| - }"> |
183 |
| - #${reason["Master"].pr}</a>${ |
184 |
| - reason.Master.is_try_parent ? " - Try commit parent" : "" |
185 |
| - }`; |
186 |
| - } else if (reason["Master"] != undefined && reason.Master.pr == 0) { |
187 |
| - return "Master"; |
188 |
| - } else if (reason["Try"] != undefined && reason.Try.pr) { |
189 |
| - return ` |
190 |
| - Try for |
191 |
| - <a href="https://github.com/rust-lang/rust/pull/${reason["Try"].pr}"> |
192 |
| - #${reason["Try"].pr} |
193 |
| - </a>`; |
194 |
| - } else { |
195 |
| - // Should never happen, but a good fallback |
196 |
| - return JSON.stringify(reason); |
197 |
| - } |
198 |
| -} |
199 |
| - |
200 |
| -function commit_url(commit) { |
201 |
| - return `<a href="https://github.com/rust-lang/rust/commit/${ |
202 |
| - commit.sha |
203 |
| - }">${commit.sha.substr(0, 13)}</a>`; |
204 |
| -} |
205 |
| - |
206 |
| -function format_duration(seconds) { |
207 |
| - let secs = seconds % 60; |
208 |
| - let mins = Math.trunc(seconds / 60); |
209 |
| - let hours = Math.trunc(mins / 60); |
210 |
| - mins -= hours * 60; |
211 |
| - |
212 |
| - let s = ""; |
213 |
| - if (hours > 0) { |
214 |
| - s = `${hours}h${mins < 10 ? "0" + mins : mins}m${ |
215 |
| - secs < 10 ? "0" + secs : secs |
216 |
| - }s`; |
217 |
| - } else { |
218 |
| - s = `${mins < 10 ? " " + mins : mins}m${secs < 10 ? "0" + secs : secs}s`; |
219 |
| - } |
220 |
| - return s; |
221 |
| -} |
222 |
| - |
223 |
| -async function make_data() { |
224 |
| - const response = await getJson<StatusResponse>(STATUS_DATA_URL); |
225 |
| - populate_data(response); |
226 |
| -} |
227 |
| - |
228 |
| -make_data(); |
| 1 | +import Status from "./status/page.vue"; |
| 2 | +import {createApp} from "vue"; |
| 3 | +import WithSuspense from "../components/with-suspense.vue"; |
| 4 | + |
| 5 | +const app = createApp(WithSuspense, { |
| 6 | + component: Status, |
| 7 | +}); |
| 8 | +app.mount("#app"); |
0 commit comments