Reformat everything
This commit is contained in:
parent
93663fff8c
commit
36ce75b43d
12 changed files with 560 additions and 526 deletions
|
|
@ -5,11 +5,13 @@ Run benchmarks against commits in a git repo and present their results.
|
||||||
## Building from source
|
## Building from source
|
||||||
|
|
||||||
The following tools are required:
|
The following tools are required:
|
||||||
|
|
||||||
- `cargo` and `rustc` (best installed via [rustup](https://rustup.rs/))
|
- `cargo` and `rustc` (best installed via [rustup](https://rustup.rs/))
|
||||||
- `tsc`, the [typescript](https://www.typescriptlang.org/) compiler
|
- `tsc`, the [typescript](https://www.typescriptlang.org/) compiler
|
||||||
|
|
||||||
Once you have installed these tools, run the following command to install or
|
Once you have installed these tools, run the following command to install or
|
||||||
update tablejohn to `~/.cargo/bin/tablejohn`:
|
update tablejohn to `~/.cargo/bin/tablejohn`:
|
||||||
|
|
||||||
```
|
```
|
||||||
cargo install --force --git https://github.com/Garmelon/tablejohn
|
cargo install --force --git https://github.com/Garmelon/tablejohn
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,9 @@ export class Commits {
|
||||||
|
|
||||||
update(response: CommitsResponse) {
|
update(response: CommitsResponse) {
|
||||||
console.assert(response.hashByHash.length == response.authorByHash.length);
|
console.assert(response.hashByHash.length == response.authorByHash.length);
|
||||||
console.assert(response.hashByHash.length == response.committerDateByHash.length);
|
console.assert(
|
||||||
|
response.hashByHash.length == response.committerDateByHash.length,
|
||||||
|
);
|
||||||
console.assert(response.hashByHash.length == response.summaryByHash.length);
|
console.assert(response.hashByHash.length == response.summaryByHash.length);
|
||||||
|
|
||||||
let commits = this.#loadCommits(response);
|
let commits = this.#loadCommits(response);
|
||||||
|
|
@ -36,15 +38,18 @@ export class Commits {
|
||||||
commit.indexByGraph = idx;
|
commit.indexByGraph = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
const committerDatesNormal = commits.map(c => c.committerDate);
|
const committerDatesNormal = commits.map((c) => c.committerDate);
|
||||||
const committerDatesDayEquidistant = this.#makeDayEquidistant(committerDatesNormal);
|
const committerDatesDayEquidistant =
|
||||||
|
this.#makeDayEquidistant(committerDatesNormal);
|
||||||
|
|
||||||
// To prevent exceptions and other weirdness from messing up our state,
|
// To prevent exceptions and other weirdness from messing up our state,
|
||||||
// we update everything in one go.
|
// we update everything in one go.
|
||||||
this.#graphId = response.graphId;
|
this.#graphId = response.graphId;
|
||||||
this.#commitsByGraph = commits;
|
this.#commitsByGraph = commits;
|
||||||
this.#committerDatesNormal = this.#epochTimesToDates(committerDatesNormal);
|
this.#committerDatesNormal = this.#epochTimesToDates(committerDatesNormal);
|
||||||
this.#committerDatesDayEquidistant = this.#epochTimesToDates(committerDatesDayEquidistant);
|
this.#committerDatesDayEquidistant = this.#epochTimesToDates(
|
||||||
|
committerDatesDayEquidistant,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#loadCommits(response: CommitsResponse): Commit[] {
|
#loadCommits(response: CommitsResponse): Commit[] {
|
||||||
|
|
@ -95,7 +100,7 @@ export class Commits {
|
||||||
*/
|
*/
|
||||||
#sortCommitsTopologically(commits: Commit[]): Commit[] {
|
#sortCommitsTopologically(commits: Commit[]): Commit[] {
|
||||||
const visited: Set<string> = new Set();
|
const visited: Set<string> = new Set();
|
||||||
const visiting: Commit[] = commits.filter(c => c.parents.length == 0);
|
const visiting: Commit[] = commits.filter((c) => c.parents.length == 0);
|
||||||
|
|
||||||
const sorted: Commit[] = [];
|
const sorted: Commit[] = [];
|
||||||
|
|
||||||
|
|
@ -128,7 +133,7 @@ export class Commits {
|
||||||
* Assumes the times are sorted.
|
* Assumes the times are sorted.
|
||||||
*/
|
*/
|
||||||
#makeDayEquidistant(times: number[]): number[] {
|
#makeDayEquidistant(times: number[]): number[] {
|
||||||
const days: { day: number, amount: number; }[] = [];
|
const days: { day: number; amount: number }[] = [];
|
||||||
for (const time of times) {
|
for (const time of times) {
|
||||||
const day = time % SECONDS_PER_DAY;
|
const day = time % SECONDS_PER_DAY;
|
||||||
const prev = days.at(-1);
|
const prev = days.at(-1);
|
||||||
|
|
@ -152,6 +157,6 @@ export class Commits {
|
||||||
}
|
}
|
||||||
|
|
||||||
#epochTimesToDates(times: number[]): Date[] {
|
#epochTimesToDates(times: number[]): Date[] {
|
||||||
return times.map(t => new Date(1000 * t));
|
return times.map((t) => new Date(1000 * t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,28 +23,43 @@ class Folder {
|
||||||
}
|
}
|
||||||
|
|
||||||
toHtmlElement(name: string): HTMLElement {
|
toHtmlElement(name: string): HTMLElement {
|
||||||
if (this.children.size > 0) { // Folder
|
if (this.children.size > 0) {
|
||||||
|
// Folder
|
||||||
name = `${name}/`;
|
name = `${name}/`;
|
||||||
if (this.metric === null) { // Folder without metric
|
if (this.metric === null) {
|
||||||
return el("details", { "class": "no-metric" },
|
// Folder without metric
|
||||||
|
return el(
|
||||||
|
"details",
|
||||||
|
{ class: "no-metric" },
|
||||||
el("summary", {}, name),
|
el("summary", {}, name),
|
||||||
this.childrenToHtmlElements(),
|
this.childrenToHtmlElements(),
|
||||||
);
|
);
|
||||||
} else { // Folder with metric
|
} else {
|
||||||
return el("details", {},
|
// Folder with metric
|
||||||
el("summary", {},
|
return el(
|
||||||
el("input", { "type": "checkbox", "name": this.metric }),
|
"details",
|
||||||
" ", name,
|
{},
|
||||||
|
el(
|
||||||
|
"summary",
|
||||||
|
{},
|
||||||
|
el("input", { type: "checkbox", name: this.metric }),
|
||||||
|
" ",
|
||||||
|
name,
|
||||||
),
|
),
|
||||||
this.childrenToHtmlElements(),
|
this.childrenToHtmlElements(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if (this.metric !== null) { // Normal metric
|
} else if (this.metric !== null) {
|
||||||
return el("label", {},
|
// Normal metric
|
||||||
el("input", { "type": "checkbox", "name": this.metric }),
|
return el(
|
||||||
" ", name,
|
"label",
|
||||||
|
{},
|
||||||
|
el("input", { type: "checkbox", name: this.metric }),
|
||||||
|
" ",
|
||||||
|
name,
|
||||||
);
|
);
|
||||||
} else { // Metric without metric, should never happen
|
} else {
|
||||||
|
// Metric without metric, should never happen
|
||||||
return el("label", {}, name);
|
return el("label", {}, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -69,7 +84,8 @@ export class Metrics {
|
||||||
getSelected(): Set<string> {
|
getSelected(): Set<string> {
|
||||||
const selected = new Set<string>();
|
const selected = new Set<string>();
|
||||||
|
|
||||||
const checkedInputs = this.#div.querySelectorAll<HTMLInputElement>("input:checked");
|
const checkedInputs =
|
||||||
|
this.#div.querySelectorAll<HTMLInputElement>("input:checked");
|
||||||
for (const input of checkedInputs) {
|
for (const input of checkedInputs) {
|
||||||
selected.add(input.name);
|
selected.add(input.name);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ export type CommitsResponse = {
|
||||||
export type MeasurementsResponse = {
|
export type MeasurementsResponse = {
|
||||||
graphId: number;
|
graphId: number;
|
||||||
dataId: number;
|
dataId: number;
|
||||||
measurements: { [key: string]: (number | null)[]; };
|
measurements: { [key: string]: (number | null)[] };
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getData<R>(url: string): Promise<R> {
|
async function getData<R>(url: string): Promise<R> {
|
||||||
|
|
@ -41,7 +41,9 @@ export async function getCommits(): Promise<CommitsResponse> {
|
||||||
return getData("commits");
|
return getData("commits");
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getMeasurements(metrics: string[]): Promise<MeasurementsResponse> {
|
export async function getMeasurements(
|
||||||
const params = new URLSearchParams(metrics.map(m => ["metric", m]));
|
metrics: string[],
|
||||||
|
): Promise<MeasurementsResponse> {
|
||||||
|
const params = new URLSearchParams(metrics.map((m) => ["metric", m]));
|
||||||
return getData(`measurements?${params}`);
|
return getData(`measurements?${params}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
/**
|
/**
|
||||||
* Create an {@link HTMLElement}.
|
* Create an {@link HTMLElement}.
|
||||||
*/
|
*/
|
||||||
export function el(name: string, attributes: { [key: string]: string; }, ...children: (string | Node)[]) {
|
export function el(
|
||||||
|
name: string,
|
||||||
|
attributes: { [key: string]: string },
|
||||||
|
...children: (string | Node)[]
|
||||||
|
) {
|
||||||
let element = document.createElement(name);
|
let element = document.createElement(name);
|
||||||
for (let [name, value] of Object.entries(attributes)) {
|
for (let [name, value] of Object.entries(attributes)) {
|
||||||
element.setAttribute(name, value);
|
element.setAttribute(name, value);
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,14 @@ const REFRESH_SECONDS = 10;
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
fetch("inner")
|
fetch("inner")
|
||||||
.then(response => response.text())
|
.then((response) => response.text())
|
||||||
.then(text => {
|
.then((text) => {
|
||||||
INNER.innerHTML = text;
|
INNER.innerHTML = text;
|
||||||
let count = document.getElementById("queue")?.dataset["count"]!;
|
let count = document.getElementById("queue")?.dataset["count"]!;
|
||||||
document.title = document.title.replace(/^queue \(\S+\)/, `queue (${count})`);
|
document.title = document.title.replace(
|
||||||
|
/^queue \(\S+\)/,
|
||||||
|
`queue (${count})`,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: .7em;
|
margin: 0.7em;
|
||||||
}
|
}
|
||||||
|
|
||||||
details,
|
details,
|
||||||
|
|
@ -20,7 +20,7 @@ ul {
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 1.7em;
|
font-size: 1.7em;
|
||||||
margin: 1em 0 .5em;
|
margin: 1em 0 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
|
@ -33,7 +33,7 @@ a:hover {
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
padding: 0 .5ch;
|
padding: 0 0.5ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.linkish {
|
button.linkish {
|
||||||
|
|
@ -45,17 +45,17 @@ button.linkish {
|
||||||
}
|
}
|
||||||
|
|
||||||
details {
|
details {
|
||||||
padding: .3em 1ch;
|
padding: 0.3em 1ch;
|
||||||
background-color: #ddd;
|
background-color: #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
details>summary {
|
details > summary {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
list-style: "> " inside;
|
list-style: "> " inside;
|
||||||
}
|
}
|
||||||
|
|
||||||
details[open]>summary {
|
details[open] > summary {
|
||||||
list-style: "v " inside;
|
list-style: "v " inside;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,12 +88,11 @@ tbody tr:hover {
|
||||||
|
|
||||||
th,
|
th,
|
||||||
td {
|
td {
|
||||||
padding: .1em 0;
|
padding: 0.1em 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
th+th,
|
th + th,
|
||||||
td+td {
|
td + td {
|
||||||
padding-left: 2ch;
|
padding-left: 2ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,28 +109,28 @@ nav {
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav>* {
|
nav > * {
|
||||||
padding: 0 1ch;
|
padding: 0 1ch;
|
||||||
border-right: 0.1em solid black;
|
border-right: 0.1em solid black;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav>:first-child img {
|
nav > :first-child img {
|
||||||
width: 1.2em;
|
width: 1.2em;
|
||||||
height: 1.2em;
|
height: 1.2em;
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
padding-right: 0.3em;
|
padding-right: 0.3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav>:first-child {
|
nav > :first-child {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav>:last-child {
|
nav > :last-child {
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav>.current {
|
nav > .current {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,17 +169,17 @@ nav a:hover {
|
||||||
.graph-container #plot {
|
.graph-container #plot {
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
box-shadow: 0 0 .5em black;
|
box-shadow: 0 0 0.5em black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.graph-container #metrics {
|
.graph-container #metrics {
|
||||||
flex: 0 50ch;
|
flex: 0 50ch;
|
||||||
box-shadow: 0 0 .5em black;
|
box-shadow: 0 0 0.5em black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.metrics-list {
|
.metrics-list {
|
||||||
background-color: #ddd;
|
background-color: #ddd;
|
||||||
padding: .3em 1ch;
|
padding: 0.3em 1ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.metrics-list * {
|
.metrics-list * {
|
||||||
|
|
@ -190,7 +189,7 @@ nav a:hover {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.metrics-list details[open]>summary {
|
.metrics-list details[open] > summary {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,14 +197,14 @@ nav a:hover {
|
||||||
width: 2ch;
|
width: 2ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.metrics-list details.no-metric>summary {
|
.metrics-list details.no-metric > summary {
|
||||||
list-style: "-> " outside;
|
list-style: "-> " outside;
|
||||||
margin-left: 3ch;
|
margin-left: 3ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.metrics-list summary~* {
|
.metrics-list summary ~ * {
|
||||||
border-left: .1ch solid black;
|
border-left: 0.1ch solid black;
|
||||||
margin-left: .9ch;
|
margin-left: 0.9ch;
|
||||||
padding-left: 1ch;
|
padding-left: 1ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,7 +239,9 @@ nav a:hover {
|
||||||
column-gap: 1ch;
|
column-gap: 1ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commit-like dl, .commit-like dt, .commit-like dd {
|
.commit-like dl,
|
||||||
|
.commit-like dt,
|
||||||
|
.commit-like dd {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
{ // See also https://aka.ms/tsconfig
|
{
|
||||||
"include": [ "scripts/**/*" ],
|
// See also https://aka.ms/tsconfig
|
||||||
|
"include": ["scripts/**/*"],
|
||||||
|
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2022", // Should be fine according to caniuse.com
|
"target": "ES2022", // Should be fine according to caniuse.com
|
||||||
|
|
@ -19,6 +20,6 @@
|
||||||
"noImplicitOverride": true,
|
"noImplicitOverride": true,
|
||||||
"noPropertyAccessFromIndexSignature": true,
|
"noPropertyAccessFromIndexSignature": true,
|
||||||
"noUncheckedIndexedAccess": true,
|
"noUncheckedIndexedAccess": true,
|
||||||
"strict": true,
|
"strict": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue