Format code
Signed-off-by: Steven Kriegler <61625851+justusbunsi@users.noreply.github.com>
This commit is contained in:
parent
16f545f179
commit
a1990a60f4
|
@ -23,10 +23,10 @@ func main() {
|
||||||
settings.Load(getConfigLocation())
|
settings.Load(getConfigLocation())
|
||||||
|
|
||||||
app := &cli.App{
|
app := &cli.App{
|
||||||
Name: "gitea-sonarqube-pr-bot",
|
Name: "gitea-sonarqube-pr-bot",
|
||||||
Usage: "Improve your experience with SonarQube and Gitea",
|
Usage: "Improve your experience with SonarQube and Gitea",
|
||||||
Description: `By default, gitea-sonarqube-pr-bot will start running the webserver if no arguments are passed.`,
|
Description: `By default, gitea-sonarqube-pr-bot will start running the webserver if no arguments are passed.`,
|
||||||
Action: handler.Serve,
|
Action: handler.Serve,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := app.Run(os.Args)
|
err := app.Run(os.Args)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package gitea_sdk
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"gitea-sonarqube-pr-bot/internal/settings"
|
"gitea-sonarqube-pr-bot/internal/settings"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package sonarqube_sdk
|
package sonarqube_sdk
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"gitea-sonarqube-pr-bot/internal/settings"
|
"gitea-sonarqube-pr-bot/internal/settings"
|
||||||
)
|
)
|
||||||
|
@ -15,9 +15,9 @@ type SonarQubeSdkInterface interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type SonarQubeSdk struct {
|
type SonarQubeSdk struct {
|
||||||
client *http.Client
|
client *http.Client
|
||||||
baseUrl string
|
baseUrl string
|
||||||
token string
|
token string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sdk *SonarQubeSdk) GetMeasures(project string, branch string) (string, error) {
|
func (sdk *SonarQubeSdk) GetMeasures(project string, branch string) (string, error) {
|
||||||
|
@ -43,8 +43,8 @@ func (sdk *SonarQubeSdk) basicAuth() string {
|
||||||
|
|
||||||
func New() *SonarQubeSdk {
|
func New() *SonarQubeSdk {
|
||||||
return &SonarQubeSdk{
|
return &SonarQubeSdk{
|
||||||
client: &http.Client{},
|
client: &http.Client{},
|
||||||
baseUrl: settings.SonarQube.Url,
|
baseUrl: settings.SonarQube.Url,
|
||||||
token: settings.SonarQube.Token.Value,
|
token: settings.SonarQube.Token.Value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,18 +9,18 @@ import (
|
||||||
|
|
||||||
type GiteaRepository struct {
|
type GiteaRepository struct {
|
||||||
Owner string
|
Owner string
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
type giteaConfig struct {
|
type giteaConfig struct {
|
||||||
Url string
|
Url string
|
||||||
Token *token
|
Token *token
|
||||||
Webhook *webhook
|
Webhook *webhook
|
||||||
}
|
}
|
||||||
|
|
||||||
type sonarQubeConfig struct {
|
type sonarQubeConfig struct {
|
||||||
Url string
|
Url string
|
||||||
Token *token
|
Token *token
|
||||||
Webhook *webhook
|
Webhook *webhook
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,9 +32,9 @@ type Project struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Gitea giteaConfig
|
Gitea giteaConfig
|
||||||
SonarQube sonarQubeConfig
|
SonarQube sonarQubeConfig
|
||||||
Projects []Project
|
Projects []Project
|
||||||
)
|
)
|
||||||
|
|
||||||
func newConfigReader() *viper.Viper {
|
func newConfigReader() *viper.Viper {
|
||||||
|
@ -83,16 +83,16 @@ func Load(configPath string) {
|
||||||
|
|
||||||
Projects = projects
|
Projects = projects
|
||||||
|
|
||||||
errCallback := func(msg string) {panic(msg)}
|
errCallback := func(msg string) { panic(msg) }
|
||||||
|
|
||||||
Gitea = giteaConfig{
|
Gitea = giteaConfig{
|
||||||
Url: r.GetString("gitea.url"),
|
Url: r.GetString("gitea.url"),
|
||||||
Token: NewToken(r, "gitea", errCallback),
|
Token: NewToken(r, "gitea", errCallback),
|
||||||
Webhook: NewWebhook(r, "gitea", errCallback),
|
Webhook: NewWebhook(r, "gitea", errCallback),
|
||||||
}
|
}
|
||||||
SonarQube = sonarQubeConfig{
|
SonarQube = sonarQubeConfig{
|
||||||
Url: r.GetString("sonarqube.url"),
|
Url: r.GetString("sonarqube.url"),
|
||||||
Token: NewToken(r, "sonarqube", errCallback),
|
Token: NewToken(r, "sonarqube", errCallback),
|
||||||
Webhook: NewWebhook(r, "sonarqube", errCallback),
|
Webhook: NewWebhook(r, "sonarqube", errCallback),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var defaultConfig []byte = []byte(
|
var defaultConfig []byte = []byte(
|
||||||
`gitea:
|
`gitea:
|
||||||
url: https://example.com/gitea
|
url: https://example.com/gitea
|
||||||
token:
|
token:
|
||||||
value: d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565
|
value: d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565
|
||||||
|
@ -38,7 +38,7 @@ func WriteConfigFile(t *testing.T, content []byte) {
|
||||||
os.Remove(config)
|
os.Remove(config)
|
||||||
})
|
})
|
||||||
|
|
||||||
_ = ioutil.WriteFile(config, content,0444)
|
_ = ioutil.WriteFile(config, content, 0444)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLoadWithMissingFile(t *testing.T) {
|
func TestLoadWithMissingFile(t *testing.T) {
|
||||||
|
@ -135,19 +135,19 @@ func TestLoadSonarQubeStructureInjectedEnvs(t *testing.T) {
|
||||||
|
|
||||||
func TestLoadStructureWithFileReferenceResolving(t *testing.T) {
|
func TestLoadStructureWithFileReferenceResolving(t *testing.T) {
|
||||||
giteaWebhookSecretFile := path.Join(os.TempDir(), "webhook-secret-gitea")
|
giteaWebhookSecretFile := path.Join(os.TempDir(), "webhook-secret-gitea")
|
||||||
_ = ioutil.WriteFile(giteaWebhookSecretFile, []byte(`gitea-totally-secret`),0444)
|
_ = ioutil.WriteFile(giteaWebhookSecretFile, []byte(`gitea-totally-secret`), 0444)
|
||||||
|
|
||||||
giteaTokenFile := path.Join(os.TempDir(), "token-secret-gitea")
|
giteaTokenFile := path.Join(os.TempDir(), "token-secret-gitea")
|
||||||
_ = ioutil.WriteFile(giteaTokenFile, []byte(`d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565`),0444)
|
_ = ioutil.WriteFile(giteaTokenFile, []byte(`d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565`), 0444)
|
||||||
|
|
||||||
sonarqubeWebhookSecretFile := path.Join(os.TempDir(), "webhook-secret-sonarqube")
|
sonarqubeWebhookSecretFile := path.Join(os.TempDir(), "webhook-secret-sonarqube")
|
||||||
_ = ioutil.WriteFile(sonarqubeWebhookSecretFile, []byte(`sonarqube-totally-secret`),0444)
|
_ = ioutil.WriteFile(sonarqubeWebhookSecretFile, []byte(`sonarqube-totally-secret`), 0444)
|
||||||
|
|
||||||
sonarqubeTokenFile := path.Join(os.TempDir(), "token-secret-sonarqube")
|
sonarqubeTokenFile := path.Join(os.TempDir(), "token-secret-sonarqube")
|
||||||
_ = ioutil.WriteFile(sonarqubeTokenFile, []byte(`a09eb5785b25bb2cbacf48808a677a0709f02d8e`),0444)
|
_ = ioutil.WriteFile(sonarqubeTokenFile, []byte(`a09eb5785b25bb2cbacf48808a677a0709f02d8e`), 0444)
|
||||||
|
|
||||||
WriteConfigFile(t, []byte(
|
WriteConfigFile(t, []byte(
|
||||||
`gitea:
|
`gitea:
|
||||||
url: https://example.com/gitea
|
url: https://example.com/gitea
|
||||||
token:
|
token:
|
||||||
value: fake-gitea-token
|
value: fake-gitea-token
|
||||||
|
@ -171,10 +171,10 @@ projects:
|
||||||
Url: "https://example.com/gitea",
|
Url: "https://example.com/gitea",
|
||||||
Token: &token{
|
Token: &token{
|
||||||
Value: "d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565",
|
Value: "d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565",
|
||||||
file: giteaTokenFile,
|
file: giteaTokenFile,
|
||||||
},
|
},
|
||||||
Webhook: &webhook{
|
Webhook: &webhook{
|
||||||
Secret: "gitea-totally-secret",
|
Secret: "gitea-totally-secret",
|
||||||
secretFile: giteaWebhookSecretFile,
|
secretFile: giteaWebhookSecretFile,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -183,10 +183,10 @@ projects:
|
||||||
Url: "https://example.com/sonarqube",
|
Url: "https://example.com/sonarqube",
|
||||||
Token: &token{
|
Token: &token{
|
||||||
Value: "a09eb5785b25bb2cbacf48808a677a0709f02d8e",
|
Value: "a09eb5785b25bb2cbacf48808a677a0709f02d8e",
|
||||||
file: sonarqubeTokenFile,
|
file: sonarqubeTokenFile,
|
||||||
},
|
},
|
||||||
Webhook: &webhook{
|
Webhook: &webhook{
|
||||||
Secret: "sonarqube-totally-secret",
|
Secret: "sonarqube-totally-secret",
|
||||||
secretFile: sonarqubeWebhookSecretFile,
|
secretFile: sonarqubeWebhookSecretFile,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -213,12 +213,12 @@ func TestLoadProjectsStructure(t *testing.T) {
|
||||||
|
|
||||||
expectedProjects := []Project{
|
expectedProjects := []Project{
|
||||||
Project{
|
Project{
|
||||||
SonarQube: struct {Key string}{
|
SonarQube: struct{ Key string }{
|
||||||
Key: "gitea-sonarqube-pr-bot",
|
Key: "gitea-sonarqube-pr-bot",
|
||||||
},
|
},
|
||||||
Gitea: GiteaRepository{
|
Gitea: GiteaRepository{
|
||||||
Owner: "example-organization",
|
Owner: "example-organization",
|
||||||
Name: "pr-bot",
|
Name: "pr-bot",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ func TestLoadProjectsStructure(t *testing.T) {
|
||||||
|
|
||||||
func TestLoadProjectsStructureWithNoMapping(t *testing.T) {
|
func TestLoadProjectsStructureWithNoMapping(t *testing.T) {
|
||||||
invalidConfig := []byte(
|
invalidConfig := []byte(
|
||||||
`gitea:
|
`gitea:
|
||||||
url: https://example.com/gitea
|
url: https://example.com/gitea
|
||||||
token:
|
token:
|
||||||
value: d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565
|
value: d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
type token struct {
|
type token struct {
|
||||||
Value string
|
Value string
|
||||||
file string
|
file string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *token) lookupSecret(errCallback func(string)) {
|
func (t *token) lookupSecret(errCallback func(string)) {
|
||||||
|
@ -29,7 +29,7 @@ func (t *token) lookupSecret(errCallback func(string)) {
|
||||||
func NewToken(v *viper.Viper, confContainer string, errCallback func(string)) *token {
|
func NewToken(v *viper.Viper, confContainer string, errCallback func(string)) *token {
|
||||||
t := &token{
|
t := &token{
|
||||||
Value: v.GetString(fmt.Sprintf("%s.token.value", confContainer)),
|
Value: v.GetString(fmt.Sprintf("%s.token.value", confContainer)),
|
||||||
file: v.GetString(fmt.Sprintf("%s.token.file", confContainer)),
|
file: v.GetString(fmt.Sprintf("%s.token.file", confContainer)),
|
||||||
}
|
}
|
||||||
|
|
||||||
t.lookupSecret(errCallback)
|
t.lookupSecret(errCallback)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type webhook struct {
|
type webhook struct {
|
||||||
Secret string
|
Secret string
|
||||||
secretFile string
|
secretFile string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ func (w *webhook) lookupSecret(errCallback func(string)) {
|
||||||
|
|
||||||
func NewWebhook(v *viper.Viper, confContainer string, errCallback func(string)) *webhook {
|
func NewWebhook(v *viper.Viper, confContainer string, errCallback func(string)) *webhook {
|
||||||
w := &webhook{
|
w := &webhook{
|
||||||
Secret: v.GetString(fmt.Sprintf("%s.webhook.secret", confContainer)),
|
Secret: v.GetString(fmt.Sprintf("%s.webhook.secret", confContainer)),
|
||||||
secretFile: v.GetString(fmt.Sprintf("%s.webhook.secretFile", confContainer)),
|
secretFile: v.GetString(fmt.Sprintf("%s.webhook.secretFile", confContainer)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ func Serve(c *cli.Context) error {
|
||||||
fmt.Println("Hi! I'm the Gitea-SonarQube-PR bot. At your service.")
|
fmt.Println("Hi! I'm the Gitea-SonarQube-PR bot. At your service.")
|
||||||
|
|
||||||
var wait time.Duration
|
var wait time.Duration
|
||||||
flag.DurationVar(&wait, "graceful-timeout", time.Second * 15, "the duration for which the server gracefully wait for existing connections to finish")
|
flag.DurationVar(&wait, "graceful-timeout", time.Second*15, "the duration for which the server gracefully wait for existing connections to finish")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
|
@ -30,9 +30,9 @@ func Serve(c *cli.Context) error {
|
||||||
Addr: "0.0.0.0:8080",
|
Addr: "0.0.0.0:8080",
|
||||||
// Good practice to set timeouts to avoid Slowloris attacks.
|
// Good practice to set timeouts to avoid Slowloris attacks.
|
||||||
WriteTimeout: time.Second * 15,
|
WriteTimeout: time.Second * 15,
|
||||||
ReadTimeout: time.Second * 15,
|
ReadTimeout: time.Second * 15,
|
||||||
IdleTimeout: time.Second * 60,
|
IdleTimeout: time.Second * 60,
|
||||||
Handler: r,
|
Handler: r,
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package webhook_handler
|
package webhook_handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,22 +2,22 @@ package webhook_handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gitea-sonarqube-pr-bot/internal/settings"
|
|
||||||
giteaSdk "gitea-sonarqube-pr-bot/internal/clients/gitea_sdk"
|
giteaSdk "gitea-sonarqube-pr-bot/internal/clients/gitea_sdk"
|
||||||
sqSdk "gitea-sonarqube-pr-bot/internal/clients/sonarqube_sdk"
|
sqSdk "gitea-sonarqube-pr-bot/internal/clients/sonarqube_sdk"
|
||||||
|
"gitea-sonarqube-pr-bot/internal/settings"
|
||||||
webhook "gitea-sonarqube-pr-bot/internal/webhooks/sonarqube"
|
webhook "gitea-sonarqube-pr-bot/internal/webhooks/sonarqube"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SonarQubeWebhookHandler struct {
|
type SonarQubeWebhookHandler struct {
|
||||||
fetchDetails func(w *webhook.Webhook)
|
fetchDetails func(w *webhook.Webhook)
|
||||||
giteaSdk giteaSdk.GiteaSdkInterface
|
giteaSdk giteaSdk.GiteaSdkInterface
|
||||||
sqSdk sqSdk.SonarQubeSdkInterface
|
sqSdk sqSdk.SonarQubeSdkInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *SonarQubeWebhookHandler) composeGiteaComment(w *webhook.Webhook) string {
|
func (h *SonarQubeWebhookHandler) composeGiteaComment(w *webhook.Webhook) string {
|
||||||
|
@ -114,7 +114,7 @@ func fetchDetails(w *webhook.Webhook) {
|
||||||
func NewSonarQubeWebhookHandler(g giteaSdk.GiteaSdkInterface, sq sqSdk.SonarQubeSdkInterface) *SonarQubeWebhookHandler {
|
func NewSonarQubeWebhookHandler(g giteaSdk.GiteaSdkInterface, sq sqSdk.SonarQubeSdkInterface) *SonarQubeWebhookHandler {
|
||||||
return &SonarQubeWebhookHandler{
|
return &SonarQubeWebhookHandler{
|
||||||
fetchDetails: fetchDetails,
|
fetchDetails: fetchDetails,
|
||||||
giteaSdk: g,
|
giteaSdk: g,
|
||||||
sqSdk: sq,
|
sqSdk: sq,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package sonarqube
|
package sonarqube
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,19 +12,19 @@ import (
|
||||||
|
|
||||||
type Webhook struct {
|
type Webhook struct {
|
||||||
ServerUrl string `mapstructure:"serverUrl"`
|
ServerUrl string `mapstructure:"serverUrl"`
|
||||||
Revision string
|
Revision string
|
||||||
Project struct {
|
Project struct {
|
||||||
Key string
|
Key string
|
||||||
Name string
|
Name string
|
||||||
Url string
|
Url string
|
||||||
}
|
}
|
||||||
Branch struct {
|
Branch struct {
|
||||||
Name string
|
Name string
|
||||||
Type string
|
Type string
|
||||||
Url string
|
Url string
|
||||||
}
|
}
|
||||||
QualityGate struct {
|
QualityGate struct {
|
||||||
Status string
|
Status string
|
||||||
Conditions []struct {
|
Conditions []struct {
|
||||||
Metric string
|
Metric string
|
||||||
Status string
|
Status string
|
||||||
|
@ -42,7 +42,7 @@ func New(raw []byte) (*Webhook, bool) {
|
||||||
|
|
||||||
err := v.Unmarshal(&w)
|
err := v.Unmarshal(&w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error parsing SonarQube webhook: %s", err.Error())
|
log.Printf("Error parsing SonarQube webhook: %s", err.Error())
|
||||||
return w, false
|
return w, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue