diff --git a/.make/.gitignore b/.make/.gitignore new file mode 100644 index 0000000..33733b7 --- /dev/null +++ b/.make/.gitignore @@ -0,0 +1,2 @@ +.tools +.build diff --git a/.make/Makefile.common b/.make/Makefile.common new file mode 100644 index 0000000..bd83472 --- /dev/null +++ b/.make/Makefile.common @@ -0,0 +1,116 @@ +MAKE_DIR ?= .make + +# all go sources in build tree excluding vendor +SOURCES ?= $(shell find . -type f \( -iname '*.go' \) -not \( -path "./vendor/*" -path ".*" \)) + +export GO111MODULE = on +export CGO_ENABLED ?= 0 + +# do not use automatic targets +.SUFFIXES: + +all: lint test + +### +### Maintenance +### + +fmt: $(SOURCES) ## format go sources + gofmt -w -s -l $^ + +mod-tidy: ## tidy go.mod + go mod tidy +.NOTPARALLEL: mod-tidy +.PHONY: mod-tidy + + +### +### Tools and external binaries +### +### Use $(TOOL)/go/package as prerequisite. Requested tool will be +### installed automatically on demand. +### Use .bin-my-binary as prerequisite to assert required binary in path +### + +TOOLS ?= $(MAKE_DIR)/.tools +$(TOOLS)/%: + test -x "$@" || (mkdir -p /tmp/.INSTALL/$* && cd /tmp/.INSTALL/$* && echo "module toolchain" > go.mod && GOBIN=$(shell pwd)/$(dir $@) go get -u $* && rm -rf /tmp/.INSTALL/$*) + +.bin-%: + @test -x "$(shell which $*)" || (echo "binary $* not found" && exit 2) + +clean:: + rm -rf $(TOOLS) + + +### +### Test +### + +TESTS ?= . +TEST_TAGS ?= +TEST_ARGS ?= + +test: $(SOURCES) go.mod ## regular tests + go test $(TEST_ARGS) -tags="$(TEST_TAGS)" -run=$(TESTS) ./... + +race: $(SOURCES) go.mod ## race tests + CGO_ENABLED=1 go test $(TEST_ARGS) -tags="$(TEST_TAGS)" -race -run=$(TESTS) ./... + +bench: $(SOURCES) go.mod ## benchmarks + go test $(TEST_ARGS) -tags="$(TEST_TAGS)" -run=^$ -bench=$(TESTS) -benchmem -cpu 32 ./... + +test-nocache: $(SOURCES) go.mod + go test $(TEST_ARGS) -tags="$(TEST_TAGS)" -count=1 -run=$(TESTS) ./... + +race-nocache: $(SOURCES) go.mod + CGO_ENABLED=1 go test $(TEST_ARGS) -tags="$(TEST_TAGS)" -race -count=1 -run=$(TESTS) ./... + + +### +### Lint +### + +lint:: \ + .lint-fmt \ + .lint-mod-tidy \ + .lint-mod-verify \ + .lint-vet + +.lint-fmt: $(SOURCES) ## compare gofmt output + @DIFF=`gofmt -s -d $^` && echo "$$DIFF" && test -z "$$DIFF" + +.lint-vet: $(SOURCES) go.mod ## run vet + go vet $(VET_FLAGS) ./... +.NOTPARALLEL: .lint-vet + +.lint-mod-tidy: ## check go mod tidy is applied + @rm -f go.sum /tmp/$(PROJECT).go.mod.tidy.bak /tmp/$(PROJECT).go.mod.tidy + @cp go.mod /tmp/$(PROJECT).go.mod.tidy.bak + @go mod tidy + @mv go.mod /tmp/$(PROJECT).go.mod.tidy + @mv /tmp/$(PROJECT).go.mod.tidy.bak go.mod + diff go.mod /tmp/$(PROJECT).go.mod.tidy +.NOTPARALLEL: .lint-mod-tidy +.PHONY: .lint-mod-tidy + +.lint-mod-verify: + go mod verify + +lint-mod-outdated: ## check outdated deps + @rm -f go.sum /tmp/$(PROJECT).go.mod.bak /tmp/$(PROJECT).go.mod.up + @cp go.mod /tmp/$(PROJECT).go.mod.bak + @go get -u + @go mod tidy + @mv go.mod /tmp/$(PROJECT).go.mod.up + @mv /tmp/$(PROJECT).go.mod.bak go.mod + diff go.mod /tmp/$(PROJECT).go.mod.up +.NOTPARALLEL: lint-mod-outdated +.PHONY: lint-mod-outdated + +### +### Self update +### + +make-go-update: .bin-tar .bin-curl .bin-env .bin-sh + curl -sSL https://github.com/akaspin/make-go/raw/master/setup.sh | sh - diff --git a/.make/Makefile.revive b/.make/Makefile.revive new file mode 100644 index 0000000..9b5efaf --- /dev/null +++ b/.make/Makefile.revive @@ -0,0 +1,5 @@ +REVIVE_CONFIG ?= $(or $(wildcard revive.toml),$(MAKE_DIR)/revive.toml) +.lint-revive: $(TOOLS)/github.com/mgechev/revive $(REVIVE_CONFIG) $(SOURCES) ## run revive linter + $< -config $(REVIVE_CONFIG) -formatter friendly -exclude ./vendor/... $(REVIVELINTER_EXCLUDES) ./... + +lint:: .lint-revive diff --git a/.make/Makefile.shadow b/.make/Makefile.shadow new file mode 100644 index 0000000..4cbc841 --- /dev/null +++ b/.make/Makefile.shadow @@ -0,0 +1,5 @@ +.lint-shadow: $(TOOLS)/golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow $(SOURCES) + go vet -vettool=$< ./... +.NOTPARALLEL: .lint-shadow + +lint:: .lint-shadow diff --git a/.make/README.md b/.make/README.md new file mode 100644 index 0000000..f210c3e --- /dev/null +++ b/.make/README.md @@ -0,0 +1,19 @@ +# go-make + +The goal is simplify and streamline development of Golang projects. + +## Installation and update + +```console +$ curl -sSL https://github.com/akaspin/make-go/raw/master/setup.sh | sh - +``` + +This oneliner will install files to `.make` directory. To use features include +installed Makefiles in your Make. + +```makefile +include .make/Makefile.common .make/Makefile.shadow +``` + +Use `make-go-update` target to update to the latest version. + diff --git a/revive.toml b/.make/revive.toml similarity index 60% rename from revive.toml rename to .make/revive.toml index d0ed48d..ca0bbfe 100644 --- a/revive.toml +++ b/.make/revive.toml @@ -4,27 +4,44 @@ confidence = 0.8 errorCode = 2 warningCode = 1 +#[rule.add-constant] +[rule.atomic] +#[rule.bare-return] [rule.blank-imports] +[rule.bool-literal-in-expr] +[rule.confusing-naming] +[rule.confusing-results] +[rule.constant-logical-expr] [rule.context-as-argument] [rule.context-keys-type] +[rule.deep-exit] [rule.dot-imports] +[rule.empty-block] +[rule.error-naming] [rule.error-return] [rule.error-strings] -[rule.error-naming] +[rule.errorf] [rule.exported] +[rule.flag-parameter] +[rule.get-return] [rule.if-return] +[rule.import-shadowing] [rule.increment-decrement] -[rule.var-naming] -[rule.var-declaration] +[rule.indent-error-flow] +[rule.modifies-parameter] +[rule.modifies-value-receiver] [rule.package-comments] +[rule.range-val-in-closure] [rule.range] [rule.receiver-naming] +[rule.redefines-builtin-id] +[rule.struct-tag] +[rule.superfluous-else] [rule.time-naming] [rule.unexported-return] -[rule.indent-error-flow] -[rule.errorf] -[rule.empty-block] -[rule.superfluous-else] -[rule.unused-parameter] +[rule.unnecessary-stmt] [rule.unreachable-code] -[rule.redefines-builtin-id] +[rule.unused-parameter] +[rule.var-declaration] +[rule.var-naming] +[rule.waitgroup-by-value] diff --git a/.make/setup.sh b/.make/setup.sh new file mode 100755 index 0000000..e3837b6 --- /dev/null +++ b/.make/setup.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +set -ae + +rm -f \ + .make/.gitignore \ + .make/setup.sh \ + .make/Makefile.common \ + .make/Makefile.revive \ + .make/revive.toml +mkdir -p .make +curl -sSL https://github.com/akaspin/make-go/tarball/master | tar --strip-components 1 -xz -C .make diff --git a/.travis.yml b/.travis.yml index 02d6523..dfe7130 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,9 @@ language: go go: -- 1.11.2 +- '1.11.6' +- '1.12' +- '1.13' cache: directories: @@ -10,10 +12,7 @@ cache: - "$HOME/.cache/go-build" script: -- make coverage lint - -after_success: -- bash <(curl -s https://codecov.io/bash) +- make lint race-nocache branches: only: diff --git a/Makefile b/Makefile index 0c8acdb..4ed4b5c 100644 --- a/Makefile +++ b/Makefile @@ -1,77 +1 @@ - -# all go sources excluding vendor -GO_SOURCES = $(shell find . -type f \( -iname '*.go' \) -not -path "./vendor/*" 2>/dev/null) -.SUFFIXES: - -# Required to use modules inside GOPATH with Go 1.11. Temporary. -export GO111MODULE ?= on - -## -## Use $(eval $(call TOOL,,)) to make .TOOL- target -## .TOOL-* targets can be used as dependencies for goals which requires -## specific binaries. All binaries will be installed to $GOBIN directory. -## Hint: to install tools to specific directory override GOBIN and PATH -## OS environment variables. -## - -define TOOL -.TOOL-$1: - test -x "$(shell which $1)" \ - || (mkdir -p /tmp/.INSTALL-$1 && cd /tmp/.INSTALL-$1 && \ - echo "module toolchain" > go.mod && \ - go get -u $2 && \ - rm -rf /tmp/.INSTALL-$1) -.NOTPARALLEL: .TOOL-$1 -endef - -## -## Maintenance -## - -go.mod: $(GO_SOURCES) - go mod tidy - -mod: $(GO_SOURCES) - go get -u=patch - go mod tidy - -mod-vendor: go.mod - go mod vendor - -fmt: $(GO_SOURCES) - go fmt ./... - -## -## Testing and lint -## - -.PHONY: test bench race - -test: go.mod - go test -run=Test ./... - -coverage: go.mod - go test -coverprofile=coverage.txt -covermode=atomic ./... - -race: go.mod - go test -run=Test -race ./... - -examples: go.mod - go test -run=Example ./... - -bench: go.mod - go test -run= -bench=. -benchmem ./... - -lint: .ASSERT-fmt .ASSERT-vet .ASSERT-lint - -.ASSERT-fmt: $(GO_SOURCES) - @DIFF=`gofmt -s -d $^` && echo "$$DIFF" && test -z "$$DIFF" - -.ASSERT-vet: $(GO_SOURCES) go.mod - go vet ./... -.NOTPARALLEL: .ASSERT-vet - -$(eval $(call TOOL,revive,github.com/mgechev/revive)) -.ASSERT-lint: .TOOL-revive $(GO_SOURCES) - revive -config revive.toml -formatter friendly -exclude ./vendor/... ./... - +include .make/Makefile.common .make/Makefile.revive diff --git a/README.md b/README.md index 5809bbf..28a4183 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,3 @@ [![GoDoc](https://godoc.org/github.com/akaspin/supervisor?status.svg)](http://godoc.org/github.com/akaspin/supervisor) [![Build Status](https://img.shields.io/travis/akaspin/supervisor/master.svg)](https://travis-ci.org/akaspin/supervisor) -[![Codecov](https://img.shields.io/codecov/c/github/akaspin/supervisor/master.svg)](https://codecov.io/gh/akaspin/supervisor) diff --git a/composite.go b/composite.go index 0a8e8f9..42467ef 100644 --- a/composite.go +++ b/composite.go @@ -43,7 +43,7 @@ func newComposite(ctx context.Context, handler func(control *compositeControl)) } // Open blocks until all components are opened. This method should be called -// before Close(). Otherwise Open() will return error. If Open() method of one +// before Close(). Otherwise, Open() will return error. If Open() method of one // of components returns error all opened components will be closed. This // method may be called many times and will return equal results. It's // guaranteed that Open() method of all components will be called only once. diff --git a/control.go b/control.go index d6b32a4..876baea 100644 --- a/control.go +++ b/control.go @@ -17,7 +17,7 @@ type Control struct { func NewControl(ctx context.Context) (c *Control) { c = &Control{} c.ctx, c.cancel = context.WithCancel(ctx) - return + return c } // Open sets Control in open state diff --git a/go.mod b/go.mod index b7f29f7..cb2bd11 100644 --- a/go.mod +++ b/go.mod @@ -4,3 +4,5 @@ require ( github.com/akaspin/errslice v1.0.1 github.com/stretchr/testify v1.2.2 ) + +go 1.13 diff --git a/timeout_test.go b/timeout_test.go index 0dfca4c..34ff2e6 100644 --- a/timeout_test.go +++ b/timeout_test.go @@ -3,10 +3,11 @@ package supervisor_test import ( "context" "errors" - "github.com/akaspin/supervisor" - "github.com/stretchr/testify/assert" "testing" "time" + + "github.com/akaspin/supervisor" + "github.com/stretchr/testify/assert" ) type component500 struct { diff --git a/trap.go b/trap.go index a175e76..d773470 100644 --- a/trap.go +++ b/trap.go @@ -37,7 +37,7 @@ func (*Trap) Open() (err error) { // Close closes trap func (t *Trap) Close() (err error) { t.cancel() - return + return nil } // Wait returns last accepted error diff --git a/trap_test.go b/trap_test.go index 4216e2c..f3aa65a 100644 --- a/trap_test.go +++ b/trap_test.go @@ -4,10 +4,11 @@ import ( "context" "errors" "fmt" - "github.com/akaspin/supervisor" - "github.com/stretchr/testify/assert" "strconv" "testing" + + "github.com/akaspin/supervisor" + "github.com/stretchr/testify/assert" ) func TestTrap_Wait(t *testing.T) {