diff --git a/cmd/gitea-sonarqube-bot/main.go b/cmd/gitea-sonarqube-bot/main.go index cdc33c0..c69dc47 100644 --- a/cmd/gitea-sonarqube-bot/main.go +++ b/cmd/gitea-sonarqube-bot/main.go @@ -1,10 +1,13 @@ package main import ( + "log" "os" "path" "gitea-sonarqube-pr-bot/internal/settings" + handler "gitea-sonarqube-pr-bot/internal/webhook_handler" + "github.com/urfave/cli/v2" ) func getConfigLocation() string { @@ -18,4 +21,16 @@ func getConfigLocation() string { func main() { settings.Load(getConfigLocation()) + + app := &cli.App{ + Name: "gitea-sonarqube-pr-bot", + 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.`, + Action: handler.Serve, + } + + err := app.Run(os.Args) + if err != nil { + log.Fatal(err) + } } diff --git a/go.mod b/go.mod index abef9c1..2f1864f 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 // indirect github.com/coreos/etcd v3.3.10+incompatible // indirect github.com/coreos/go-etcd v2.0.0+incompatible // indirect + github.com/gorilla/mux v1.8.0 // indirect github.com/spf13/viper v1.8.0 // indirect github.com/stretchr/testify v1.7.0 // indirect github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 // indirect diff --git a/go.sum b/go.sum index b9b6def..df5b50f 100644 --- a/go.sum +++ b/go.sum @@ -141,6 +141,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= diff --git a/internal/webhook_handler/main.go b/internal/webhook_handler/main.go new file mode 100644 index 0000000..016d12a --- /dev/null +++ b/internal/webhook_handler/main.go @@ -0,0 +1,57 @@ +package webhook_handler + +import ( + "context" + "flag" + "fmt" + "log" + "net/http" + "os" + "os/signal" + "time" + + "github.com/gorilla/mux" + "github.com/urfave/cli/v2" +) + +func Serve(c *cli.Context) error { + fmt.Println("Hi! I'm the Gitea-SonarQube-PR bot. At your service.") + + 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.Parse() + + r := mux.NewRouter() + r.HandleFunc("/hooks/sonarqube", NewSonarQubeWebhookHandler().Handle).Methods("POST").Headers("X-SonarQube-Project", "") + + srv := &http.Server{ + Addr: "0.0.0.0:8080", + // Good practice to set timeouts to avoid Slowloris attacks. + WriteTimeout: time.Second * 15, + ReadTimeout: time.Second * 15, + IdleTimeout: time.Second * 60, + Handler: r, + } + + go func() { + log.Println("Listen on :8080") + if err := srv.ListenAndServe(); err != nil { + log.Println(err) + } + }() + + ch := make(chan os.Signal, 1) + signal.Notify(ch, os.Interrupt) + + // Block until we receive our signal. + <-ch + + // Create a deadline to wait for. + ctx, cancel := context.WithTimeout(context.Background(), wait) + defer cancel() + srv.Shutdown(ctx) + log.Println("Shutting down webhook server") + os.Exit(0) + + return nil +}