diff --git a/Makefile b/Makefile index 29845d84..e2fb13b3 100644 --- a/Makefile +++ b/Makefile @@ -213,6 +213,8 @@ mocks: ./daemon/inertiad/project/deployment.go Deployer counterfeiter -o ./daemon/inertiad/build/mocks/builder.go \ ./daemon/inertiad/build/builder.go ContainerBuilder + counterfeiter -o ./daemon/inertiad/notify/mocks/notify.go \ + ./daemon/inertiad/notify/notifier.go Notifier ## scripts: recompile script assets .PHONY: scripts diff --git a/client/internal/compiled.go b/client/internal/compiled.go index ae28642c..0e96eddb 100644 --- a/client/internal/compiled.go +++ b/client/internal/compiled.go @@ -1,5 +1,5 @@ -// Code generated by fileb0x at "2019-02-22 22:51:49.669477 -0800 PST m=+0.027708686" from config file "b0x.yml" DO NOT EDIT. -// modification hash(b1436cbcf3e6eb9caef571b09a6ea51f.902253dd4a7873ead7b8164875470c16) +// Code generated by fileb0x at "2019-02-23 13:54:28.818874 -0800 PST m=+0.033841651" from config file "b0x.yml" DO NOT EDIT. +// modification hash(666876753f820045880839cd7d5a88f3.902253dd4a7873ead7b8164875470c16) package internal diff --git a/daemon/inertiad/notify/mocks/notify.go b/daemon/inertiad/notify/mocks/notify.go new file mode 100644 index 00000000..cb6dde23 --- /dev/null +++ b/daemon/inertiad/notify/mocks/notify.go @@ -0,0 +1,112 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package mocks + +import ( + "sync" + + "github.com/ubclaunchpad/inertia/daemon/inertiad/notify" +) + +type FakeNotifier struct { + NotifyStub func(string, notify.Options) error + notifyMutex sync.RWMutex + notifyArgsForCall []struct { + arg1 string + arg2 notify.Options + } + notifyReturns struct { + result1 error + } + notifyReturnsOnCall map[int]struct { + result1 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeNotifier) Notify(arg1 string, arg2 notify.Options) error { + fake.notifyMutex.Lock() + ret, specificReturn := fake.notifyReturnsOnCall[len(fake.notifyArgsForCall)] + fake.notifyArgsForCall = append(fake.notifyArgsForCall, struct { + arg1 string + arg2 notify.Options + }{arg1, arg2}) + fake.recordInvocation("Notify", []interface{}{arg1, arg2}) + fake.notifyMutex.Unlock() + if fake.NotifyStub != nil { + return fake.NotifyStub(arg1, arg2) + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.notifyReturns + return fakeReturns.result1 +} + +func (fake *FakeNotifier) NotifyCallCount() int { + fake.notifyMutex.RLock() + defer fake.notifyMutex.RUnlock() + return len(fake.notifyArgsForCall) +} + +func (fake *FakeNotifier) NotifyCalls(stub func(string, notify.Options) error) { + fake.notifyMutex.Lock() + defer fake.notifyMutex.Unlock() + fake.NotifyStub = stub +} + +func (fake *FakeNotifier) NotifyArgsForCall(i int) (string, notify.Options) { + fake.notifyMutex.RLock() + defer fake.notifyMutex.RUnlock() + argsForCall := fake.notifyArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeNotifier) NotifyReturns(result1 error) { + fake.notifyMutex.Lock() + defer fake.notifyMutex.Unlock() + fake.NotifyStub = nil + fake.notifyReturns = struct { + result1 error + }{result1} +} + +func (fake *FakeNotifier) NotifyReturnsOnCall(i int, result1 error) { + fake.notifyMutex.Lock() + defer fake.notifyMutex.Unlock() + fake.NotifyStub = nil + if fake.notifyReturnsOnCall == nil { + fake.notifyReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.notifyReturnsOnCall[i] = struct { + result1 error + }{result1} +} + +func (fake *FakeNotifier) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.notifyMutex.RLock() + defer fake.notifyMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeNotifier) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ notify.Notifier = new(FakeNotifier) diff --git a/daemon/inertiad/notify/notifier.go b/daemon/inertiad/notify/notifier.go new file mode 100644 index 00000000..bed8bc33 --- /dev/null +++ b/daemon/inertiad/notify/notifier.go @@ -0,0 +1,54 @@ +package notify + +import ( + "go.uber.org/multierr" +) + +// Notifiers is a collection of notification targets +type Notifiers []Notifier + +// Notify delivers a notification to all targets +func (n Notifiers) Notify(msg string, opts Options) error { + if len(n) == 0 { + return nil + } + + var errs error + for _, notif := range n { + errs = multierr.Append(errs, notif.Notify(msg, opts)) + } + return errs +} + +// Notifier manages notifications +type Notifier interface { + Notify(string, Options) error +} + +// Options is used to configure formatting of notifications +type Options struct { + Color Color +} + +// Color is used to represent message color for different states (i.e success, fail) +type Color string + +const ( + // Green for success messages + Green Color = "good" + // Yellow for warning messages + Yellow Color = "warning" + // Red for error messages + Red Color = "danger" +) + +// MessageArray builds the json message to be posted to webhook +type MessageArray struct { + Attachments []Message `json:"attachments"` +} + +// Message builds the attachments content of Message +type Message struct { + Text string `json:"text"` + Color string `json:"color"` +} diff --git a/daemon/inertiad/notify/slack.go b/daemon/inertiad/notify/slack.go new file mode 100644 index 00000000..687b1bd7 --- /dev/null +++ b/daemon/inertiad/notify/slack.go @@ -0,0 +1,62 @@ +package notify + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" +) + +// SlackNotifier represents slack notifications +type SlackNotifier struct { + hookURL string +} + +// NewSlackNotifier creates a notifier with web hook url to slack channel. Passing +// it an empty url makes it a no-op notifier. +func NewSlackNotifier(webhookURL string) Notifier { + return &SlackNotifier{ + hookURL: webhookURL, + } +} + +// Notify sends the notification +func (n *SlackNotifier) Notify(text string, options Options) error { + if n.hookURL == "" { + return nil + } + + b, err := json.Marshal(MessageArray{ + Attachments: []Message{ + { + Text: fmt.Sprintf("*%s*", text), + Color: colorToString(options.Color), + }, + }, + }) + if err != nil { + return fmt.Errorf("failed to encode request: %w", err) + } + + resp, err := http.Post(n.hookURL, "application/json", bytes.NewBuffer(b)) + if err != nil { + return err + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("failed to read response body: %w", err) + } + if resp.StatusCode < 200 || resp.StatusCode > 299 { + return errors.New("http request rejected by Slack: " + string(body)) + } + + return nil +} + +func colorToString(color Color) string { + return string(color) +} diff --git a/daemon/inertiad/project/deployment.go b/daemon/inertiad/project/deployment.go index 8edc625c..c5ee3595 100644 --- a/daemon/inertiad/project/deployment.go +++ b/daemon/inertiad/project/deployment.go @@ -13,14 +13,16 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" docker "github.com/docker/docker/client" + gogit "gopkg.in/src-d/go-git.v4" + "gopkg.in/src-d/go-git.v4/plumbing/transport/ssh" + "github.com/ubclaunchpad/inertia/api" "github.com/ubclaunchpad/inertia/common" "github.com/ubclaunchpad/inertia/daemon/inertiad/build" "github.com/ubclaunchpad/inertia/daemon/inertiad/containers" "github.com/ubclaunchpad/inertia/daemon/inertiad/crypto" "github.com/ubclaunchpad/inertia/daemon/inertiad/git" - gogit "gopkg.in/src-d/go-git.v4" - "gopkg.in/src-d/go-git.v4/plumbing/transport/ssh" + "github.com/ubclaunchpad/inertia/daemon/inertiad/notify" ) // Deployer manages the deployed user project @@ -60,6 +62,8 @@ type Deployment struct { mux sync.Mutex dataManager *DeploymentDataManager + + notifiers notify.Notifiers } // DeploymentConfig is used to configure Deployment @@ -148,6 +152,8 @@ func (d *Deployment) SetConfig(cfg DeploymentConfig) { if cfg.BuildFilePath != "" { d.buildFilePath = cfg.BuildFilePath } + + // TODO: register notifiers } // DeployOptions is used to configure how the deployment handles the deploy @@ -196,9 +202,21 @@ func (d *Deployment) Deploy( // Build project deploy, err := d.builder.Build(strings.ToLower(d.buildType), *conf, cli, out) if err != nil { + if notifyErr := d.notifiers.Notify("Build error", notify.Options{ + Color: notify.Red, + }); notifyErr != nil { + fmt.Fprintln(out, notifyErr.Error()) + } return func() error { return nil }, err } + // Send build complete slack notification + if notifyErr := d.notifiers.Notify("Build completed", notify.Options{ + Color: notify.Green, + }); notifyErr != nil { + fmt.Fprintln(out, notifyErr.Error()) + } + // Deploy return func() error { d.active = true diff --git a/daemon/inertiad/project/deployment_test.go b/daemon/inertiad/project/deployment_test.go index 4907ae6a..0823437f 100644 --- a/daemon/inertiad/project/deployment_test.go +++ b/daemon/inertiad/project/deployment_test.go @@ -118,6 +118,7 @@ func TestGetStatusIntegration(t *testing.T) { builder: fakeBuilder, } status, err := deployment.GetStatus(cli) + assert.NoError(t, err) assert.False(t, status.BuildContainerActive) assert.Equal(t, "test", status.BuildType) diff --git a/go.mod b/go.mod index 3dd7dd35..8976c5a8 100644 --- a/go.mod +++ b/go.mod @@ -27,6 +27,7 @@ require ( github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/kyokomi/emoji v2.1.1-0.20190303065119-51762253ec2b+incompatible github.com/mattn/go-isatty v0.0.6 // indirect + github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/gox v1.0.1 github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect @@ -42,13 +43,14 @@ require ( github.com/stretchr/testify v1.3.0 github.com/xanzy/ssh-agent v0.2.1 // indirect go.etcd.io/bbolt v1.3.2 + go.uber.org/atomic v1.4.0 // indirect + go.uber.org/multierr v1.2.0 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac - golang.org/x/net v0.0.0-20190311183353-d8887717615a + golang.org/x/net v0.0.0-20190628185345-da137c7871d7 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect google.golang.org/grpc v1.23.1 // indirect gopkg.in/src-d/go-billy.v4 v4.3.0 // indirect gopkg.in/src-d/go-git.v4 v4.10.0 - gopkg.in/yaml.v2 v2.2.2 // indirect gotest.tools v2.2.0+incompatible // indirect ) diff --git a/go.sum b/go.sum index 363125d4..a60f78b7 100644 --- a/go.sum +++ b/go.sum @@ -44,6 +44,7 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-chi/chi v4.0.2+incompatible h1:maB6vn6FqCxrpz4FqWdh4+lwpyZIQS7YEAUcHlgXVRs= @@ -59,6 +60,7 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= @@ -67,6 +69,7 @@ github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/hashicorp/go-version v1.0.0 h1:21MVWPKDphxa7ineQQTrCU5brh7OuVVAzGOCnnCPtE8= github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -74,6 +77,7 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/karrick/godirwalk v1.7.8 h1:VfG72pyIxgtC7+3X9CMHI0AOl4LwyRAg98WAgsvffi8= github.com/karrick/godirwalk v1.7.8/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34= github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e h1:RgQk53JHp/Cjunrr1WlsXSZpqXn+uREuHvUVcK82CV8= @@ -102,6 +106,8 @@ github.com/mattn/go-isatty v0.0.6 h1:SrwhHcpV4nWrMGdNcC2kXpMfcBVYGDuTArqyhocJgvA github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8BzLR4= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2 h1:g+4J5sZg6osfvEfkRZxJ1em0VT95/UOZgi/l7zi1/oE= +github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -115,6 +121,9 @@ github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8d github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/nsf/termbox-go v0.0.0-20180819125858-b66b20ab708e h1:fvw0uluMptljaRKSU8459cJ4bmi3qUYyMs5kzpic2fY= github.com/nsf/termbox-go v0.0.0-20180819125858-b66b20ab708e/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= @@ -130,6 +139,7 @@ github.com/pquerna/otp v1.1.0 h1:q2gMsMuMl3JzneUaAX1MRGxLvOG6bzXV51hivBaStf0= github.com/pquerna/otp v1.1.0/go.mod h1:Zad1CMQfSQZI5KLpahDiSUX4tMMREnXw98IvL1nhgMk= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= @@ -156,6 +166,10 @@ github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70 github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.2.0 h1:6I+W7f5VwC5SV9dNrZ3qXrDB9mD0dyGOi/ZJmYw03T4= +go.uber.org/multierr v1.2.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -168,24 +182,34 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180921000356-2f5d2388922f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181019160139-8e24a49d80f8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db h1:9hRk1xeL9LTT3yX/941DqeBz87XgHAQuj+TbimYJuiw= +golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -194,6 +218,7 @@ google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/src-d/go-billy.v4 v4.2.1/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk= gopkg.in/src-d/go-billy.v4 v4.3.0 h1:KtlZ4c1OWbIs4jCv5ZXrTqG8EQocr0g/d4DjNg70aek= gopkg.in/src-d/go-billy.v4 v4.3.0/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk= @@ -201,6 +226,7 @@ gopkg.in/src-d/go-git-fixtures.v3 v3.1.1 h1:XWW/s5W18RaJpmo1l0IYGqXKuJITWRFuA45i gopkg.in/src-d/go-git-fixtures.v3 v3.1.1/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= gopkg.in/src-d/go-git.v4 v4.10.0 h1:NWjTJTQnk8UpIGlssuefyDZ6JruEjo5s88vm88uASbw= gopkg.in/src-d/go-git.v4 v4.10.0/go.mod h1:Vtut8izDyrM8BUVQnzJ+YvmNcem2J89EmfZYCkLokZk= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/internal/tools/tools.go b/internal/tools/tools.go index 55c81164..724d67be 100644 --- a/internal/tools/tools.go +++ b/internal/tools/tools.go @@ -4,6 +4,7 @@ package tools import ( _ "github.com/UnnoTed/fileb0x" + _ "github.com/maxbrunsfeld/counterfeiter/v6" _ "github.com/mitchellh/gox" _ "golang.org/x/lint/golint" )