diff --git a/Makefile b/Makefile index 609f3134..e3ae23cf 100644 --- a/Makefile +++ b/Makefile @@ -17,9 +17,7 @@ FRONTEND_DIR = $(BIN_DIR)/ui/app DOCKER_IMAGE_NAME ?= alertmanager ERRCHECK_BINARY := $(FIRST_GOPATH)/bin/errcheck -STATICCHECK_IGNORE = \ - github.com/prometheus/alertmanager/notify/notify.go:SA6002 - +STATICCHECK_IGNORE = # Go modules needs the bzr binary because of the dependency on launchpad.net/gocheck. $(eval $(call PRECHECK_COMMAND_template,bzr)) diff --git a/Makefile.common b/Makefile.common index 741579e6..fff85f92 100644 --- a/Makefile.common +++ b/Makefile.common @@ -29,6 +29,8 @@ GO ?= go GOFMT ?= $(GO)fmt FIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH))) GOOPTS ?= +GOHOSTOS ?= $(shell $(GO) env GOHOSTOS) +GOHOSTARCH ?= $(shell $(GO) env GOHOSTARCH) GO_VERSION ?= $(shell $(GO) version) GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION)) @@ -62,17 +64,30 @@ PROMU := $(FIRST_GOPATH)/bin/promu STATICCHECK := $(FIRST_GOPATH)/bin/staticcheck pkgs = ./... -GO_VERSION ?= $(shell $(GO) version) -GO_BUILD_PLATFORM ?= $(subst /,-,$(lastword $(GO_VERSION))) +ifeq (arm, $(GOHOSTARCH)) + GOHOSTARM ?= $(shell GOARM= $(GO) env GOARM) + GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)v$(GOHOSTARM) +else + GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH) +endif PROMU_VERSION ?= 0.2.0 PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz +STATICCHECK_VERSION ?= 2019.1 +STATICCHECK_URL := https://github.com/dominikh/go-tools/releases/download/$(STATICCHECK_VERSION)/staticcheck_$(GOHOSTOS)_$(GOHOSTARCH) PREFIX ?= $(shell pwd) BIN_DIR ?= $(shell pwd) DOCKER_IMAGE_TAG ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD)) DOCKER_REPO ?= prom +ifeq ($(GOHOSTARCH),amd64) + ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux freebsd darwin windows)) + # Only supported on amd64 + test-flags := -race + endif +endif + .PHONY: all all: precheck style staticcheck unused build test @@ -110,12 +125,12 @@ common-test-short: .PHONY: common-test common-test: @echo ">> running all tests" - GO111MODULE=$(GO111MODULE) $(GO) test -race $(GOOPTS) $(pkgs) + GO111MODULE=$(GO111MODULE) $(GO) test $(test-flags) $(GOOPTS) $(pkgs) .PHONY: common-format common-format: @echo ">> formatting code" - GO111MODULE=$(GO111MODULE) $(GO) fmt $(GOOPTS) $(pkgs) + GO111MODULE=$(GO111MODULE) $(GO) fmt $(pkgs) .PHONY: common-vet common-vet: @@ -125,8 +140,12 @@ common-vet: .PHONY: common-staticcheck common-staticcheck: $(STATICCHECK) @echo ">> running staticcheck" + chmod +x $(STATICCHECK) ifdef GO111MODULE - GO111MODULE=$(GO111MODULE) $(STATICCHECK) -ignore "$(STATICCHECK_IGNORE)" -checks "SA*" $(pkgs) +# 'go list' needs to be executed before staticcheck to prepopulate the modules cache. +# Otherwise staticcheck might fail randomly for some reason not yet explained. + GO111MODULE=$(GO111MODULE) $(GO) list -e -compiled -test=true -export=false -deps=true -find=false -tags= -- ./... > /dev/null + GO111MODULE=$(GO111MODULE) $(STATICCHECK) -ignore "$(STATICCHECK_IGNORE)" $(pkgs) else $(STATICCHECK) -ignore "$(STATICCHECK_IGNORE)" $(pkgs) endif @@ -140,8 +159,9 @@ else ifdef GO111MODULE @echo ">> running check for unused/missing packages in go.mod" GO111MODULE=$(GO111MODULE) $(GO) mod tidy +ifeq (,$(wildcard vendor)) @git diff --exit-code -- go.sum go.mod -ifneq (,$(wildcard vendor)) +else @echo ">> running check for unused packages in vendor/" GO111MODULE=$(GO111MODULE) $(GO) mod vendor @git diff --exit-code -- go.sum go.mod vendor/ @@ -175,30 +195,20 @@ common-docker-tag-latest: promu: $(PROMU) $(PROMU): - curl -s -L $(PROMU_URL) | tar -xvz -C /tmp - mkdir -v -p $(FIRST_GOPATH)/bin - cp -v /tmp/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM)/promu $(PROMU) + $(eval PROMU_TMP := $(shell mktemp -d)) + curl -s -L $(PROMU_URL) | tar -xvzf - -C $(PROMU_TMP) + mkdir -p $(FIRST_GOPATH)/bin + cp $(PROMU_TMP)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM)/promu $(FIRST_GOPATH)/bin/promu + rm -r $(PROMU_TMP) .PHONY: proto proto: @echo ">> generating code from proto files" @./scripts/genproto.sh -.PHONY: $(STATICCHECK) $(STATICCHECK): -ifdef GO111MODULE -# Get staticcheck from a temporary directory to avoid modifying the local go.{mod,sum}. -# See https://github.com/golang/go/issues/27643. -# For now, we are using the next branch of staticcheck because master isn't compatible yet with Go modules. - tmpModule=$$(mktemp -d 2>&1) && \ - mkdir -p $${tmpModule}/staticcheck && \ - cd "$${tmpModule}"/staticcheck && \ - GO111MODULE=on $(GO) mod init example.com/staticcheck && \ - GO111MODULE=on GOOS= GOARCH= $(GO) get -u honnef.co/go/tools/cmd/staticcheck@next && \ - rm -rf $${tmpModule}; -else - GOOS= GOARCH= GO111MODULE=off $(GO) get -u honnef.co/go/tools/cmd/staticcheck -endif + mkdir -p $(FIRST_GOPATH)/bin + curl -s -L $(STATICCHECK_URL) > $(STATICCHECK) ifdef GOVENDOR .PHONY: $(GOVENDOR) diff --git a/api/v1/api.go b/api/v1/api.go index 6b19cd53..a8e2cc52 100644 --- a/api/v1/api.go +++ b/api/v1/api.go @@ -165,7 +165,6 @@ func (api *API) Update(cfg *config.Config, resolveTimeout time.Duration) error { type errorType string const ( - errorNone errorType = "" errorInternal errorType = "server_error" errorBadData errorType = "bad_data" ) diff --git a/cli/routing.go b/cli/routing.go index eaafbe6a..9d9556b3 100644 --- a/cli/routing.go +++ b/cli/routing.go @@ -29,7 +29,6 @@ type routingShow struct { configFile string labels []string expectedReceivers string - tree treeprint.Tree debugTree bool } @@ -106,15 +105,15 @@ func getMatchingTree(route *dispatch.Route, tree treeprint.Tree, lset client.Lab final := true branch := tree.AddBranch(getRouteTreeSlug(route, false, false)) for _, r := range route.Routes { - if r.Matchers.Match(convertClientToCommonLabelSet(lset)) == true { + if r.Matchers.Match(convertClientToCommonLabelSet(lset)) { getMatchingTree(r, branch, lset) final = false - if r.Continue != true { + if !r.Continue { break } } } - if final == true { + if final { branch.SetValue(getRouteTreeSlug(route, false, true)) } } diff --git a/cli/test_routing.go b/cli/test_routing.go index 2c68bad8..0a35d4e9 100644 --- a/cli/test_routing.go +++ b/cli/test_routing.go @@ -84,7 +84,7 @@ func (c *routingShow) routingTestAction(ctx context.Context, _ *kingpin.ParseCon kingpin.Fatalf("Failed to parse labels: %v\n", err) } - if c.debugTree == true { + if c.debugTree { printMatchingTree(mainRoute, ls) } diff --git a/cli/utils.go b/cli/utils.go index 66b481ed..929ded42 100644 --- a/cli/utils.go +++ b/cli/utils.go @@ -112,7 +112,7 @@ func loadAlertmanagerConfig(ctx context.Context, alertmanagerURL *url.URL, confi } return status.ConfigJSON, nil } - return nil, errors.New("Failed to get Alertmanager configuration.") + return nil, errors.New("failed to get Alertmanager configuration") } // convertClientToCommonLabelSet converts client.LabelSet to model.Labelset diff --git a/client/client.go b/client/client.go index 976fe62b..fbeedc90 100644 --- a/client/client.go +++ b/client/client.go @@ -31,11 +31,10 @@ import ( const ( apiPrefix = "/api/v1" - epStatus = apiPrefix + "/status" - epSilence = apiPrefix + "/silence/:id" - epSilences = apiPrefix + "/silences" - epAlerts = apiPrefix + "/alerts" - epAlertGroups = apiPrefix + "/alerts/groups" + epStatus = apiPrefix + "/status" + epSilence = apiPrefix + "/silence/:id" + epSilences = apiPrefix + "/silences" + epAlerts = apiPrefix + "/alerts" statusSuccess = "success" statusError = "error" diff --git a/client/client_test.go b/client/client_test.go index 56004363..b9bdf47b 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -319,7 +319,7 @@ func TestAPI(t *testing.T) { if err != nil { t.Fatal(err) } - if bytes.Compare(want, got) != 0 { + if !bytes.Equal(want, got) { t.Errorf("unexpected result: want: %s, got: %s", string(want), string(got)) } }) diff --git a/nflog/nflogpb/set_test.go b/nflog/nflogpb/set_test.go index 49fe1d33..5a2182a4 100644 --- a/nflog/nflogpb/set_test.go +++ b/nflog/nflogpb/set_test.go @@ -84,7 +84,7 @@ func newSubset(elements ...uint64) map[uint64]struct{} { func elements(m map[uint64]struct{}) []uint64 { els := make([]uint64, 0, len(m)) - for k, _ := range m { + for k := range m { els = append(els, k) } diff --git a/notify/impl.go b/notify/impl.go index 5d514b76..c2f7b670 100644 --- a/notify/impl.go +++ b/notify/impl.go @@ -895,7 +895,7 @@ func (n *Hipchat) Notify(ctx context.Context, as ...*types.Alert) (bool, error) ) apiURL.Path += fmt.Sprintf("v2/room/%s/notification", roomid) q := apiURL.Query() - q.Set("auth_token", fmt.Sprintf("%s", n.conf.AuthToken)) + q.Set("auth_token", string(n.conf.AuthToken)) apiURL.RawQuery = q.Encode() if n.conf.MessageFormat == "html" { @@ -1007,7 +1007,7 @@ func (n *Wechat) Notify(ctx context.Context, as ...*types.Alert) (bool, error) { } // Refresh AccessToken over 2 hours - if n.accessToken == "" || time.Now().Sub(n.accessTokenAt) > 2*time.Hour { + if n.accessToken == "" || time.Since(n.accessTokenAt) > 2*time.Hour { parameters := url.Values{} parameters.Add("corpsecret", tmpl(string(n.conf.APISecret))) parameters.Add("corpid", tmpl(string(n.conf.CorpID))) diff --git a/notify/notify.go b/notify/notify.go index 4e28428d..bf72b2db 100644 --- a/notify/notify.go +++ b/notify/notify.go @@ -489,6 +489,7 @@ func getHashBuffer() []byte { func putHashBuffer(b []byte) { b = b[:0] + //lint:ignore SA6002 relax staticcheck verification. hashBuffers.Put(b) } diff --git a/pkg/parse/parse.go b/pkg/parse/parse.go index 1a03592d..fd526aba 100644 --- a/pkg/parse/parse.go +++ b/pkg/parse/parse.go @@ -33,12 +33,8 @@ var ( func Matchers(s string) ([]*labels.Matcher, error) { matchers := []*labels.Matcher{} - if strings.HasPrefix(s, "{") { - s = s[1:] - } - if strings.HasSuffix(s, "}") { - s = s[:len(s)-1] - } + s = strings.TrimPrefix(s, "{") + s = strings.TrimSuffix(s, "}") var insideQuotes bool var token string diff --git a/test/with_api_v1/acceptance.go b/test/with_api_v1/acceptance.go index 97265ce7..ea181d5c 100644 --- a/test/with_api_v1/acceptance.go +++ b/test/with_api_v1/acceptance.go @@ -191,7 +191,7 @@ func (t *AcceptanceTest) Run() { deadline := t.opts.expandTime(latest) select { - case <-time.After(deadline.Sub(time.Now())): + case <-time.After(time.Until(deadline)): // continue case err := <-errc: t.Error(err) @@ -213,7 +213,7 @@ func (t *AcceptanceTest) runActions() { for _, f := range fs { go func(f func()) { - time.Sleep(ts.Sub(time.Now())) + time.Sleep(time.Until(ts)) f() wg.Done() }(f) diff --git a/test/with_api_v2/acceptance.go b/test/with_api_v2/acceptance.go index 81c49057..2725d52f 100644 --- a/test/with_api_v2/acceptance.go +++ b/test/with_api_v2/acceptance.go @@ -199,7 +199,7 @@ func (t *AcceptanceTest) Run() { deadline := t.opts.expandTime(latest) select { - case <-time.After(deadline.Sub(time.Now())): + case <-time.After(time.Until(deadline)): // continue case err := <-errc: t.Error(err) @@ -216,7 +216,7 @@ func (t *AcceptanceTest) runActions() { for _, f := range fs { go func(f func()) { - time.Sleep(ts.Sub(time.Now())) + time.Sleep(time.Until(ts)) f() wg.Done() }(f) diff --git a/types/types.go b/types/types.go index 1299f45a..67713584 100644 --- a/types/types.go +++ b/types/types.go @@ -373,10 +373,6 @@ type Silence struct { CreatedBy string `json:"createdBy"` Comment string `json:"comment,omitempty"` - // timeFunc provides the time against which to evaluate - // the silence. Used for test injection. - now func() time.Time - Status SilenceStatus `json:"status"` }