From f0a7d374a52927ce889a5c9646f1f40c3eaa8132 Mon Sep 17 00:00:00 2001 From: Khosrow Moossavi Date: Mon, 23 Sep 2019 14:27:11 -0400 Subject: [PATCH] Enhance Makefile and add editorconfig (#115) --- .chglog/CHANGELOG.tpl.md | 10 +- .chglog/config.yml | 18 ++- .circleci/config.yml | 18 ++- .editorconfig | 26 +++++ .golangci.yml | 4 + CONTRIBUTING.md | 1 - Makefile | 184 +++++++++++++++++++++++------- VERSION | 1 - examples/main.tf | 7 +- scripts/build/build-all-osarch.sh | 77 +++++++++++++ scripts/release/release.sh | 69 +++++++++++ 11 files changed, 361 insertions(+), 54 deletions(-) create mode 100644 .editorconfig create mode 100644 .golangci.yml delete mode 100644 VERSION create mode 100755 scripts/build/build-all-osarch.sh create mode 100755 scripts/release/release.sh diff --git a/.chglog/CHANGELOG.tpl.md b/.chglog/CHANGELOG.tpl.md index 3d1b032..62d8f09 100755 --- a/.chglog/CHANGELOG.tpl.md +++ b/.chglog/CHANGELOG.tpl.md @@ -7,12 +7,12 @@ {{ range .Unreleased.CommitGroups -}} ### {{ .Title }} {{ range .Commits -}} -- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} +- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ if .Subject }}{{ .Subject }}{{ else }}{{ .Header }}{{ end }} {{ end }} {{ end -}} {{ else }} {{ range .Unreleased.Commits -}} -- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} +- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ if .Subject }}{{ .Subject }}{{ else }}{{ .Header }}{{ end }} {{ end }} {{ end -}} {{ end -}} @@ -24,12 +24,12 @@ {{ range .CommitGroups -}} ### {{ .Title }} {{ range .Commits -}} -- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} +- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ if .Subject }}{{ .Subject }}{{ else }}{{ .Header }}{{ end }} {{ end }} {{ end -}} {{ else }} {{ range .Commits -}} -- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} +- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ if .Subject }}{{ .Subject }}{{ else }}{{ .Header }}{{ end }} {{ end }} {{ end -}} @@ -50,4 +50,4 @@ [{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }} {{ end -}} {{ end -}} -{{ end -}} \ No newline at end of file +{{ end -}} diff --git a/.chglog/config.yml b/.chglog/config.yml index 6fe150d..ea8ecc0 100755 --- a/.chglog/config.yml +++ b/.chglog/config.yml @@ -4,9 +4,25 @@ info: title: CHANGELOG repository_url: https://github.com/segmentio/terraform-docs options: + commits: + filters: + Type: + - docs + - feat + - fix + - perf + - refactor + commit_groups: + title_maps: + docs: Documentation + feat: Features + fix: Bug Fixes + perf: Performance Improvements + refactor: Code Refactoring header: - pattern: "^(.*)$" + pattern: "^(\\w*)?\\:\\s(.*)$" pattern_maps: + - Type - Subject notes: keywords: diff --git a/.circleci/config.yml b/.circleci/config.yml index 114ed82..158c8e5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,15 +19,21 @@ jobs: steps: - restore_cache: key: repo-{{ .Environment.CIRCLE_SHA1 }} - - run: GO111MODULE=on go mod verify + - run: make verify + + checkfmt: + <<: *defaults + steps: + - restore_cache: + key: repo-{{ .Environment.CIRCLE_SHA1 }} + - run: make goimports checkfmt lint: <<: *defaults steps: - restore_cache: key: repo-{{ .Environment.CIRCLE_SHA1 }} - - run: curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s v1.13 && mv ./bin/* /go/bin/ - - run: make lint + - run: make tools lint test: <<: *defaults @@ -61,6 +67,12 @@ workflows: filters: tags: only: /v.*/ + - checkfmt: + requires: + - checkout_code + filters: + tags: + only: /v.*/ - lint: requires: - checkout_code diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..46dd59f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,26 @@ +# http://editorconfig.org + +# this file is the top-most editorconfig file +root = true + +# all files +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.go] +indent_style = tab +indent_size = 4 + +[json*.golden] +insert_final_newline = false + +[*.{yaml,yml}] +indent_size = 2 + +[Makefile] +indent_style = tab diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..72e1d40 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,4 @@ +run: + deadline: 5m + tests: true + modules-download-mode: vendor diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3459289..77f19b2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,4 +33,3 @@ Pull requests have to meet the following requirements: - [Golang Basics: Writing Unit Tests (Alex Ellis)](https://blog.alexellis.io/golang-writing-unit-tests/) - [Advanced Testing in Go (Mitchell Hashimoto)](https://about.sourcegraph.com/go/advanced-testing-in-go/) - diff --git a/Makefile b/Makefile index 2b06a59..ae4e31c 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ +# Project variables NAME := terraform-docs VENDOR := segmentio DESCRIPTION := Generate docs from Terraform modules @@ -5,55 +6,160 @@ MAINTAINER := Martin Etmajer URL := https://github.com/$(VENDOR)/$(NAME) LICENSE := MIT -VERSION := $(shell cat ./VERSION) +# Repository variables +PACKAGE := github.com/$(VENDOR)/$(NAME) -GOBUILD := go build -ldflags "-X main.version=$(VERSION)" -GOPKGS := $(shell go list ./... | grep -v /vendor) +# Build variables +BUILD_DIR := bin +COMMIT_HASH ?= $(shell git rev-parse --short HEAD 2>/dev/null) +BUILD_DATE ?= $(shell date +%FT%T%z) +VERSION ?= $(shell git describe --tags --exact-match 2>/dev/null || git describe --tags 2>/dev/null || echo "v0.0.0-$(COMMIT_HASH)") +# Go variables +GOCMD := GO111MODULE=on go +GOOS ?= $(shell go env GOOS) +GOARCH ?= $(shell go env GOARCH) +GOFILES ?= $(shell find . -type f -name '*.go' -not -path "./vendor/*") +GOPKGS ?= $(shell $(GOCMD) list $(MODVENDOR) ./... | grep -v /vendor) +MODVENDOR := -mod=vendor + +GOLDFLAGS :=" +GOLDFLAGS += -X $(PACKAGE)/internal/pkg/version.version=$(VERSION) +GOLDFLAGS += -X $(PACKAGE)/internal/pkg/version.commitHash=$(COMMIT_HASH) +GOLDFLAGS += -X $(PACKAGE)/internal/pkg/version.buildDate=$(BUILD_DATE) +GOLDFLAGS +=" + +GOBUILD ?= CGO_ENABLED=0 $(GOCMD) build $(MODVENDOR) -ldflags $(GOLDFLAGS) +GORUN ?= GOOS=$(GOOS) GOARCH=$(GOARCH) $(GOCMD) run $(MODVENDOR) + +# Binary versions +GITCHGLOG_VERSION := 0.8.0 +GOLANGCI_VERSION := v1.17.1 .PHONY: all all: clean deps lint test build -.PHONY: authors -authors: - git log --all --format='%aN <%aE>' | sort -u | egrep -v noreply > AUTHORS - -.PHONY: build -build: authors build-darwin-amd64 build-freebsd-amd64 build-linux-amd64 build-windows-amd64 - -build-darwin-amd64: - GOOS=darwin GOARCH=amd64 $(GOBUILD) -o bin/darwin-amd64/$(NAME) - -build-freebsd-amd64: - GOOS=freebsd GOARCH=amd64 $(GOBUILD) -o bin/freebsd-amd64/$(NAME) - -build-linux-amd64: - GOOS=linux GOARCH=amd64 $(GOBUILD) -o bin/linux-amd64/$(NAME) - -build-windows-amd64: - GOOS=windows GOARCH=amd64 $(GOBUILD) -o bin/windows-amd64/$(NAME).exe +######################### +## Development targets ## +######################### +.PHONY: checkfmt +checkfmt: RESULT = $(shell goimports -l $(GOFILES) | tee >(if [ "$$(wc -l)" = 0 ]; then echo "OK"; fi)) +checkfmt: SHELL := /usr/bin/env bash +checkfmt: ## Check formatting of all go files + @ $(MAKE) --no-print-directory log-$@ + @ echo "$(RESULT)" + @ if [ "$(RESULT)" != "OK" ]; then exit 1; fi .PHONY: clean -clean: - rm -rf ./bin +clean: ## Clean workspace + @ $(MAKE) --no-print-directory log-$@ + rm -rf ./$(BUILD_DIR) -.PHONY: changelog -changelog: - git-chglog -o CHANGELOG.md - -.PHONY: deps -deps: - GO111MODULE=on go mod vendor +.PHONY: fmt +fmt: ## Format all go files + @ $(MAKE) --no-print-directory log-$@ + goimports -w $(GOFILES) .PHONY: lint -lint: - golangci-lint run ./... - -.PHONY: release -release: - git tag -a v$(VERSION) -m v$(VERSION) - git push --tags +lint: ## Run linter + @ $(MAKE) --no-print-directory log-$@ + GO111MODULE=on golangci-lint run ./... .PHONY: test -test: - go test -v $(GOPKGS) +test: ## Run tests + @ $(MAKE) --no-print-directory log-$@ + $(GOCMD) test $(MODVENDOR) -v $(GOPKGS) + +.PHONY: vendor +vendor: ## Install 'vendor' dependencies + @ $(MAKE) --no-print-directory log-$@ + $(GOCMD) mod vendor + +.PHONY: verify +verify: ## Verify 'vendor' dependencies + @ $(MAKE) --no-print-directory log-$@ + $(GOCMD) mod verify + +################### +## Build targets ## +################### +.PHONY: build +build: clean ## Build binary for current OS/ARCH + @ $(MAKE) --no-print-directory log-$@ + $(GOBUILD) -o ./$(BUILD_DIR)/$(GOOS)-$(GOARCH)/$(NAME) + +.PHONY: build-all +build-all: GOOS = linux darwin windows freebsd +build-all: GOARCH = amd64 arm +build-all: clean ## Build binary for all OS/ARCH + @ $(MAKE) --no-print-directory log-$@ + @ ./scripts/build/build-all-osarch.sh "$(BUILD_DIR)" "$(NAME)" "$(VERSION)" "$(GOOS)" "$(GOARCH)" $(GOLDFLAGS) + +##################### +## Release targets ## +##################### +PATTERN = + +.PHONY: release +release: version ?= $(shell echo $(VERSION) | sed 's/^v//' | awk -F'[ .]' '{print $(PATTERN)}') +release: ## Prepare release + @ $(MAKE) --no-print-directory log-$@ + @ ./scripts/release/release.sh "$(version)" "$(VERSION)" "1" + +.PHONY: patch +patch: PATTERN = '\$$1\".\"\$$2\".\"\$$3+1' +patch: release ## Prepare Patch release + +.PHONY: minor +minor: PATTERN = '\$$1\".\"\$$2+1\".0\"' +minor: release ## Prepare Minor release + +.PHONY: major +major: PATTERN = '\$$1+1\".0.0\"' +major: release ## Prepare Major release + +#################### +## Helper targets ## +#################### +.PHONY: authors +authors: ## Generate Authors + git log --all --format='%aN <%aE>' | sort -u | egrep -v noreply > AUTHORS + +.PHONY: changelog +changelog: ## Generate Changelog + git-chglog -o CHANGELOG.md + git add CHANGELOG.md + git commit -m "Update Changelog" + git push origin master + +.PHONY: git-chglog +git-chglog: + curl -sfL https://github.com/git-chglog/git-chglog/releases/download/$(GITCHGLOG_VERSION)/git-chglog_$(shell go env GOOS)_$(shell go env GOARCH) -o $(shell go env GOPATH)/bin/git-chglog && chmod +x $(shell go env GOPATH)/bin/git-chglog + +.PHONY: goimports +goimports: + GO111MODULE=off go get -u golang.org/x/tools/cmd/goimports + +.PHONY: golangci +golangci: + curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(shell go env GOPATH)/bin $(GOLANGCI_VERSION) + +.PHONY: gox +gox: + GO111MODULE=off go get -u github.com/mitchellh/gox + +.PHONY: tools +tools: ## Install required tools + @ $(MAKE) --no-print-directory log-$@ + @ $(MAKE) --no-print-directory git-chglog goimports golangci gox + +######################################################################## +## Self-Documenting Makefile Help ## +## https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html ## +######################################################################## +.PHONY: help +help: + @ grep -h -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' + +log-%: + @ grep -h -E '^$*:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m==> %s\033[0m\n", $$2}' diff --git a/VERSION b/VERSION deleted file mode 100644 index a918a2a..0000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.6.0 diff --git a/examples/main.tf b/examples/main.tf index 5320c3e..6ca23b0 100644 --- a/examples/main.tf +++ b/examples/main.tf @@ -3,12 +3,12 @@ * * module "foo" { * source = "github.com/foo/bar" - * + * * id = "1234567890" * name = "baz" - * + * * zones = ["us-east-1", "us-west-1"] - * + * * tags = { * Name = "baz" * Created-By = "first.last@email.com" @@ -16,4 +16,3 @@ * } * } */ - diff --git a/scripts/build/build-all-osarch.sh b/scripts/build/build-all-osarch.sh new file mode 100755 index 0000000..f0c368a --- /dev/null +++ b/scripts/build/build-all-osarch.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +set -e + +BUILD_DIR="${1:-bin}" +NAME="${2:-terraform-docs}" +VERSION="$3" +GOOS="${4:-"linux darwin windows freebsd"}" +GOARCH="${5:-"amd64 arm"}" +GOLDFLAGS="$6" + +if [ -z "${VERSION}" ]; then + echo "Error: VERSION is missing. e.g. ./compress.sh " + exit 1 +fi +if [ -z "${GOLDFLAGS}" ]; then + echo "Error: GOLDFLAGS is missing. e.g. ./compress.sh " + exit 1 +fi + +PWD=$(cd $(dirname "$0") && pwd -P) +BUILD_DIR="${PWD}/../../${BUILD_DIR}" + +CGO_ENABLED=0 gox \ + -verbose \ + -ldflags "${GOLDFLAGS}" \ + -gcflags=-trimpath=`go env GOPATH` \ + -os="${GOOS}" \ + -arch="${GOARCH}" \ + -osarch="!darwin/arm" \ + -output="${BUILD_DIR}/{{.OS}}-{{.Arch}}/{{.Dir}}" ${PWD}/../../ + +printf "\033[36m==> Compress binary\033[0m\n" + +for platform in $(find ${BUILD_DIR} -mindepth 1 -maxdepth 1 -type d); do + OSARCH=$(basename ${platform}) + FULLNAME="${NAME}-${VERSION}-${OSARCH}" + + case "${OSARCH}" in + "windows"*) + if ! command -v zip >/dev/null; then + echo "Error: cannot compress, 'zip' not found" + exit 1 + fi + + zip -q -j ${BUILD_DIR}/${FULLNAME}.zip ${platform}/${NAME}.exe + printf -- "--> %15s: bin/%s\n" "${OSARCH}" "${FULLNAME}.zip" + + ;; + *) + if ! command -v tar >/dev/null; then + echo "Error: cannot compress, 'tar' not found" + exit 1 + fi + + tar -czf ${BUILD_DIR}/${FULLNAME}.tar.gz --directory ${platform}/ ${NAME} + printf -- "--> %15s: bin/%s\n" "${OSARCH}" "${FULLNAME}.tar.gz" + + ;; + esac +done + +cd ${BUILD_DIR} +touch ${NAME}-${VERSION}.sha256sum + +for binary in $(find . -mindepth 1 -maxdepth 1 -type f | grep -v "${NAME}-${VERSION}.sha256sum" | sort); do + binary=$(basename ${binary}) + + if command -v sha256sum >/dev/null; then + sha256sum ${binary} >>${NAME}-${VERSION}.sha256sum + elif command -v shasum >/dev/null; then + shasum -a256 ${binary} >>${NAME}-${VERSION}.sha256sum + fi +done + +cd - >/dev/null 2>&1 +printf -- "\n--> %15s: bin/%s\n" "sha256sum" "${NAME}-${VERSION}.sha256sum" diff --git a/scripts/release/release.sh b/scripts/release/release.sh new file mode 100755 index 0000000..2b09d9c --- /dev/null +++ b/scripts/release/release.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +set -o errexit +set -o pipefail + +RELEASE_VERSION=$1 +CURRENT_VERSION=$2 +FROM_MAKEFILE=$3 + +if [ -z "${RELEASE_VERSION}" ]; then + if [ -z "${FROM_MAKEFILE}" ]; then + echo "Error: VERSION is missing. e.g. ./release.sh " + else + echo "Error: missing value for 'version'. e.g. 'make release version=x.y.z'" + fi + exit 1 +fi + +if [ -z "${CURRENT_VERSION}" ]; then + CURRENT_VERSION=$(git describe --tags --exact-match 2>/dev/null || git describe --tags 2>/dev/null || echo "v0.0.1-$(COMMIT_HASH)") +fi + +if [ "v${RELEASE_VERSION}" = "${CURRENT_VERSION}" ]; then + echo "Error: provided version (v${version}) exists." + exit 1 +fi + +PWD=$(cd $(dirname "$0") && pwd -P) +CLOSEST_VERSION=$(git describe --tags --abbrev=0) + +# Bump the released version in README and version.go +sed -i -E 's|'${CLOSEST_VERSION}'|v'${RELEASE_VERSION}'|g' README.md +sed -i -E 's|'${CLOSEST_VERSION}'-alpha|v'${RELEASE_VERSION}'|g' cmd/rostamctl/version/version.go + +# Commit changes +printf "\033[36m==> %s\033[0m\n" "Commit changes for release version v${RELEASE_VERSION}" +git add README.md cmd/rostamctl/version/version.go +git commit -m "Release version v${RELEASE_VERSION}" + +printf "\033[36m==> %s\033[0m\n" "Push commits for v${RELEASE_VERSION}" +git push origin master + +# Temporary tag the release to generate the changelog +git tag --annotate --message "v${RELEASE_VERSION} Release" "v${RELEASE_VERSION}" + +# Generate Changelog +make --no-print-directory -f ${PWD}/../../Makefile changelog + +# Delete the temporary tag and create it again to include the just generated changelog +git tag -d "v${RELEASE_VERSION}" + +# Tag the release +printf "\033[36m==> %s\033[0m\n" "Tag release v${RELEASE_VERSION}" +git tag --annotate --message "v${RELEASE_VERSION} Release" "v${RELEASE_VERSION}" + +printf "\033[36m==> %s\033[0m\n" "Push tag release v${RELEASE_VERSION}" +git push origin v${RELEASE_VERSION} + +# Bump the next version in version.go +NEXT_VERSION=$(echo "${RELEASE_VERSION}" | sed 's/^v//' | awk -F'[ .]' '{print $1"."$2+1".0"}') +sed -i -E 's|'${RELEASE_VERSION}'|'${NEXT_VERSION}'-alpha|g' cmd/rostamctl/version/version.go + +# Commit changes +printf "\033[36m==> %s\033[0m\n" "Bump version to ${NEXT_VERSION}-alpha" +git add cmd/rostamctl/version/version.go +git commit -m "Bump version to ${NEXT_VERSION}-alpha" + +printf "\033[36m==> %s\033[0m\n" "Push commits for ${NEXT_VERSION}-alpha" +git push origin master