diff options
Diffstat (limited to 'third_party/gerrit-queue/frontend')
4 files changed, 223 insertions, 0 deletions
diff --git a/third_party/gerrit-queue/frontend/frontend.go b/third_party/gerrit-queue/frontend/frontend.go new file mode 100644 index 000000000000..2cc65423f0e6 --- /dev/null +++ b/third_party/gerrit-queue/frontend/frontend.go @@ -0,0 +1,113 @@ +package frontend + +import ( + "embed" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + + "html/template" + + "github.com/apex/log" + + "github.com/tweag/gerrit-queue/gerrit" + "github.com/tweag/gerrit-queue/misc" + "github.com/tweag/gerrit-queue/submitqueue" +) + +//go:embed templates +var templates embed.FS + +//loadTemplate loads a list of templates, relative to the templates root, and a +//FuncMap, and returns a template object +func loadTemplate(templateNames []string, funcMap template.FuncMap) (*template.Template, error) { + if len(templateNames) == 0 { + return nil, fmt.Errorf("templateNames can't be empty") + } + tmpl := template.New(templateNames[0]).Funcs(funcMap) + + for _, templateName := range templateNames { + r, err := templates.Open("/" + templateName) + if err != nil { + return nil, err + } + defer r.Close() + contents, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + tmpl, err = tmpl.Parse(string(contents)) + if err != nil { + return nil, err + } + } + + return tmpl, nil +} + +// MakeFrontend returns a http.Handler +func MakeFrontend(rotatingLogHandler *misc.RotatingLogHandler, gerritClient *gerrit.Client, runner *submitqueue.Runner) http.Handler { + projectName := gerritClient.GetProjectName() + branchName := gerritClient.GetBranchName() + + mux := http.NewServeMux() + mux.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) { + var wipSerie *gerrit.Serie = nil + HEAD := "" + currentlyRunning := runner.IsCurrentlyRunning() + + // don't trigger operations requiring a lock + if !currentlyRunning { + wipSerie = runner.GetWIPSerie() + HEAD = gerritClient.GetHEAD() + } + + funcMap := template.FuncMap{ + "changesetURL": func(changeset *gerrit.Changeset) string { + return gerritClient.GetChangesetURL(changeset) + }, + "levelToClasses": func(level log.Level) string { + switch level { + case log.DebugLevel: + return "text-muted" + case log.InfoLevel: + return "text-info" + case log.WarnLevel: + return "text-warning" + case log.ErrorLevel: + return "text-danger" + case log.FatalLevel: + return "text-danger" + default: + return "text-white" + } + }, + "fieldsToJSON": func(fields log.Fields) string { + jsonData, _ := json.Marshal(fields) + return string(jsonData) + }, + } + + tmpl := template.Must(loadTemplate([]string{ + "index.tmpl.html", + "serie.tmpl.html", + "changeset.tmpl.html", + }, funcMap)) + + tmpl.ExecuteTemplate(w, "index.tmpl.html", map[string]interface{}{ + // Config + "projectName": projectName, + "branchName": branchName, + + // State + "currentlyRunning": currentlyRunning, + "wipSerie": wipSerie, + "HEAD": HEAD, + + // History + "memory": rotatingLogHandler, + }) + }) + return mux +} diff --git a/third_party/gerrit-queue/frontend/templates/changeset.tmpl.html b/third_party/gerrit-queue/frontend/templates/changeset.tmpl.html new file mode 100644 index 000000000000..5d3997885c73 --- /dev/null +++ b/third_party/gerrit-queue/frontend/templates/changeset.tmpl.html @@ -0,0 +1,15 @@ +{{ define "changeset" }} +<tr> + <td>{{ .OwnerName }}</td> + <td> + <strong>{{ .Subject }}</strong> (<a href="{{ changesetURL . }}" target="_blank">#{{ .Number }}</a>)<br /> + <small><code>{{ .CommitID }}</code></small> + </td> + <td> + <span> + {{ if .IsVerified }}<span class="badge badge-success badge-pill">+1 (CI)</span>{{ end }} + {{ if .IsCodeReviewed }}<span class="badge badge-info badge-pill">+2 (CR)</span>{{ end }} + </span> + </td> +</tr> +{{ end }} \ No newline at end of file diff --git a/third_party/gerrit-queue/frontend/templates/index.tmpl.html b/third_party/gerrit-queue/frontend/templates/index.tmpl.html new file mode 100644 index 000000000000..e04c0a349dfc --- /dev/null +++ b/third_party/gerrit-queue/frontend/templates/index.tmpl.html @@ -0,0 +1,76 @@ +<!DOCTYPE html> +<html> +<head> + <title>Gerrit Submit Queue</title> + <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script> + <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha256-CjSoeELFOcH0/uxWu6mC/Vlrc1AARqbm/jiiImDGV3s=" crossorigin="anonymous"></script> + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha256-YLGeXaapI0/5IgZopewRJcFXomhRMlYYjugPLSyNjTY=" crossorigin="anonymous" /> +</head> +<body> + <nav class="navbar sticky-top navbar-expand-sm navbar-dark bg-dark"> + <div class="container"> + <a class="navbar-brand" href="#">Gerrit Submit Queue</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + <div class="collapse navbar-collapse" id="navbarSupportedContent"> + <ul class="navbar-nav mr-auto"> + <li class="nav-item"> + <a class="nav-link" href="#region-info">Info</a> + </li> + <li class="nav-item"> + <a class="nav-link" href="#region-wipserie">WIP Serie</a> + </li> + <li class="nav-item"> + <a class="nav-link" href="#region-log">Log</a> + </li> + </ul> + </div> + </div> + </nav> + <div class="container"> + <h2 id="region-info">Info</h2> + <table class="table"> + <tbody> + <tr> + <th scope="row">Project Name:</th> + <td>{{ .projectName }}</td> + </tr> + <tr> + <th scope="row">Branch Name:</th> + <td>{{ .branchName }}</td> + </tr> + <tr> + <th scope="row">Currently running:</th> + <td> + {{ if .currentlyRunning }}yes{{ else }}no{{ end }} + </td> + </tr> + <tr> + <th scope="row">HEAD:</th> + <td> + {{ if .HEAD }}{{ .HEAD }}{{ else }}-{{ end }} + </td> + </tr> + </tbody> + </table> + + <h2 id="region-wipserie">WIP Serie</h2> + {{ if .wipSerie }} + {{ block "serie" .wipSerie }}{{ end }} + {{ else }} + - + {{ end }} + + <h2 id="region-log">Log</h2> + {{ range $entry := .memory.Entries }} + <div class="d-flex flex-row bg-dark {{ levelToClasses $entry.Level }} text-monospace"> + <div class="p-2"><small>{{ $entry.Timestamp.Format "2006-01-02 15:04:05 UTC"}}</small></div> + <div class="p-2 flex-grow-1"><small><strong>{{ $entry.Message }}</strong></small></div> + </div> + <div class="bg-dark {{ levelToClasses $entry.Level }} text-monospace text-break" style="padding-left: 4rem"> + <small>{{ fieldsToJSON $entry.Fields }}</small> + </div> + {{ end }} +</body> +</html> diff --git a/third_party/gerrit-queue/frontend/templates/serie.tmpl.html b/third_party/gerrit-queue/frontend/templates/serie.tmpl.html new file mode 100644 index 000000000000..60f0c18113d7 --- /dev/null +++ b/third_party/gerrit-queue/frontend/templates/serie.tmpl.html @@ -0,0 +1,19 @@ +{{ define "serie" }} +<table class="table table-sm table-hover"> +<thead class="thead-light"> + <tr> + <th scope="col">Owner</th> + <th scope="col">Changeset</th> + <th scope="col">Flags</th> + </tr> +</thead> +<tbody> + <tr> + <td colspan="3" class="table-success">Serie with {{ len .ChangeSets }} changes</td> + </tr> + {{ range $changeset := .ChangeSets }} + {{ block "changeset" $changeset }}{{ end }} + {{ end }} +</tbody> +</table> +{{ end }} \ No newline at end of file |