diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 5c4176f..0000000
--- a/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-coverage.db
\ No newline at end of file
diff --git a/badge.go b/badge.go
new file mode 100644
index 0000000..e4ad7e4
--- /dev/null
+++ b/badge.go
@@ -0,0 +1,74 @@
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "net/http"
+ "text/template"
+
+ "github.com/gorilla/mux"
+)
+
+var baseTemplate *template.Template
+
+func init() {
+ baseTemplate = template.New("svgTemplate")
+ baseTemplate, _ = baseTemplate.Parse(svgTemplate)
+}
+
+func badgeFromCommit(w http.ResponseWriter, r *http.Request) {
+ commitID := mux.Vars(r)["commit"]
+ result := svgFromHash(commitID)
+
+ w.Header().Set("Content-Type", "image/svg+xml")
+ fmt.Fprint(w, result)
+}
+
+func badgeFromProject(w http.ResponseWriter, r *http.Request) {
+ projectName := mux.Vars(r)["project"]
+ tagName := mux.Vars(r)["tag"]
+ commitRow, err := db.Query("SELECT commit_hash FROM alias WHERE project_name=? AND project_tag=?", projectName, tagName)
+
+ if err != nil {
+ panic(err)
+ }
+ if !commitRow.Next() {
+ fmt.Fprint(w, unknownCoveragePill())
+ return
+ }
+
+ var commitHash string
+ commitRow.Scan(&commitHash)
+ commitRow.Close()
+
+ result := svgFromHash(commitHash)
+
+ w.Header().Set("Content-Type", "image/svg+xml")
+ fmt.Fprint(w, result)
+}
+
+func svgFromHash(commit string) string {
+ result, err := db.Query("SELECT percentage FROM badge WHERE commit_hash=?", commit)
+ defer result.Close()
+ if err != nil {
+ panic(err)
+ }
+
+ if !result.Next() {
+ return unknownCoveragePill()
+ }
+
+ var percentage float64
+ result.Scan(&percentage)
+
+ fillColour := percentageToRGB(percentage)
+ pill := CoveragePill{
+ toOneDecimal(percentage*100) + "%",
+ baseColour,
+ fillColour,
+ }
+
+ buf := &bytes.Buffer{}
+ baseTemplate.Execute(buf, pill)
+ return buf.String()
+}
diff --git a/cmd/server/Dockerfile b/cmd/server/Dockerfile
deleted file mode 100644
index 422b10a..0000000
--- a/cmd/server/Dockerfile
+++ /dev/null
@@ -1,10 +0,0 @@
-FROM golang:1.16 AS build
-WORKDIR /root/
-COPY . .
-RUN go build -o coverage .
-
-FROM golang:1.16
-WORKDIR /root/
-COPY --from=build /root/coverage .
-EXPOSE 8080
-CMD ["./coverage"]
diff --git a/cmd/server/main.go b/cmd/server/main.go
deleted file mode 100644
index 0fadeda..0000000
--- a/cmd/server/main.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package main
-
-import (
- "fmt"
- "log"
- "os"
- "os/signal"
-
- "gitea.teamortix.com/team-ortix/coverage/db"
- "gitea.teamortix.com/team-ortix/coverage/server"
-)
-
-var (
- port = os.Getenv("COVERAGE_PORT")
- dbFile = os.Getenv("DB_FILE")
-)
-
-func main() {
- if port == "" {
- port = "8080"
- }
- if dbFile == "" {
- dbFile = "coverage.db"
- }
-
- c := make(chan os.Signal, 1)
- signal.Notify(c, os.Interrupt)
-
- go func() {
- db.OpenDatabase(dbFile)
- server.StartServer(port)
- }()
-
- log.Printf("server starting. at http://0.0.0.0:%s", port)
-
- <-c
- fmt.Println("\nAborting...")
-}
diff --git a/connection.go b/connection.go
new file mode 100644
index 0000000..fc2c978
--- /dev/null
+++ b/connection.go
@@ -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)`)
+}
diff --git a/database.sqlite b/database.sqlite
new file mode 100644
index 0000000..441bb3a
Binary files /dev/null and b/database.sqlite differ
diff --git a/db/connection.go b/db/connection.go
deleted file mode 100644
index 835b046..0000000
--- a/db/connection.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package db
-
-import (
- "database/sql"
- "log"
-
- // Required to connect to database.
- _ "github.com/mattn/go-sqlite3"
-)
-
-var db *sql.DB
-
-func OpenDatabase(fileLocation string) {
- var err error
- db, err = sql.Open("sqlite3", fileLocation)
- if err != nil {
- log.Fatalf("could not open database: %v", err)
- }
-
- // Initializes the table.
- _, err = db.Exec(`CREATE TABLE IF NOT EXISTS badge (
- namespace VARCHAR(64) NOT NULL,
- project_name VARCHAR(64) NOT NULL,
- coverage INTEGER NOT NULL,
- html TEXT NOT NULL,
-
- branch VARCHAR(64),
- pull INTEGER
- )`)
- if err != nil {
- log.Fatalf("Could not create table: %v", err)
- }
-}
diff --git a/db/query.go b/db/query.go
deleted file mode 100644
index 4c988d1..0000000
--- a/db/query.go
+++ /dev/null
@@ -1,75 +0,0 @@
-package db
-
-import (
- "database/sql"
- "errors"
- "strconv"
-)
-
-var ErrNoData = errors.New("no badge found with the provided data")
-
-type CoverageData struct {
- Namespace string
- Project string
- Coverage float64
- HTML string
-}
-
-// QueryByBranch returns CoverageData for the provided branch for the project.
-// If there is no such data, it returns ErrNoData.
-func QueryByBranch(namespace, project, branch string) (CoverageData, error) {
- result, err := db.Query(`SELECT coverage,html FROM badge WHERE
- namespace=? AND
- project_name=? AND
- branch=?`,
- namespace, project, branch)
- if err != nil {
- return CoverageData{}, err
- }
-
- return parseRows(result, namespace, project)
-}
-
-// QueryByBranch returns CoverageData for the provided pull request of the project.
-// If there is no such data, it returns ErrNoData.
-func QueryByPull(namespace, project, pullStr string) (CoverageData, error) {
- pull, err := strconv.Atoi(pullStr)
- if err != nil {
- return CoverageData{}, ErrNoData
- }
-
- result, err := db.Query(`SELECT coverage, html FROM badge WHERE
- namespace=? AND
- project_name=? AND
- pull=?`,
- namespace, project, pull)
- if err != nil {
- return CoverageData{}, err
- }
-
- return parseRows(result, namespace, project)
-}
-
-func parseRows(result *sql.Rows, namespace, project string) (CoverageData, error) {
- if !result.Next() {
- return CoverageData{}, ErrNoData
- }
-
- var coverage float64
- var html string
- err := result.Scan(&coverage, &html)
- if err != nil {
- return CoverageData{}, err
- }
-
- if err = result.Close(); err != nil {
- return CoverageData{}, ErrNoData
- }
-
- return CoverageData{
- Namespace: namespace,
- Project: project,
- Coverage: coverage,
- HTML: html,
- }, nil
-}
diff --git a/db/upload.go b/db/upload.go
deleted file mode 100644
index 73189be..0000000
--- a/db/upload.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package db
-
-import (
- "fmt"
- "strconv"
-)
-
-func UploadBranchData(namespace, project, branch, coverageStr, html string) error {
- coverage, err := strconv.ParseFloat(coverageStr, 64)
- if err != nil {
- return fmt.Errorf("coverage param must be valid float, instead got %s", coverageStr)
- }
-
- // Because we don't have have a primary key, we must do the upsert manually.
- _, err = QueryByBranch(namespace, project, branch)
- if err == ErrNoData {
- _, err = db.Exec("INSERT INTO badge (namespace, project_name, branch, coverage, html) VALUES (?, ?, ?, ?, ?)",
- namespace, project, branch, coverage, html)
- if err != nil {
- return fmt.Errorf("could not update database: %v", err)
- }
- }
- if err != nil {
- return err
- }
-
- _, err = db.Exec("UPDATE badge SET coverage=?, html=? WHERE namespace=? AND project_name=? AND branch=?",
- coverage, html, namespace, project, branch)
- if err != nil {
- return fmt.Errorf("could not update database: %v", err)
- }
-
- return nil
-}
-
-func UploadPullData(namespace, project, pullStr, coverageStr, html string) error {
- pull, err := strconv.Atoi(pullStr)
- if err != nil {
- return fmt.Errorf("pull param must be valid int, instead got %s", pullStr)
- }
- coverage, err := strconv.ParseFloat(coverageStr, 64)
- if err != nil {
- return fmt.Errorf("coverage param must be valid float, instead got %s", coverageStr)
- }
-
- // Because we don't have have a primary key, we must do the upsert manually.
- _, err = QueryByPull(namespace, project, pullStr)
- if err == ErrNoData {
- _, err = db.Exec("INSERT INTO badge (namespace, project_name, pull, coverage, html) VALUES (?, ?, ?, ?, ?)",
- namespace, project, pull, coverage, html)
- if err != nil {
- return fmt.Errorf("could not update database: %v", err)
- }
- }
- if err != nil {
- return err
- }
-
- _, err = db.Exec("UPDATE badge SET coverage=?, html=? WHERE namespace=? AND project_name=? AND pull=?",
- coverage, html, namespace, project, pull)
- if err != nil {
- return fmt.Errorf("could not update database: %v", err)
- }
-
- return nil
-}
diff --git a/go.mod b/go.mod
deleted file mode 100644
index 573805c..0000000
--- a/go.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-module gitea.teamortix.com/team-ortix/coverage
-
-go 1.16
-
-require (
- github.com/gorilla/mux v1.8.0
- github.com/mattn/go-sqlite3 v1.14.6
-)
diff --git a/go.sum b/go.sum
deleted file mode 100644
index 27294bc..0000000
--- a/go.sum
+++ /dev/null
@@ -1,4 +0,0 @@
-github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
-github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
-github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
-github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..7ed99af
--- /dev/null
+++ b/main.go
@@ -0,0 +1,37 @@
+package main
+
+import (
+ "fmt"
+ "net/http"
+ "strconv"
+ "strings"
+
+ "github.com/gorilla/mux"
+)
+
+func main() {
+ r := mux.NewRouter()
+ r.HandleFunc("/upload/go", uploadGo)
+ r.HandleFunc("/badge/commit/{commit}.svg", badgeFromCommit)
+ r.HandleFunc("/badge/{project}/{tag}.svg", badgeFromProject)
+ _ = http.ListenAndServe(":8080", r)
+}
+
+func parseCoverage(content string) float64 {
+ var totalStatements = 0
+ var totalRun = 0
+
+ lines := strings.Split(content, "\n")
+ for _, line := range lines[1 : len(lines)-1] { // Skip first line (which is not relevant)
+ sl := strings.Split(line, " ")
+ statements, _ := strconv.Atoi(sl[len(sl)-2])
+ runCount, _ := strconv.Atoi(sl[len(sl)-1])
+
+ totalStatements += statements
+ if runCount != 0 {
+ totalRun += statements
+ }
+ }
+ fmt.Printf("DEBUG :: TotalStatements: %d, TotalRunCount: %d\n", totalStatements, totalRun)
+ return float64(totalRun) / float64(totalStatements)
+}
diff --git a/pill.go b/pill.go
new file mode 100644
index 0000000..7ff2705
--- /dev/null
+++ b/pill.go
@@ -0,0 +1,85 @@
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "math"
+ "strconv"
+)
+
+const svgTemplate string = `
+`
+
+const (
+ baseColour = "#555"
+ modifier float64 = 0.2
+ maxValue = 220
+ blue = 55
+)
+
+//Pill used for template
+type CoveragePill struct {
+ Percentage string
+ BaseColour string
+ FillColour string
+}
+
+func unknownCoveragePill() string {
+ pill := CoveragePill{
+ "?",
+ baseColour,
+ baseColour, // Using the base colour for fill colour because unknown
+ }
+
+ buf := &bytes.Buffer{}
+ baseTemplate.Execute(buf, pill)
+ return buf.String()
+}
+
+func percentageToRGB(percentage float64) string {
+ red := modifier + clamp(2-2*math.Pow(percentage, 2), 0, 1)*(1-modifier)
+ green := modifier + clamp(2*math.Pow(percentage, 2), 0, 1)*(1-modifier)
+
+ redValue := strconv.Itoa(int(red * maxValue))
+ greenValue := strconv.Itoa(int(green * maxValue))
+ blueValue := strconv.Itoa(blue)
+
+ return "rgb(" + redValue + ", " + greenValue + ", " + blueValue + ")"
+}
+
+func clamp(operation float64, min float64, max float64) float64 {
+ if operation < min {
+ return min
+ }
+ if operation > max {
+ return max
+ }
+ return operation
+}
+
+func round(num float64) int {
+ return int(num + math.Copysign(0.5, num))
+}
+
+func toOneDecimal(num float64) string {
+ output := math.Pow(10, float64(5))
+ return fmt.Sprintf("%.1f", float64(round(num*output))/output)
+}
diff --git a/pill/badge.go b/pill/badge.go
deleted file mode 100644
index bfcec92..0000000
--- a/pill/badge.go
+++ /dev/null
@@ -1 +0,0 @@
-package pill
diff --git a/pill/pill.go b/pill/pill.go
deleted file mode 100644
index 5edf9db..0000000
--- a/pill/pill.go
+++ /dev/null
@@ -1,79 +0,0 @@
-package pill
-
-import (
- // Used for embedding pill.
- _ "embed"
- "fmt"
- "io"
- "math"
- "text/template"
-)
-
-var (
- //go:embed pill.svg
- pill string
-
- tmpl = template.New("svgTemplate")
-)
-
-const (
- modifier = 0.2
- max = 190
- blue = 55
-)
-
-// Pill is used to execute the pill.svg template.
-// Width is dependent on whether the percentage is 2 digits or 3 digits.
-type Pill struct {
- Percentage string
- Colour string
- Width string
-}
-
-// NewPill creates creates a Pill, automatically calculating the colour, width, and formatting the percentage.
-// Note: %.0f gives us a float with 0 decimals and 0 padding for 2 numbers less than 10.
-func NewPill(percentDecimal float64) Pill {
- square := math.Pow(percentDecimal, 2)
- red := modifier + clamp(2-2*square, 0, 1)*(1-modifier)
- green := modifier + clamp(2*square, 0, 1)*(1-modifier)
-
- percentage := fmt.Sprintf("%.0f", percentDecimal*100)
- colour := fmt.Sprintf("rgb(%.0f, %.0f, %d)", red*max, green*max, blue)
- width := "250"
- if len(percentage) == 1 {
- percentage = " " + percentage
- width = "220"
- }
- if len(percentage) == 3 {
- width = "300"
- }
-
- return Pill{
- Percentage: percentage,
- Colour: colour,
- Width: width,
- }
-}
-
-// Execute runs the pill template with the data and writes the result to the writer given.
-func (p Pill) Execute(w io.Writer) error {
- var err error
- tmpl, err = tmpl.Parse(pill)
- if err != nil {
- return err
- }
-
- err = tmpl.Execute(w, p)
- return err
-}
-
-func clamp(n, min, max float64) float64 {
- switch {
- case n > max:
- return max
- case n < min:
- return min
- default:
- return n
- }
-}
diff --git a/pill/pill.svg b/pill/pill.svg
deleted file mode 100644
index ff9012c..0000000
--- a/pill/pill.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
\ No newline at end of file
diff --git a/server/query.go b/server/query.go
deleted file mode 100644
index a73d6a0..0000000
--- a/server/query.go
+++ /dev/null
@@ -1,92 +0,0 @@
-package server
-
-import (
- "fmt"
- "log"
- "net/http"
-
- "gitea.teamortix.com/team-ortix/coverage/db"
- "gitea.teamortix.com/team-ortix/coverage/pill"
-)
-
-type endpointData struct {
- thirdParam string
- queryFunc func(string, string, string) (db.CoverageData, error)
- handle func(db.CoverageData)
-}
-
-func (d endpointData) run(w http.ResponseWriter, r *http.Request) {
- params, ok := getAllParams(w, r, d.thirdParam)
- if !ok {
- return
- }
-
- data, err := d.queryFunc(params[0], params[1], params[2])
- if err == db.ErrNoData {
- http.Error(w, "not found", http.StatusNotFound)
- return
- }
- if err != nil {
- http.Error(w, fmt.Sprintf("could not query from db: %v", err), http.StatusInternalServerError)
- log.Printf("error occurred while querying data from db: %v", err)
- return
- }
-
- d.handle(data)
-}
-
-func handleBranchReport(w http.ResponseWriter, r *http.Request) {
- endpointData{
- thirdParam: "branch",
- queryFunc: db.QueryByBranch,
- handle: func(cd db.CoverageData) {
- w.Header().Set("Content-Type", "text/html")
- fmt.Fprint(w, cd.HTML)
- },
- }.run(w, r)
-}
-
-func handleBadgeBranch(w http.ResponseWriter, r *http.Request) {
- endpointData{
- thirdParam: "branch",
- queryFunc: db.QueryByBranch,
- handle: func(cd db.CoverageData) {
- p := pill.NewPill(cd.Coverage)
-
- w.Header().Set("Content-Type", "image/svg+xml")
- err := p.Execute(w)
- if err != nil {
- http.Error(w, fmt.Sprintf("could not write pill: %v", err), http.StatusInternalServerError)
- return
- }
- },
- }.run(w, r)
-}
-
-func handlePullReport(w http.ResponseWriter, r *http.Request) {
- endpointData{
- thirdParam: "pull",
- queryFunc: db.QueryByPull,
- handle: func(cd db.CoverageData) {
- w.Header().Set("Content-Type", "text/html")
- fmt.Fprint(w, cd.HTML)
- },
- }.run(w, r)
-}
-
-func handlePullBadge(w http.ResponseWriter, r *http.Request) {
- endpointData{
- thirdParam: "pull",
- queryFunc: db.QueryByPull,
- handle: func(cd db.CoverageData) {
- p := pill.NewPill(cd.Coverage)
-
- w.Header().Set("Content-Type", "image/svg+xml")
- err := p.Execute(w)
- if err != nil {
- http.Error(w, fmt.Sprintf("could not write pill: %v", err), http.StatusInternalServerError)
- return
- }
- },
- }.run(w, r)
-}
diff --git a/server/server.go b/server/server.go
deleted file mode 100644
index 2fe3953..0000000
--- a/server/server.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package server
-
-import (
- "fmt"
- "log"
- "net/http"
- "strconv"
-
- "gitea.teamortix.com/team-ortix/coverage/pill"
- "github.com/gorilla/mux"
-)
-
-func StartServer(port string) {
- r := mux.NewRouter()
- r.HandleFunc("/badge/{percentage}", handleBadge)
-
- r.HandleFunc("/report/branch/{namespace}/{project}/{branch}", handleBranchReport)
- r.HandleFunc("/report/pulls/{namespace}/{project}/{pull}", handlePullReport)
- r.HandleFunc("/badge/branch/{namespace}/{project}/{branch}", handleBadgeBranch)
- r.HandleFunc("/badge/pulls/{namespace}/{project}/{pull}", handlePullBadge)
-
- r.HandleFunc("/upload/branch/{namespace}/{project}/{branch}", uploadBranch)
- r.HandleFunc("/upload/pulls/{namespace}/{project}/{pull}", uploadPull)
-
- portStr := fmt.Sprintf(":%s", port)
- err := http.ListenAndServe(portStr, r)
- if err != nil {
- log.Fatalf("could not start server: %v", err)
- }
-}
-
-func handleBadge(w http.ResponseWriter, r *http.Request) {
- percentString, ok := mux.Vars(r)["percentage"]
- if !ok {
- http.Error(w, "could not find percentage in path", http.StatusBadRequest)
- return
- }
-
- percent, err := strconv.ParseFloat(percentString, 64)
- if err != nil {
- http.Error(w, fmt.Sprintf("could not convert %s to a number", percentString), http.StatusBadRequest)
- return
- }
-
- p := pill.NewPill(percent / 100)
-
- w.Header().Set("Content-Type", "image/svg+xml")
- err = p.Execute(w)
- if err != nil {
- http.Error(w, fmt.Sprintf("could not write pill: %v", err), http.StatusInternalServerError)
- return
- }
-}
-
-func getAllParams(w http.ResponseWriter, r *http.Request, thirdParam string) ([3]string, bool) {
- vars := mux.Vars(r)
- namespace, ok := vars["namespace"]
- if !ok {
- http.Error(w, "Path 'namespace' not found", http.StatusBadRequest)
- return [3]string{}, false
- }
-
- project, ok := vars["project"]
- if !ok {
- http.Error(w, "Path 'project' not found", http.StatusBadRequest)
- return [3]string{}, false
- }
-
- third, ok := vars[thirdParam]
- if !ok {
- http.Error(w, fmt.Sprintf("Path '%s' not found", thirdParam), http.StatusBadRequest)
- return [3]string{}, false
- }
-
- return [3]string{namespace, project, third}, true
-}
diff --git a/server/upload.go b/server/upload.go
deleted file mode 100644
index 98c2ec5..0000000
--- a/server/upload.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package server
-
-import (
- "fmt"
- "io"
- "net/http"
- "os"
-
- "gitea.teamortix.com/team-ortix/coverage/db"
-)
-
-const coverageSecret = "COVERAGE_SECRET"
-
-var secretEnv = os.Getenv(coverageSecret)
-
-func uploadBranch(w http.ResponseWriter, r *http.Request) {
- upload(w, r, "branch", db.UploadBranchData)
-}
-
-func uploadPull(w http.ResponseWriter, r *http.Request) {
- upload(w, r, "pull", db.UploadPullData)
-}
-
-func upload(w http.ResponseWriter, r *http.Request,
- uploadType string, uploadFunc func(string, string, string, string, string) error) {
- if r.Method != "POST" {
- return
- }
-
- err := r.ParseMultipartForm(5 << 20)
- if err != nil {
- http.Error(w, "file too large", http.StatusRequestEntityTooLarge)
- return
- }
- err = r.ParseForm()
- if err != nil {
- http.Error(w, "could not parse form", http.StatusBadRequest)
- return
- }
-
- secret := r.Form.Get("secret")
- params, ok := getAllParams(w, r, uploadType)
- coverage := r.Form.Get("coverage")
-
- if secretEnv != secret && secretEnv != "" {
- http.Error(w, "invalid secret provided", http.StatusUnauthorized)
- return
- }
- if !ok {
- return
- }
-
- if coverage == "" {
- http.Error(w, "request param coverage must be present", http.StatusBadRequest)
- return
- }
-
- report, _, err := r.FormFile("report")
- if err != nil {
- http.Error(w, "could not parse report parameter", http.StatusBadRequest)
- return
- }
- bytes, err := io.ReadAll(report)
- if err != nil {
- http.Error(w, fmt.Sprintf("could not read file: %v", err), http.StatusBadRequest)
- return
- }
-
- err = uploadFunc(params[0], params[1], params[2], coverage, string(bytes))
- if err != nil {
- http.Error(w, fmt.Sprintf("could not upload data to database: %v", err), http.StatusInternalServerError)
- return
- }
-
- fmt.Fprintln(w, "uploaded")
-}
diff --git a/test.svg b/test.svg
new file mode 100644
index 0000000..b84c231
--- /dev/null
+++ b/test.svg
@@ -0,0 +1,20 @@
+
+
diff --git a/upload.go b/upload.go
new file mode 100644
index 0000000..418c3e9
--- /dev/null
+++ b/upload.go
@@ -0,0 +1,56 @@
+package main
+
+import (
+ "database/sql"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+)
+
+func uploadGo(w http.ResponseWriter, r *http.Request) {
+ if r.Method != "POST" {
+ return
+ }
+ w.Header().Set("Content-Type", "application/json")
+
+ err := r.ParseForm()
+ if err != nil {
+ http.Error(w, `{"success": false, "message": "Request parameters not parsed"}`, 500)
+ return
+ }
+ err = r.ParseMultipartForm(5 << 20)
+ if err != nil {
+ http.Error(w, `{"success": false, "message": "Request parameters too large"}`, 500)
+ return
+ }
+
+ name := r.Form.Get("project-name")
+ tag := r.Form.Get("tag")
+ id := r.Form.Get("id")
+
+ if name == "" || tag == "" || id == "" {
+ http.Error(w, `{"success": false, "message": "Request parameters [secret, name, tag, id] not found"}`, 400)
+ return
+ }
+ file, _, err := r.FormFile("file")
+ if err != nil {
+ http.Error(w, `{"success": false, "message": "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)
+
+ _, err = db.Query("SELECT commit_hash FROM alias WHERE project_name=? AND project_tag=?", name, tag)
+
+ if err == nil {
+ db.Exec("UPDATE ALIAS SET commit_hash=? WHERE project_name=? AND project_tag=?", id, name, tag)
+ } else if err == sql.ErrNoRows {
+ db.Exec("INSERT INTO alias (commit_hash, project_name, project_tag VALUES (?, ?, ?)", id, name, tag)
+ } else {
+ panic(err)
+ }
+
+ fmt.Fprintf(w, `{"success": "true", "coverage": %s%%}`, toOneDecimal(coverage*100))
+}