diff --git a/makefile b/makefile index e69de29..89ddb0f 100644 --- a/makefile +++ b/makefile @@ -0,0 +1,106 @@ +.PHONY: clean + +GOBIN = build/bin +GO ?= lastest +LINT_FOLDERS := extkeys ./ stats/... +TESTPKG := $(shell go list ./stats/...) + +# This is a code for automatic help generator. +# It supports ANSI colors and categories. +# To add new item into help output, simply add comments +# starting with '##'. To add category, use @category. +GREEN := $(shell tput -Txterm setaf 2) +WHITE := $(shell tput -Txterm setaf 7) +YELLOW := $(shell tput -Txterm setaf 3) +RESET := $(shell tput -Txterm sgr0) +HELP_FUN = \ + %help; \ + while(<>) { push @{$$help{$$2 // 'options'}}, [$$1, $$3] if /^([a-zA-Z\-]+)\s*:.*\#\#(?:@([a-zA-Z\-]+))?\s(.*)$$/ }; \ + print "Usage: make [target]\n\n"; \ + for (sort keys %help) { \ + print "${WHITE}$$_:${RESET}\n"; \ + for (@{$$help{$$_}}) { \ + $$sep = " " x (32 - length $$_->[0]); \ + print " ${YELLOW}$$_->[0]${RESET}$$sep${GREEN}$$_->[1]${RESET}\n"; \ + }; \ + print "\n"; \ + } + +help: ##@tasks Show this help + @perl -e '$(HELP_FUN)' $(MAKEFILE_LIST) + +build: ##@tasks Build msgstat binary into build/bin + go build -o $(GOBIN)/msgstat -v ./ + +ci: lint test-coverage test-units ##@tasks Runs code linting, code coverage and tests for project + +clean: ##@tasks Cleanup + rm -rf build/bin/* + +test-units: + go test $(TESTPKG) + +test-coverage: + go test -coverpkg= $(TESTPKG) + + +lint: lint-vet lint-gofmt lint-deadcode lint-misspell lint-unparam lint-unused lint-gocyclo lint-errcheck lint-ineffassign lint-interfacer lint-unconvert lint-staticcheck lint-goconst lint-gas lint-varcheck lint-structcheck lint-gosimple + +lint-deps: + go get -u github.com/alecthomas/gometalinter + gometalinter --install + +lint-vet: + @echo "lint-vet" + @gometalinter --disable-all --enable=vet --deadline=45s $(LINT_FOLDERS) +lint-golint: + @echo "lint-golint" + @gometalinter --disable-all --enable=golint --deadline=45s $(LINT_FOLDERS) +lint-gofmt: + @echo "lint-gofmt" + @gometalinter --disable-all --enable=gofmt --deadline=45s $(LINT_FOLDERS) +lint-deadcode: + @echo "lint-deadcode" + @gometalinter --disable-all --enable=deadcode --deadline=45s $(LINT_FOLDERS) +lint-misspell: + @echo "lint-misspell" + @gometalinter --disable-all --enable=misspell --deadline=45s $(LINT_FOLDERS) +lint-unparam: + @echo "lint-unparam" + @gometalinter --disable-all --enable=unparam --deadline=45s $(LINT_FOLDERS) +lint-unused: + @echo "lint-unused" + @gometalinter --disable-all --enable=unused --deadline=45s $(LINT_FOLDERS) +lint-gocyclo: + @echo "lint-gocyclo" + @gometalinter --disable-all --enable=gocyclo --cyclo-over=16 --deadline=45s $(LINT_FOLDERS) +lint-errcheck: + @echo "lint-errcheck" + @gometalinter --disable-all --enable=errcheck --deadline=1m $(LINT_FOLDERS) +lint-ineffassign: + @echo "lint-ineffassign" + @gometalinter --disable-all --enable=ineffassign --deadline=45s $(LINT_FOLDERS) +lint-interfacer: + @echo "lint-interfacer" + @gometalinter --disable-all --enable=interfacer --deadline=45s $(LINT_FOLDERS) +lint-unconvert: + @echo "lint-unconvert" + @gometalinter --disable-all --enable=unconvert --deadline=45s $(LINT_FOLDERS) +lint-staticcheck: + @echo "lint-staticcheck" + @gometalinter --disable-all --enable=staticcheck --deadline=45s $(LINT_FOLDERS) +lint-goconst: + @echo "lint-goconst" + @gometalinter --disable-all --enable=goconst --deadline=45s $(LINT_FOLDERS) +lint-gas: + @echo "lint-gas" + @gometalinter --disable-all --enable=gas --deadline=45s $(LINT_FOLDERS) +lint-varcheck: + @echo "lint-varcheck" + @gometalinter --disable-all --enable=varcheck --deadline=45s $(LINT_FOLDERS) +lint-structcheck: + @echo "lint-structcheck" + @gometalinter --disable-all --enable=structcheck --deadline=45s $(LINT_FOLDERS) +lint-gosimple: + @echo "lint-gosimple" + @gometalinter --disable-all --enable=gosimple --deadline=45s $(LINT_FOLDERS) diff --git a/stats/stats.go b/stats/stats.go index 3e80721..ee95ac6 100644 --- a/stats/stats.go +++ b/stats/stats.go @@ -19,7 +19,6 @@ import ( var ( messageHeader = regexp.MustCompile(`INFO \[\d+-\d+\|\d+:\d+:\d+\]\sMessage delivery notification`) - incomingMessage = "IncomingMessage" outgoingMessage = "OutgoingMessage" ) @@ -94,7 +93,7 @@ func ReadAggregates(r io.ReadCloser, w io.WriteCloser, format string) error { // parseLogReader parses out all log messages and returns associated AggregatedMessages // or returns error if encountered. -func parseLogReader(r io.ReadCloser) ([]AggregatedMessage, error) { +func parseLogReader(r io.Reader) ([]AggregatedMessage, error) { var order []string aggregates := make(map[string]AggregatedMessage) diff --git a/stats/stats_test.go b/stats/stats_test.go index 18909a7..635f60c 100644 --- a/stats/stats_test.go +++ b/stats/stats_test.go @@ -15,28 +15,28 @@ import ( func TestAggregationReadToJSON(t *testing.T) { reader, err := os.Open("../fixtures/status.log") if err != nil { - t.Fatalf("Should have succesfully opened log file") + t.Fatalf("Should have successfully opened log file") } - t.Logf("Should have succesfully opened log file") + t.Logf("Should have successfully opened log file") var buf bytes.Buffer if err := stats.ReadAggregates(reader, &writeCloser{&buf}, "json"); err != nil { - t.Fatalf("Should have succesfully processed log data") + t.Fatalf("Should have successfully processed log data") } - t.Logf("Should have succesfully processed log data") + t.Logf("Should have successfully processed log data") expected, err := ioutil.ReadFile("../fixtures/expected.json") if err != nil { - t.Fatalf("Should have succesfully opened expected output file") + t.Fatalf("Should have successfully opened expected output file") } - t.Logf("Should have succesfully opened expected output file") + t.Logf("Should have successfully opened expected output file") if !bytes.Equal(expected, buf.Bytes()) { t.Logf("Expected: %+q\n", expected) t.Logf("Received: %+q\n", buf.Bytes()) - t.Fatalf("Should have succesfully matched aggregated data with expected data") + t.Fatalf("Should have successfully matched aggregated data with expected data") } - t.Logf("Should have succesfully matched aggregated data with expected data") + t.Logf("Should have successfully matched aggregated data with expected data") } // TestAggregationReadToTOML validates the generation of aggregation data into @@ -44,28 +44,28 @@ func TestAggregationReadToJSON(t *testing.T) { func TestAggregationReadToTOML(t *testing.T) { reader, err := os.Open("../fixtures/status.log") if err != nil { - t.Fatalf("Should have succesfully opened log file") + t.Fatalf("Should have successfully opened log file") } - t.Logf("Should have succesfully opened log file") + t.Logf("Should have successfully opened log file") var buf bytes.Buffer if err := stats.ReadAggregates(reader, &writeCloser{&buf}, "toml"); err != nil { - t.Fatalf("Should have succesfully processed log data") + t.Fatalf("Should have successfully processed log data") } - t.Logf("Should have succesfully processed log data") + t.Logf("Should have successfully processed log data") expected, err := ioutil.ReadFile("../fixtures/expected.toml") if err != nil { - t.Fatalf("Should have succesfully opened expected output file") + t.Fatalf("Should have successfully opened expected output file") } - t.Logf("Should have succesfully opened expected output file") + t.Logf("Should have successfully opened expected output file") if !bytes.Equal(expected, buf.Bytes()) { t.Logf("Expected: %+q\n", expected) t.Logf("Received: %+q\n", buf.Bytes()) - t.Fatalf("Should have succesfully matched aggregated data with expected data") + t.Fatalf("Should have successfully matched aggregated data with expected data") } - t.Logf("Should have succesfully matched aggregated data with expected data") + t.Logf("Should have successfully matched aggregated data with expected data") } // TestAggregationReadToYAML validates the generation of aggregation data into @@ -73,28 +73,28 @@ func TestAggregationReadToTOML(t *testing.T) { func TestAggregationReadToYAML(t *testing.T) { reader, err := os.Open("../fixtures/status.log") if err != nil { - t.Fatalf("Should have succesfully opened log file") + t.Fatalf("Should have successfully opened log file") } - t.Logf("Should have succesfully opened log file") + t.Logf("Should have successfully opened log file") var buf bytes.Buffer if err := stats.ReadAggregates(reader, &writeCloser{&buf}, "yaml"); err != nil { - t.Fatalf("Should have succesfully processed log data") + t.Fatalf("Should have successfully processed log data") } - t.Logf("Should have succesfully processed log data") + t.Logf("Should have successfully processed log data") expected, err := ioutil.ReadFile("../fixtures/expected.yaml") if err != nil { - t.Fatalf("Should have succesfully opened expected output file") + t.Fatalf("Should have successfully opened expected output file") } - t.Logf("Should have succesfully opened expected output file") + t.Logf("Should have successfully opened expected output file") if !bytes.Equal(expected, buf.Bytes()) { t.Logf("Expected: %+q\n", expected) t.Logf("Received: %+q\n", buf.Bytes()) - t.Fatalf("Should have succesfully matched aggregated data with expected data") + t.Fatalf("Should have successfully matched aggregated data with expected data") } - t.Logf("Should have succesfully matched aggregated data with expected data") + t.Logf("Should have successfully matched aggregated data with expected data") } // writeCloser provides a decorator which adds a `Close` method to a composed io.Writer. diff --git a/travis.yml b/travis.yml new file mode 100644 index 0000000..f075470 --- /dev/null +++ b/travis.yml @@ -0,0 +1,26 @@ +notifications: + email: false + +language: go + +go: + - 1.9 + - 1.8 + - 1.7 + +sudo: false + +dist: trust + +install: + - go get golang.org/x/tools/cmd/cover + - make lint-deps + +jobs: + include: + - stage: Code Lint + script: make lint + - stage: Code Coverage + script: make test-coverage + - stage: Code Test + script: make test-units