aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2022-05-21 11:01:02 +0200
committerDmitry Vyukov <dvyukov@google.com>2022-05-23 11:53:38 +0200
commitecb7480009671f03b559ca19b0f4507f9e98e8e2 (patch)
tree7c0e76d54763df38b07defd26e9e8394a0d29a7f
parentc06b338683a7a14ed2e9db22c5b5dae9c5fa5db6 (diff)
pkg/html/pages: switch to go:embed
We use clumsy generate scripts that embed some static files. Switch to the new go:embed thing (added in Go 1.16): https://pkg.go.dev/embed It's much nicer, does not require separate generate step and does not lead to additional diffs in code reviews. go:embed can only embed "files read from the package directory or subdirectories", so we need to move these assets to the package dir.
-rw-r--r--Makefile2
l---------[-rw-r--r--]dashboard/app/static/common.js102
l---------[-rw-r--r--]dashboard/app/static/style.css301
-rw-r--r--pkg/html/pages/common.js101
-rwxr-xr-xpkg/html/pages/gen.sh14
-rw-r--r--pkg/html/pages/pages.go9
-rw-r--r--pkg/html/pages/style.css (renamed from pkg/html/pages/generated.go)108
7 files changed, 111 insertions, 526 deletions
diff --git a/Makefile b/Makefile
index 6a2fb7b57..18448309e 100644
--- a/Makefile
+++ b/Makefile
@@ -238,7 +238,7 @@ generate:
$(MAKE) format
generate_go: format_cpp
- $(GO) generate ./pkg/csource ./executor ./pkg/ifuzz ./pkg/build ./pkg/html/pages
+ $(GO) generate ./pkg/csource ./executor ./pkg/ifuzz ./pkg/build
generate_fidl:
ifeq ($(TARGETOS),fuchsia)
diff --git a/dashboard/app/static/common.js b/dashboard/app/static/common.js
index 95e6c8f61..7e926878f 100644..120000
--- a/dashboard/app/static/common.js
+++ b/dashboard/app/static/common.js
@@ -1,101 +1 @@
-// Copyright 2018 syzkaller project authors. All rights reserved.
-// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
-
-function sortTable(item, colName, conv, desc = false) {
- table = item.parentNode.parentNode.parentNode.parentNode;
- rows = table.rows;
- col = findColumnByName(rows[0].getElementsByTagName("th"), colName);
- values = [];
- for (i = 1; i < rows.length; i++)
- values.push([conv(rows[i].getElementsByTagName("td")[col].textContent), rows[i]]);
- if (desc)
- desc = !isSorted(values.slice().reverse())
- else
- desc = isSorted(values);
- values.sort(function(a, b) {
- if (a[0] == b[0]) return 0;
- if (desc && a[0] > b[0] || !desc && a[0] < b[0]) return -1;
- return 1;
- });
- for (i = 0; i < values.length; i++)
- table.tBodies[0].appendChild(values[i][1]);
- return false;
-}
-
-function findColumnByName(headers, colName) {
- for (i = 0; i < headers.length; i++) {
- if (headers[i].textContent == colName)
- return i;
- }
- return 0;
-}
-
-function isSorted(values) {
- for (i = 0; i < values.length - 1; i++) {
- if (values[i][0] > values[i + 1][0])
- return false;
- }
- return true;
-}
-
-function textSort(v) { return v == "" ? "zzz" : v.toLowerCase(); }
-function numSort(v) { return -parseInt(v); }
-function floatSort(v) { return -parseFloat(v); }
-function reproSort(v) { return v == "C" ? 0 : v == "syz" ? 1 : 2; }
-function patchedSort(v) { return v == "" ? -1 : parseInt(v); }
-function lineSort(v) { return -v.split(/\r\n|\r|\n/g).length }
-
-function timeSort(v) {
- if (v == "now")
- return 0;
- m = v.indexOf('m');
- h = v.indexOf('h');
- d = v.indexOf('d');
- if (m > 0 && h < 0)
- return parseInt(v);
- if (h > 0 && m > 0)
- return parseInt(v) * 60 + parseInt(v.substring(h + 1));
- if (d > 0 && h > 0)
- return parseInt(v) * 60 * 24 + parseInt(v.substring(d + 1)) * 60;
- if (d > 0)
- return parseInt(v) * 60 * 24;
- return 1000000000;
-}
-
-
-
-function findAncestorByClass (el, cls) {
- while ((el = el.parentElement) && !el.classList.contains(cls));
- return el;
-}
-
-function deleteInputGroup(node) {
- group = findAncestorByClass(node, "input-group")
- values = findAncestorByClass(group, "input-values")
- if (!values) {
- return false
- }
- count = values.querySelectorAll('.input-group').length
- if (count == 1) {
- // If it's the only input, just clear it.
- input = group.querySelector('input')
- input.value = ""
- } else {
- group.remove()
- }
- return false
-}
-
-function addInputGroup(node) {
- values = findAncestorByClass(node, "input-values")
- groups = values.querySelectorAll(".input-group")
- if (groups.length == 0) {
- // Something strange has happened.
- return false
- }
- lastGroup = groups[groups.length - 1]
- newGroup = lastGroup.cloneNode(true)
- newGroup.querySelector('input').value = ""
- values.insertBefore(newGroup, lastGroup.nextSibling)
- return false
-}
+../../../pkg/html/pages/common.js \ No newline at end of file
diff --git a/dashboard/app/static/style.css b/dashboard/app/static/style.css
index 7a2ca851a..08a4fd05b 100644..120000
--- a/dashboard/app/static/style.css
+++ b/dashboard/app/static/style.css
@@ -1,300 +1 @@
-#topbar {
- padding: 5px 10px;
- background: #E0EBF5;
-}
-
-#topbar a {
- color: #375EAB;
- text-decoration: none;
-}
-
-h1, h2, h3, h4 {
- margin: 0;
- padding: 0;
- color: #375EAB;
- font-weight: bold;
-}
-
-.navigation_tab {
- border: 1px solid black;
- padding: 4px;
- margin: 4px;
-}
-
-.navigation_tab_selected {
- font-weight: bold;
- border: 2px solid black;
- padding: 4px;
- margin: 4px;
-}
-
-.position_table .navigation {
- padding-top: 15px;
- padding-bottom: 6px;
-}
-
-table {
- border: 1px solid #ccc;
- margin: 20px 5px;
- border-collapse: collapse;
- white-space: nowrap;
- text-overflow: ellipsis;
- overflow: hidden;
-}
-
-table caption {
- font-weight: bold;
-}
-
-table td, table th {
- vertical-align: top;
- padding: 2px 8px;
- text-overflow: ellipsis;
- overflow: hidden;
-}
-
-.namespace {
- font-weight: bold;
- font-size: large;
- color: #375EAB;
-}
-
-.position_table {
- border: 0px;
- margin: 0px;
- width: 100%;
- border-collapse: collapse;
-}
-
-.position_table td, .position_table tr {
- vertical-align: center;
- padding: 0px;
-}
-
-.position_table .namespace_td {
- width: 100%;
- padding-top: 10px;
- padding-left: 20px;
-}
-
-.position_table .search {
- text-align: right;
-}
-
-.list_table td, .list_table th {
- border-left: 1px solid #ccc;
-}
-
-.list_table th {
- background: #F4F4F4;
-}
-
-.list_table tr:nth-child(2n) {
- background: #F4F4F4;
-}
-
-.list_table tr:hover {
- background: #ffff99;
-}
-
-.list_table .namespace {
- width: 100pt;
- max-width: 100pt;
-}
-
-.list_table .title {
- width: 350pt;
- max-width: 350pt;
-}
-
-.list_table .commit_list {
- width: 500pt;
- max-width: 500pt;
-}
-
-.list_table .tag {
- font-family: monospace;
- font-size: 8pt;
- max-width: 60pt;
-}
-
-.list_table .opts {
- width: 40pt;
- max-width: 40pt;
-}
-
-.list_table .status {
- width: 250pt;
- max-width: 250pt;
-}
-
-.list_table .patched {
- width: 60pt;
- max-width: 60pt;
- text-align: center;
-}
-
-.list_table .kernel {
- width: 80pt;
- max-width: 80pt;
-}
-
-.list_table .maintainers {
- width: 150pt;
- max-width: 150pt;
-}
-
-.list_table .result {
- width: 60pt;
- max-width: 60pt;
-}
-
-.list_table .stat {
- width: 55pt;
- font-family: monospace;
- text-align: right;
-}
-
-.list_table .bisect_status {
- width: 75pt;
- max-width: 75pt;
- font-family: monospace;
- text-align: right;
-}
-
-.list_table .date {
- width: 60pt;
- max-width: 60pt;
- font-family: monospace;
- text-align: right;
-}
-
-.list_table .stat_name {
- width: 150pt;
- max-width: 150pt;
- font-family: monospace;
-}
-
-.list_table .stat_value {
- width: 120pt;
- max-width: 120pt;
- font-family: monospace;
-}
-
-.bad {
- color: #f00;
- font-weight: bold;
-}
-
-.inactive {
- color: #888;
-}
-
-.plain {
- text-decoration: none;
-}
-
-textarea {
- width:100%;
- font-family: monospace;
-}
-
-.mono {
- font-family: monospace;
-}
-
-.info_link {
- color: #25a7db;
- text-decoration: none;
-}
-
-.page {
- position: relative;
- width: 100%;
-}
-
-aside {
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- width: 290px;
- margin-top: 5px;
-}
-
-.panel {
- border: 1px solid #aaa;
- border-radius: 5px;
- margin-bottom: 5px;
- margin-top: 5px;
-}
-
-.panel h1 {
- font-size: 16px;
- margin: 0;
- padding: 2px 8px;
-}
-
-.panel select {
- padding: 5px;
- border: 0;
- width: 100%;
-}
-
-.panel label {
- margin-left: 7px;
-}
-
-.main-content {
- position: absolute;
- top: 0;
- left: 300px;
- right: 5px;
- min-height: 200px;
- overflow: hidden;
-}
-
-.graph_help {
- position: absolute;
- top: 115px;
- left: 10px;
- z-index: 1;
- text-decoration: none;
- font-weight: bold;
- font-size: xx-large;
- color: blue;
-}
-
-#graph_div {
- height: 85vh;
-}
-
-#crash_div {
- align: left;
- width: 90%;
- height: 400px;
- margin: 0 0;
- overflow: scroll;
- border: 1px solid #777;
- padding: 0px;
- background: transparent;
-}
-
-#crash_div pre {
- margin: 1px;
-}
-
-.input-values {
- margin-left: 7px;
- margin-bottom: 7px;
-}
-
-.input-group {
- margin-top: 7px;
- margin-bottom: 7px;
- display: block;
-}
-
-.input-group button {
- width: 20pt;
-}
+../../../pkg/html/pages/style.css \ No newline at end of file
diff --git a/pkg/html/pages/common.js b/pkg/html/pages/common.js
new file mode 100644
index 000000000..95e6c8f61
--- /dev/null
+++ b/pkg/html/pages/common.js
@@ -0,0 +1,101 @@
+// Copyright 2018 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+function sortTable(item, colName, conv, desc = false) {
+ table = item.parentNode.parentNode.parentNode.parentNode;
+ rows = table.rows;
+ col = findColumnByName(rows[0].getElementsByTagName("th"), colName);
+ values = [];
+ for (i = 1; i < rows.length; i++)
+ values.push([conv(rows[i].getElementsByTagName("td")[col].textContent), rows[i]]);
+ if (desc)
+ desc = !isSorted(values.slice().reverse())
+ else
+ desc = isSorted(values);
+ values.sort(function(a, b) {
+ if (a[0] == b[0]) return 0;
+ if (desc && a[0] > b[0] || !desc && a[0] < b[0]) return -1;
+ return 1;
+ });
+ for (i = 0; i < values.length; i++)
+ table.tBodies[0].appendChild(values[i][1]);
+ return false;
+}
+
+function findColumnByName(headers, colName) {
+ for (i = 0; i < headers.length; i++) {
+ if (headers[i].textContent == colName)
+ return i;
+ }
+ return 0;
+}
+
+function isSorted(values) {
+ for (i = 0; i < values.length - 1; i++) {
+ if (values[i][0] > values[i + 1][0])
+ return false;
+ }
+ return true;
+}
+
+function textSort(v) { return v == "" ? "zzz" : v.toLowerCase(); }
+function numSort(v) { return -parseInt(v); }
+function floatSort(v) { return -parseFloat(v); }
+function reproSort(v) { return v == "C" ? 0 : v == "syz" ? 1 : 2; }
+function patchedSort(v) { return v == "" ? -1 : parseInt(v); }
+function lineSort(v) { return -v.split(/\r\n|\r|\n/g).length }
+
+function timeSort(v) {
+ if (v == "now")
+ return 0;
+ m = v.indexOf('m');
+ h = v.indexOf('h');
+ d = v.indexOf('d');
+ if (m > 0 && h < 0)
+ return parseInt(v);
+ if (h > 0 && m > 0)
+ return parseInt(v) * 60 + parseInt(v.substring(h + 1));
+ if (d > 0 && h > 0)
+ return parseInt(v) * 60 * 24 + parseInt(v.substring(d + 1)) * 60;
+ if (d > 0)
+ return parseInt(v) * 60 * 24;
+ return 1000000000;
+}
+
+
+
+function findAncestorByClass (el, cls) {
+ while ((el = el.parentElement) && !el.classList.contains(cls));
+ return el;
+}
+
+function deleteInputGroup(node) {
+ group = findAncestorByClass(node, "input-group")
+ values = findAncestorByClass(group, "input-values")
+ if (!values) {
+ return false
+ }
+ count = values.querySelectorAll('.input-group').length
+ if (count == 1) {
+ // If it's the only input, just clear it.
+ input = group.querySelector('input')
+ input.value = ""
+ } else {
+ group.remove()
+ }
+ return false
+}
+
+function addInputGroup(node) {
+ values = findAncestorByClass(node, "input-values")
+ groups = values.querySelectorAll(".input-group")
+ if (groups.length == 0) {
+ // Something strange has happened.
+ return false
+ }
+ lastGroup = groups[groups.length - 1]
+ newGroup = lastGroup.cloneNode(true)
+ newGroup.querySelector('input').value = ""
+ values.insertBefore(newGroup, lastGroup.nextSibling)
+ return false
+}
diff --git a/pkg/html/pages/gen.sh b/pkg/html/pages/gen.sh
deleted file mode 100755
index a326138b2..000000000
--- a/pkg/html/pages/gen.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2020 syzkaller project authors. All rights reserved.
-# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
-
-set -eu
-
-echo '// Code generated by pkg/html/html.go. DO NOT EDIT.' > generated.go
-echo 'package pages' >> generated.go
-echo 'const style = `' >> generated.go
-cat ../../../dashboard/app/static/style.css >> generated.go
-echo '`' >> generated.go
-echo 'const js = `' >> generated.go
-cat ../../../dashboard/app/static/common.js >> generated.go
-echo '`' >> generated.go
diff --git a/pkg/html/pages/pages.go b/pkg/html/pages/pages.go
index 0040c8617..51bc902c7 100644
--- a/pkg/html/pages/pages.go
+++ b/pkg/html/pages/pages.go
@@ -1,11 +1,10 @@
// Copyright 2022 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
-//go:generate ./gen.sh
-
package pages
import (
+ _ "embed" // for go:embed directives
"fmt"
"html/template"
"io/fs"
@@ -28,3 +27,9 @@ func getHeadTemplate() string {
const headTempl = `<style type="text/css" media="screen">%v</style><script>%v</script>`
return fmt.Sprintf(headTempl, style, js)
}
+
+//go:embed style.css
+var style string
+
+//go:embed common.js
+var js string
diff --git a/pkg/html/pages/generated.go b/pkg/html/pages/style.css
index 56f5e2d5f..7a2ca851a 100644
--- a/pkg/html/pages/generated.go
+++ b/pkg/html/pages/style.css
@@ -1,7 +1,3 @@
-// Code generated by pkg/html/html.go. DO NOT EDIT.
-package pages
-
-const style = `
#topbar {
padding: 5px 10px;
background: #E0EBF5;
@@ -302,107 +298,3 @@ aside {
.input-group button {
width: 20pt;
}
-`
-const js = `
-// Copyright 2018 syzkaller project authors. All rights reserved.
-// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
-
-function sortTable(item, colName, conv, desc = false) {
- table = item.parentNode.parentNode.parentNode.parentNode;
- rows = table.rows;
- col = findColumnByName(rows[0].getElementsByTagName("th"), colName);
- values = [];
- for (i = 1; i < rows.length; i++)
- values.push([conv(rows[i].getElementsByTagName("td")[col].textContent), rows[i]]);
- if (desc)
- desc = !isSorted(values.slice().reverse())
- else
- desc = isSorted(values);
- values.sort(function(a, b) {
- if (a[0] == b[0]) return 0;
- if (desc && a[0] > b[0] || !desc && a[0] < b[0]) return -1;
- return 1;
- });
- for (i = 0; i < values.length; i++)
- table.tBodies[0].appendChild(values[i][1]);
- return false;
-}
-
-function findColumnByName(headers, colName) {
- for (i = 0; i < headers.length; i++) {
- if (headers[i].textContent == colName)
- return i;
- }
- return 0;
-}
-
-function isSorted(values) {
- for (i = 0; i < values.length - 1; i++) {
- if (values[i][0] > values[i + 1][0])
- return false;
- }
- return true;
-}
-
-function textSort(v) { return v == "" ? "zzz" : v.toLowerCase(); }
-function numSort(v) { return -parseInt(v); }
-function floatSort(v) { return -parseFloat(v); }
-function reproSort(v) { return v == "C" ? 0 : v == "syz" ? 1 : 2; }
-function patchedSort(v) { return v == "" ? -1 : parseInt(v); }
-function lineSort(v) { return -v.split(/\r\n|\r|\n/g).length }
-
-function timeSort(v) {
- if (v == "now")
- return 0;
- m = v.indexOf('m');
- h = v.indexOf('h');
- d = v.indexOf('d');
- if (m > 0 && h < 0)
- return parseInt(v);
- if (h > 0 && m > 0)
- return parseInt(v) * 60 + parseInt(v.substring(h + 1));
- if (d > 0 && h > 0)
- return parseInt(v) * 60 * 24 + parseInt(v.substring(d + 1)) * 60;
- if (d > 0)
- return parseInt(v) * 60 * 24;
- return 1000000000;
-}
-
-
-
-function findAncestorByClass (el, cls) {
- while ((el = el.parentElement) && !el.classList.contains(cls));
- return el;
-}
-
-function deleteInputGroup(node) {
- group = findAncestorByClass(node, "input-group")
- values = findAncestorByClass(group, "input-values")
- if (!values) {
- return false
- }
- count = values.querySelectorAll('.input-group').length
- if (count == 1) {
- // If it's the only input, just clear it.
- input = group.querySelector('input')
- input.value = ""
- } else {
- group.remove()
- }
- return false
-}
-
-function addInputGroup(node) {
- values = findAncestorByClass(node, "input-values")
- groups = values.querySelectorAll(".input-group")
- if (groups.length == 0) {
- // Something strange has happened.
- return false
- }
- lastGroup = groups[groups.length - 1]
- newGroup = lastGroup.cloneNode(true)
- newGroup.querySelector('input').value = ""
- values.insertBefore(newGroup, lastGroup.nextSibling)
- return false
-}
-`