Respect go package concepts

Signed-off-by: Steven Kriegler <61625851+justusbunsi@users.noreply.github.com>
This commit is contained in:
justusbunsi 2021-06-29 08:07:28 +02:00
parent 7bfe729b67
commit 4ba781d74f
No known key found for this signature in database
GPG key ID: 990B348ECAC9C7DB
8 changed files with 64 additions and 62 deletions

View file

@ -4,10 +4,10 @@ import (
"os" "os"
"path" "path"
"github.com/justusbunsi/gitea-sonarqube-pr-bot/internal/settings" "gitea-sonarqube-pr-bot/internal/settings"
) )
func GetConfigLocation() string { func getConfigLocation() string {
configPath := path.Join("config") configPath := path.Join("config")
if customConfigPath, ok := os.LookupEnv("PRBOT_CONFIG_PATH"); ok { if customConfigPath, ok := os.LookupEnv("PRBOT_CONFIG_PATH"); ok {
configPath = customConfigPath configPath = customConfigPath
@ -17,5 +17,5 @@ func GetConfigLocation() string {
} }
func main() { func main() {
settings.Load(GetConfigLocation()) settings.Load(getConfigLocation())
} }

View file

@ -8,13 +8,13 @@ import (
) )
func TestGetConfigLocationWithDefault(t *testing.T) { func TestGetConfigLocationWithDefault(t *testing.T) {
assert.Equal(t, "config", GetConfigLocation()) assert.Equal(t, "config", getConfigLocation())
} }
func TestGetConfigLocationWithEnvironmentOverride(t *testing.T) { func TestGetConfigLocationWithEnvironmentOverride(t *testing.T) {
os.Setenv("PRBOT_CONFIG_PATH", "/tmp/") os.Setenv("PRBOT_CONFIG_PATH", "/tmp/")
assert.Equal(t, "/tmp/", GetConfigLocation()) assert.Equal(t, "/tmp/", getConfigLocation())
t.Cleanup(func() { t.Cleanup(func() {
os.Unsetenv("PRBOT_CONFIG_PATH") os.Unsetenv("PRBOT_CONFIG_PATH")

2
go.mod
View file

@ -1,4 +1,4 @@
module github.com/justusbunsi/gitea-sonarqube-pr-bot module gitea-sonarqube-pr-bot
go 1.16 go 1.16

View file

@ -8,47 +8,53 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
) )
type GiteaRepository struct { type giteaRepository struct {
Owner string Owner string
Name string Name string
} }
type Token struct { type token struct {
Value string Value string
File string File string
} }
type Webhook struct { type webhook struct {
Secret string Secret string
SecretFile string SecretFile 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
} }
type Project struct { type Project struct {
SonarQube struct { SonarQube struct {
Key string Key string
} `mapstructure:"sonarqube"` } `mapstructure:"sonarqube"`
Gitea GiteaRepository Gitea giteaRepository
}
type fullConfig struct {
Gitea giteaConfig
SonarQube sonarQubeConfig `mapstructure:"sonarqube"`
Projects []Project
} }
var ( var (
Gitea GiteaConfig Gitea giteaConfig
SonarQube SonarQubeConfig SonarQube sonarQubeConfig
Projects []Project Projects []Project
) )
func ReadSecretFile(file string, defaultValue string) (string) { func readSecretFile(file string, defaultValue string) (string) {
if file == "" { if file == "" {
return defaultValue return defaultValue
} }
@ -61,7 +67,7 @@ func ReadSecretFile(file string, defaultValue string) (string) {
return string(content) return string(content)
} }
func NewConfigReader() *viper.Viper { func newConfigReader() *viper.Viper {
v := viper.New() v := viper.New()
v.SetConfigName("config.yaml") v.SetConfigName("config.yaml")
v.SetConfigType("yaml") v.SetConfigType("yaml")
@ -86,7 +92,7 @@ func NewConfigReader() *viper.Viper {
} }
func Load(configPath string) { func Load(configPath string) {
r := NewConfigReader() r := newConfigReader()
r.AddConfigPath(configPath) r.AddConfigPath(configPath)
err := r.ReadInConfig() err := r.ReadInConfig()
@ -94,27 +100,23 @@ func Load(configPath string) {
panic(fmt.Errorf("Fatal error while reading config file: %w \n", err)) panic(fmt.Errorf("Fatal error while reading config file: %w \n", err))
} }
var fullConfig struct { var configuration fullConfig
Gitea GiteaConfig
SonarQube SonarQubeConfig `mapstructure:"sonarqube"`
Projects []Project
}
err = r.Unmarshal(&fullConfig) err = r.Unmarshal(&configuration)
if err != nil { if err != nil {
panic(fmt.Errorf("Unable to load config into struct, %v", err)) panic(fmt.Errorf("Unable to load config into struct, %v", err))
} }
if len(fullConfig.Projects) == 0 { if len(configuration.Projects) == 0 {
panic("Invalid configuration. At least one project mapping is necessary.") panic("Invalid configuration. At least one project mapping is necessary.")
} }
Gitea = fullConfig.Gitea Gitea = configuration.Gitea
SonarQube = fullConfig.SonarQube SonarQube = configuration.SonarQube
Projects = fullConfig.Projects Projects = configuration.Projects
Gitea.Webhook.Secret = ReadSecretFile(Gitea.Webhook.SecretFile, Gitea.Webhook.Secret) Gitea.Webhook.Secret = readSecretFile(Gitea.Webhook.SecretFile, Gitea.Webhook.Secret)
Gitea.Token.Value = ReadSecretFile(Gitea.Token.File, Gitea.Token.Value) Gitea.Token.Value = readSecretFile(Gitea.Token.File, Gitea.Token.Value)
SonarQube.Webhook.Secret = ReadSecretFile(SonarQube.Webhook.SecretFile, SonarQube.Webhook.Secret) SonarQube.Webhook.Secret = readSecretFile(SonarQube.Webhook.SecretFile, SonarQube.Webhook.Secret)
SonarQube.Token.Value = ReadSecretFile(SonarQube.Token.File, SonarQube.Token.Value) SonarQube.Token.Value = readSecretFile(SonarQube.Token.File, SonarQube.Token.Value)
} }

View file

@ -55,12 +55,12 @@ func TestLoadGiteaStructure(t *testing.T) {
WriteConfigFile(t, defaultConfig) WriteConfigFile(t, defaultConfig)
Load(os.TempDir()) Load(os.TempDir())
expected := GiteaConfig{ expected := giteaConfig{
Url: "https://example.com/gitea", Url: "https://example.com/gitea",
Token: Token{ Token: token{
Value: "d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565", Value: "d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565",
}, },
Webhook: Webhook{ Webhook: webhook{
Secret: "haxxor-gitea-secret", Secret: "haxxor-gitea-secret",
}, },
} }
@ -74,12 +74,12 @@ func TestLoadGiteaStructureInjectedEnvs(t *testing.T) {
WriteConfigFile(t, defaultConfig) WriteConfigFile(t, defaultConfig)
Load(os.TempDir()) Load(os.TempDir())
expected := GiteaConfig{ expected := giteaConfig{
Url: "https://example.com/gitea", Url: "https://example.com/gitea",
Token: Token{ Token: token{
Value: "injected-token", Value: "injected-token",
}, },
Webhook: Webhook{ Webhook: webhook{
Secret: "injected-webhook-secret", Secret: "injected-webhook-secret",
}, },
} }
@ -96,12 +96,12 @@ func TestLoadSonarQubeStructure(t *testing.T) {
WriteConfigFile(t, defaultConfig) WriteConfigFile(t, defaultConfig)
Load(os.TempDir()) Load(os.TempDir())
expected := SonarQubeConfig{ expected := sonarQubeConfig{
Url: "https://example.com/sonarqube", Url: "https://example.com/sonarqube",
Token: Token{ Token: token{
Value: "a09eb5785b25bb2cbacf48808a677a0709f02d8e", Value: "a09eb5785b25bb2cbacf48808a677a0709f02d8e",
}, },
Webhook: Webhook{ Webhook: webhook{
Secret: "haxxor-sonarqube-secret", Secret: "haxxor-sonarqube-secret",
}, },
} }
@ -115,12 +115,12 @@ func TestLoadSonarQubeStructureInjectedEnvs(t *testing.T) {
WriteConfigFile(t, defaultConfig) WriteConfigFile(t, defaultConfig)
Load(os.TempDir()) Load(os.TempDir())
expected := SonarQubeConfig{ expected := sonarQubeConfig{
Url: "https://example.com/sonarqube", Url: "https://example.com/sonarqube",
Token: Token{ Token: token{
Value: "injected-token", Value: "injected-token",
}, },
Webhook: Webhook{ Webhook: webhook{
Secret: "injected-webhook-secret", Secret: "injected-webhook-secret",
}, },
} }
@ -167,25 +167,25 @@ projects:
os.Setenv("PRBOT_SONARQUBE_WEBHOOK_SECRETFILE", sonarqubeWebhookSecretFile) os.Setenv("PRBOT_SONARQUBE_WEBHOOK_SECRETFILE", sonarqubeWebhookSecretFile)
os.Setenv("PRBOT_SONARQUBE_TOKEN_FILE", sonarqubeTokenFile) os.Setenv("PRBOT_SONARQUBE_TOKEN_FILE", sonarqubeTokenFile)
expectedGitea := GiteaConfig{ expectedGitea := giteaConfig{
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,
}, },
} }
expectedSonarQube := SonarQubeConfig{ expectedSonarQube := sonarQubeConfig{
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,
}, },
@ -216,7 +216,7 @@ func TestLoadProjectsStructure(t *testing.T) {
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",
}, },

View file

@ -8,7 +8,7 @@ import (
"net/http" "net/http"
"strings" "strings"
"github.com/justusbunsi/gitea-sonarqube-pr-bot/internal/settings" "gitea-sonarqube-pr-bot/internal/settings"
) )
func inProjectsMapping(p []settings.Project, n string) bool { func inProjectsMapping(p []settings.Project, n string) bool {

View file

@ -6,7 +6,7 @@ import (
"net/http/httptest" "net/http/httptest"
"testing" "testing"
"github.com/justusbunsi/gitea-sonarqube-pr-bot/internal/settings" "gitea-sonarqube-pr-bot/internal/settings"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )

View file

@ -10,22 +10,22 @@ import (
type Webhook struct { type Webhook struct {
ServerUrl string `mapstructure:"serverUrl"` ServerUrl string `mapstructure:"serverUrl"`
Revision string Revision string
Branch Branch Branch branch
QualityGate QualityGate `mapstructure:"qualityGate"` QualityGate qualityGate `mapstructure:"qualityGate"`
} }
type Branch struct { type branch struct {
Name string Name string
Type string Type string
Url string Url string
} }
type QualityGate struct { type qualityGate struct {
Status string Status string
Conditions []QualityGateCondition Conditions []condition
} }
type QualityGateCondition struct { type condition struct {
Metric string Metric string
Status string Status string
} }