Let's Go Further Building, Versioning and Quality Control › Quality Controlling Code
Previous · Contents · Next
Chapter 19.3.

Quality Controlling Code

In this chapter we’re going to add new audit and tidy rules to our Makefile to check, test and tidy up our codebase automatically. It’s useful to have rules like these that you can routinely run before you commit changes into your version control system or build any binaries.

The audit rule won’t make any changes to our codebase, but will simply report any problems. In particular it will:

In contrast, the tidy rule will actually make changes to the codebase. It will:

If you’re following along, you’ll need to install the staticcheck tool on your machine at this point. The simplest way to do this is by running the go install command like so:

$ go install honnef.co/go/tools/cmd/staticcheck@latest
go: downloading honnef.co/go/tools v0.1.3
go: downloading golang.org/x/tools v0.1.0
go: downloading github.com/BurntSushi/toml v0.3.1
go: downloading golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4
go: downloading golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
go: downloading golang.org/x/mod v0.6.0
$ which staticcheck
/home/alex/go/bin/staticcheck

Once that’s installed, let’s go ahead and add the new tidy and audit rules to our makefile. While we’re at it, let’s also add some comment blocks to help organize and clarify the purpose of our different makefile rules, like so:

File: Makefile
include .envrc

# ==================================================================================== #
# HELPERS
# ==================================================================================== #

## help: print this help message
.PHONY: help
help:
	@echo 'Usage:'
	@sed -n 's/^##//p' ${MAKEFILE_LIST} | column -t -s ':' |  sed -e 's/^/ /'

.PHONY: confirm
confirm:
	@echo -n 'Are you sure? [y/N] ' && read ans && [ $${ans:-N} = y ]

# ==================================================================================== #
# DEVELOPMENT
# ==================================================================================== #

## run/api: run the cmd/api application
.PHONY: run/api
run/api:
	go run ./cmd/api -db-dsn=${GREENLIGHT_DB_DSN}

## db/psql: connect to the database using psql
.PHONY: db/psql
db/psql:
	psql ${GREENLIGHT_DB_DSN}

## db/migrations/new name=$1: create a new database migration
.PHONY: db/migrations/new
db/migrations/new:
	@echo 'Creating migration files for ${name}...'
	migrate create -seq -ext=.sql -dir=./migrations ${name}

## db/migrations/up: apply all up database migrations
.PHONY: db/migrations/up
db/migrations/up: confirm
	@echo 'Running up migrations...'
	migrate -path ./migrations -database ${GREENLIGHT_DB_DSN} up

# ==================================================================================== #
# QUALITY CONTROL
# ==================================================================================== #

## tidy: format all .go files and tidy module dependencies
.PHONY: tidy
tidy:
	@echo 'Formatting .go files...'
	go fmt ./...
	@echo 'Tidying module dependencies...'
	go mod tidy

## audit: run quality control checks
.PHONY: audit
audit:
	@echo 'Checking module dependencies'
	go mod tidy -diff
	go mod verify
	@echo 'Vetting code...'
	go vet ./...
	staticcheck ./...
	@echo 'Running tests...'
	go test -race -vet=off ./...

Now that’s done, all you need to do is type make tidy and make audit to execute these checks. Let’s give it a try.

If you’ve been following along closely, the output should look very similar to this:

$ make tidy
Formatting .go files...
go fmt ./...
Tidying module dependencies...
go mod tidy
go: finding module for package gopkg.in/mail.v2
go: downloading gopkg.in/mail.v2 v2.3.1
go: found gopkg.in/mail.v2 in gopkg.in/mail.v2 v2.3.1

$ make audit
Checking module dependencies
go mod tidy -diff
go mod verify
all modules verified
Vetting code...
go vet ./...
staticcheck ./...
Running tests...
go test -race -vet=off ./...
?       greenlight.alexedwards.net/cmd/api      [no test files]
?       greenlight.alexedwards.net/cmd/examples/cors/preflight  [no test files]
?       greenlight.alexedwards.net/cmd/examples/cors/simple     [no test files]
?       greenlight.alexedwards.net/internal/data        [no test files]
?       greenlight.alexedwards.net/internal/jsonlog     [no test files]
?       greenlight.alexedwards.net/internal/mailer      [no test files]
?       greenlight.alexedwards.net/internal/validator   [no test files]

That’s looking good. The make tidy command resulted in some additional packages needing to be downloaded, but apart from that, all the checks completed successfully without any problems.


Additional Information

Testing

We covered the topic of testing in a lot of detail in the first Let’s Go book, and the same principles apply again here. If you like, feel free to revisit the testing section of Let’s Go and re-implement some of those same patterns in your API. For example, you might like to try: