Skip to content

Commit

Permalink
notification to slack
Browse files Browse the repository at this point in the history
  • Loading branch information
Dima Kozlov committed Oct 25, 2020
1 parent e503690 commit d990ae9
Show file tree
Hide file tree
Showing 12 changed files with 176 additions and 24 deletions.
6 changes: 5 additions & 1 deletion cmd/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ func createMR(cmd *cobra.Command, logger zerolog.Logger, out io.StringWriter) {
os.Exit(1)
}

core := createCore(dryRun, out, &cfg.GitLab)
core, err := createCore(dryRun, out, &cfg.GitLab, &cfg.Notifier)
if err != nil {
_, _ = out.WriteString("Failed to start glmt: " + err.Error() + "\n")
os.Exit(1)
}

br, err := regexp.Compile(cfg.MR.BranchRegexp)
if err != nil {
Expand Down
21 changes: 15 additions & 6 deletions cmd/glmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import (
"path/filepath"

"gitlab.com/glmt/glmt/internal/config"
giti "gitlab.com/glmt/glmt/internal/git/impl"
"gitlab.com/glmt/glmt/internal/git"
"gitlab.com/glmt/glmt/internal/gitlab"
gitlabi "gitlab.com/glmt/glmt/internal/gitlab/impl"
"gitlab.com/glmt/glmt/internal/glmt"
"gitlab.com/glmt/glmt/internal/notifier"

"github.com/rs/zerolog"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -148,15 +149,23 @@ func applyFlags(flags *pflag.FlagSet, cfg *config.Config) error {
return nil
}

func createCore(dryRun bool, out io.StringWriter, cfg *config.GitLab) *glmt.Core {
git, _ := giti.NewLocalGit()
func createCore(dryRun bool, out io.StringWriter, gitCfg *config.GitLab, nfyCfg *config.Notifier) (*glmt.Core, error) {
git, err := git.NewLocalGit()
if err != nil {
return nil, err
}

var gitlab gitlab.GitLab
if dryRun {
gitlab = gitlabi.NewDryRunGitLab(out, cfg.Token, cfg.URL)
gitlab = gitlabi.NewDryRunGitLab(out, gitCfg.Token, gitCfg.URL)
} else {
gitlab = gitlabi.NewHTTPGitLab(cfg.Token, cfg.URL)
gitlab = gitlabi.NewHTTPGitLab(gitCfg.Token, gitCfg.URL)
}

var n glmt.Notifier
if nfyCfg.SlackWebHook.URL != "" {
n = notifier.NewSlackWebHookNotifier(nfyCfg.SlackWebHook.URL)
}

return glmt.NewGLMT(git, gitlab)
return glmt.NewGLMT(git, gitlab, n), nil
}
13 changes: 11 additions & 2 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import (
)

type Config struct {
GitLab GitLab `json:"gitlab"`
MR MR `json:"mr"`
GitLab GitLab `json:"gitlab"`
MR MR `json:"mr"`
Notifier Notifier `json:"notifier"`
}

type GitLab struct {
Expand All @@ -26,6 +27,14 @@ type MR struct {
RemoveSourceBranch bool `json:"remove_source_branch"`
}

type Notifier struct {
SlackWebHook SlackWebHook `json:"slack_web_hook"`
}

type SlackWebHook struct {
URL string `json:"url"`
}

func LoadConfig(path string) (*Config, error) {
f, err := os.Open(path)
if err != nil {
Expand Down
7 changes: 1 addition & 6 deletions internal/git/git.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,2 @@
// Package git defines interface for git service
// Package git implements glmt.Git
package git

type Git interface {
Remote() (string, error)
CurrentBranch() (string, error)
}
3 changes: 1 addition & 2 deletions internal/git/impl/local_git.go → internal/git/local_git.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// Package impl implements git service
package impl
package git

import (
"fmt"
Expand Down
40 changes: 40 additions & 0 deletions internal/glmt/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package glmt

import "errors"

func NewNestedError(wrap, cause error) error {
if wrap == nil || cause == nil {
panic("wrap or cause can not be nil")
}

return NestedError{
wrap: wrap,
cause: cause,
}
}

// NestedError is usefull when you want to wrap unknown error
// with predefined error
type NestedError struct {
wrap error
cause error
}

func (ne NestedError) Error() string {
return ne.wrap.Error() + ": " + ne.cause.Error()
}

func (ne NestedError) Is(err error) bool {
switch err.(type) {
case NestedError:
return true
}

return errors.Is(ne.wrap, err) ||
errors.Is(ne.cause, err)
}

func (ne NestedError) As(as interface{}) bool {
return errors.As(ne.wrap, as) ||
errors.As(ne.cause, as)
}
44 changes: 44 additions & 0 deletions internal/glmt/errors_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package glmt

import (
"errors"
"io"
"net"
"testing"
)

func TestNestedErrorIs(t *testing.T) {
n := NewNestedError(ErrNotification, io.EOF)

if !errors.Is(n, NestedError{}) {
t.Fatal("error is NestedError")
}

if !errors.Is(n, ErrNotification) {
t.Fatal("error is not ErrNotification")
}

if !errors.Is(n, io.EOF) {
t.Fatal("error is not io.EOF")
}
}

func TestNestedErrorAs(t *testing.T) {
n := NewNestedError(&net.ParseError{}, &net.OpError{})

// NestedError is transparent
var ne NestedError
if !errors.As(n, &ne) {
t.Fatal("error is NestedError")
}

pe := &net.ParseError{}
if !errors.As(n, &pe) {
t.Fatal("error is not ErrNotification")
}

ope := &net.OpError{}
if !errors.As(n, &ope) {
t.Fatal("error is not io.EOF")
}
}
6 changes: 6 additions & 0 deletions internal/glmt/git.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package glmt

type Git interface {
Remote() (string, error)
CurrentBranch() (string, error)
}
27 changes: 20 additions & 7 deletions internal/glmt/glmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,29 @@ import (
"time"

"github.com/rs/zerolog/log"
"gitlab.com/glmt/glmt/internal/git"
"gitlab.com/glmt/glmt/internal/gitlab"
)

var (
ErrNotification = errors.New("notification error")
)

func NewGLMT(
git git.Git,
git Git,
gitLab gitlab.GitLab,
notifier Notifier,
) *Core {
return &Core{
git: git,
gitLab: gitLab,
git: git,
gitLab: gitLab,
notifier: notifier,
}
}

type Core struct {
git git.Git
gitLab gitlab.GitLab
git Git
gitLab gitlab.GitLab
notifier Notifier
}

type CreateMRParams struct {
Expand Down Expand Up @@ -106,7 +112,14 @@ func (c *Core) CreateMR(ctx context.Context, params CreateMRParams) (MergeReques
mr.CreatedAt = gmr.CreatedAt
mr.URL = gmr.URL

return mr, nil
if c.notifier != nil {
err = c.notifier.Send(ctx, mr.URL)
if err != nil {
err = NewNestedError(ErrNotification, err)
}
}

return mr, err
}

func projectFromRemote(rem string) (string, error) {
Expand Down
7 changes: 7 additions & 0 deletions internal/glmt/notifier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package glmt

import "context"

type Notifier interface {
Send(ctx context.Context, message string) error
}
2 changes: 2 additions & 0 deletions internal/notifier/notifier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package notifier implements glmt.Notifier
package notifier
24 changes: 24 additions & 0 deletions internal/notifier/slack_wh.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package notifier

import (
"context"

"github.com/slack-go/slack"
)

func NewSlackWebHookNotifier(url string) *SlackWebHookNotifier {
return &SlackWebHookNotifier{
url: url,
}
}

type SlackWebHookNotifier struct {
url string
}

func (sn *SlackWebHookNotifier) Send(ctx context.Context, message string) error {
msg := &slack.WebhookMessage{
Text: message,
}
return slack.PostWebhookContext(ctx, sn.url, msg)
}

0 comments on commit d990ae9

Please sign in to comment.