Implementation of /badge/commit/<commit>.

pull/1/head
ALI Hamza 2019-08-12 23:13:53 +07:00
parent 63a1cad8d4
commit 99695a4c4d
No known key found for this signature in database
GPG Key ID: 7C608266BF384ADC
6 changed files with 154 additions and 55 deletions

@ -0,0 +1,57 @@
package main
import (
"fmt"
"github.com/gorilla/mux"
"net/http"
"text/template"
)
var baseTemplate *template.Template
func init() {
baseTemplate = template.New("svgTemplate")
baseTemplate, _ = baseTemplate.Parse(svgTemplate)
}
func BadgeFromCommit(w http.ResponseWriter, r *http.Request) {
fmt.Println(mux.Vars(r))
commitID := mux.Vars(r)["commit"]
result, _ := db.Query("SELECT percentage FROM badge WHERE commit_hash=?", commitID)
defer result.Close()
w.Header().Set("Content-Type", "image/svg+xml")
if !result.Next() {
http.Error(w, "Request commit hash has no corresponding badge", 400)
//TODO send unknown svg instead
return
}
var percentage float64
result.Scan(&percentage)
fillColour := percentageToRGB(percentage)
template.New("svgConv")
pill := CoveragePill{
toOneDecimal(percentage * 100),
baseColour,
fillColour,
}
baseTemplate.Execute(w, pill)
}
func BadgeFromProject(w http.ResponseWriter, r *http.Request) {
projectName := mux.Vars(r)["project"]
tagName := mux.Vars(r)["tag"]
result, _ := db.Query("SELECT commit_hash FROM alias WHERE project_name=? AND project_tag=?", projectName, tagName)
defer result.Close()
var commit_hash string
result.Scan(&commit_hash)
fmt.Println(commit_hash)
mux.Vars(r)["commit"] = commit_hash
BadgeFromCommit(w, r)
}

@ -0,0 +1,22 @@
package main
import (
"database/sql"
_ "github.com/mattn/go-sqlite3"
)
var db *sql.DB
var alreadyUsingMemory bool
func init() {
openDatabase("./database.sqlite")
}
func openDatabase(fileLocation string) {
db, _ = sql.Open("sqlite3", fileLocation)
db.SetMaxOpenConns(1)
// Initializes the tables
db.Exec(`CREATE TABLE IF NOT EXISTS badge (commit_hash VARCHAR(32) NOT NULL UNIQUE PRIMARY KEY, percentage FLOAT NOT NULL)`)
db.Exec(`CREATE TABLE IF NOT EXISTS alias (commit_hash VARCHAR(32) NOT NULL UNIQUE PRIMARY KEY, project_name TEXT NOT NULL, project_tag TEXT NOT NULL)`)
}

Binary file not shown.

@ -1,69 +1,36 @@
package main package main
import ( import (
"bytes"
"fmt" "fmt"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"io/ioutil"
"net/http" "net/http"
) "strconv"
"strings"
const (
baseColour = "#555"
modifier float64 = 0.2
maxValue = 220
blue = 55
) )
func main() { func main() {
//_ := template.New("svgConv")
//percentage := 0.999
//fill := percentageToRGB(percentage)
//_ := CoveragePill{
// fmt.Sprintf("%.1f", toFixed(percentage, 3)*100),
// baseColour,
// fill,
//}
r := mux.NewRouter() r := mux.NewRouter()
r.HandleFunc("/upload/go", upload) r.HandleFunc("/upload/go", uploadGo)
r.HandleFunc("/badge/commit/{commit}.svg", BadgeFromCommit)
r.HandleFunc("/badge/{project}/{tag}.svg", BadgeFromProject)
_ = http.ListenAndServe(":8080", r) _ = http.ListenAndServe(":8080", r)
} }
func upload(w http.ResponseWriter, r *http.Request) { func parseCoverage(content string) float64 {
if r.Method != "POST" { var totalStatements = 0
return var totalRun = 0
}
err := r.ParseForm() lines := strings.Split(content, "\n")
if err != nil { for _, line := range lines[1 : len(lines)-1] { // Skip first line (which is not relevant)
http.Error(w, "Request parameters not parsed", 500) sl := strings.Split(line, " ")
return statements, _ := strconv.Atoi(sl[len(sl)-2])
} runCount, _ := strconv.Atoi(sl[len(sl)-1])
err = r.ParseMultipartForm(5 << 20)
if err != nil {
http.Error(w, "Request parameters not parsed", 500)
return
}
form := r.Form
project := form.Get("project")
tag := form.Get("tag")
id := form.Get("id")
file, _, err := r.FormFile("file")
b, _ := ioutil.ReadAll(file)
n := bytes.Index(b, []byte{0})
content := string(b[n])
fmt.Print(content) totalStatements += statements
if runCount != 0 {
if project == "" || tag == "" || id == "" { totalRun += statements
http.Error(w, "Request parameters [secret, project, tag, id] not found", 400)
return
} }
}
_, _ = fmt.Fprintf(w, "project: '%s'\ntag: '%s'\nid: '%s'\n", project, tag, id) fmt.Printf("DEBUG :: TotalStatements: %d, TotalRunCount: %d\n", totalStatements, totalRun)
return float64(totalRun) / float64(totalStatements)
} }

@ -1,6 +1,7 @@
package main package main
import ( import (
"fmt"
"math" "math"
"strconv" "strconv"
) )
@ -26,6 +27,13 @@ const svgTemplate string = `<?xml version="1.0" encoding="UTF-8"?>
</g> </g>
</svg>` </svg>`
const (
baseColour = "#555"
modifier float64 = 0.2
maxValue = 220
blue = 55
)
type CoveragePill struct { type CoveragePill struct {
Percentage string Percentage string
BaseColour string BaseColour string
@ -57,7 +65,7 @@ func round(num float64) int {
return int(num + math.Copysign(0.5, num)) return int(num + math.Copysign(0.5, num))
} }
func toFixed(num float64, precision int) float64 { func toOneDecimal(num float64) string {
output := math.Pow(10, float64(precision)) output := math.Pow(10, float64(5))
return float64(round(num*output)) / output return fmt.Sprintf("%.1f", float64(round(num*output))/output)
} }

@ -0,0 +1,45 @@
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func uploadGo(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
return
}
err := r.ParseForm()
if err != nil {
http.Error(w, "Request parameters not parsed", 500)
return
}
err = r.ParseMultipartForm(5 << 20)
if err != nil {
http.Error(w, "Request parameters not parsed", 500)
return
}
project := r.Form.Get("project")
tag := r.Form.Get("tag")
id := r.Form.Get("id")
if project == "" || tag == "" || id == "" {
http.Error(w, "Request parameters [secret, project, tag, id] not found", 400)
return
}
file, _, err := r.FormFile("file")
if err != nil {
http.Error(w, "Request parameter file not found", 400)
return
}
b, _ := ioutil.ReadAll(file)
coverage := parseCoverage(string(b))
db.Exec("INSERT INTO badge (commit_hash, percentage) VALUES (?, ?)", id, coverage)
db.Exec("INSERT INTO alias (commit_hash, project_name, project_tag) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE commit=?", id, project, tag, id)
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, `{"success": "true", "coverage": `+toOneDecimal(coverage*100)+`}`)
}