Go Code Reviews
Style Guide
Developers should follow the Effective Go Style Guide.
Code Analysis / Linting
Project Setup
Below is the project setup that you would like to have in your VS Code.
vscode-go extension
Using the Go extension for Visual Studio Code, you get language features like IntelliSense, code navigation, symbol search, bracket matching, snippets, etc. This extension includes rich language support for go in VS Code.
go vet
go vet
is a static analysis tool that checks for common go errors, such as incorrect use of range loop variables or misaligned printf arguments. Go code should be able to build with no go vet
errors. This will be part of vscode-go extension.
golint
:exclamation: NOTICE: The golint library is deprecated and archived.
The linter revive (below) might be a suitable replacement.
golint can be an effective tool for finding many issues, but it errors on the side of false positives. It is best used by developers when working on code, not as part of an automated build process. This is the default linter which is set up as part of the vscode-go extension.
revive
Revive is a linter for go, it provides a framework for development of custom rules, and lets you define a strict preset for enhancing your development & code review processes.
Automatic Code Formatting
gofmt
gofmt
is the automated code format style guide for Go. This is part of the vs-code extension, and it is enabled by default to run on save of every file.
Aggregator
golangci-lint
golangci-lint is the replacement for the now deprecated gometalinter
. It is 2-7x faster than gometalinter
along with a host of other benefits.
golangci-lint is a powerful, customizable aggregator of linters. By default, several are enabled but not all. A full list of linters and their usages can be found here.
It will allow you to configure each linter and choose which ones you would like to enable in your project.
One awesome feature of golangci-lint
is that is can be easily introduced to an existing large codebase using the --new-from-rev COMMITID
. With this setting only newly introduced issues are flagged, allowing a team to improve new code without having to fix all historic issues in a large codebase. This provides a great path to improving code-reviews on existing solutions. golangci-lint can also be setup as the default linter in VS Code.
Installation options for golangci-lint are present at golangci-lint.
To use golangci-lint with VS Code, use the below recommended settings:
Pre-Commit Hooks
All developers should run gofmt
in a pre-commit hook to ensure standard formatting.
Step 1- Install pre-commit
Run pip install pre-commit
to install pre-commit.
Alternatively you can run brew install pre-commit
if you are using homebrew.
Step 2- Add go-fmt in pre-commit
Add .pre-commit-config.yaml file to root of the go project. Run go-fmt on pre-commit by adding it to .pre-commit-config.yaml file like below.
Step 3
Run $ pre-commit install
to set up the git hook scripts
Build Validation
gofmt
should be run as a part of every build to enforce the common standard.
To automate this process in Azure DevOps you can add the following snippet to your azure-pipelines.yaml
file. This will format any scripts in the ./scripts/
folder.
- script: go fmt
workingDirectory: $(System.DefaultWorkingDirectory)/scripts
displayName: "Run code formatting"
govet
should be run as a part of every build to check code linting.
To automate this process in Azure DevOps you can add the following snippet to your azure-pipelines.yaml
file. This will check linting of any scripts in the ./scripts/
folder.
- script: go vet
workingDirectory: $(System.DefaultWorkingDirectory)/scripts
displayName: "Run code linting"
Alternatively you can use golangci-lint as a step in the pipeline to do multiple enabled validations(including go vet and go fmt) of golangci-lint.
- script: golangci-lint run --enable gofmt --fix
workingDirectory: $(System.DefaultWorkingDirectory)/scripts
displayName: "Run code linting"
Sample Build Validation Pipeline in Azure DevOps
trigger: master
pool:
vmImage: 'ubuntu-latest'
steps:
- task: GoTool@0
inputs:
version: '1.13.5'
- task: Go@0
inputs:
command: 'get'
arguments: '-d'
workingDirectory: '$(System.DefaultWorkingDirectory)/scripts'
- script: go fmt
workingDirectory: $(System.DefaultWorkingDirectory)/scripts
displayName: "Run code formatting"
- script: go vet
workingDirectory: $(System.DefaultWorkingDirectory)/scripts
displayName: 'Run go vet'
- task: Go@0
inputs:
command: 'build'
workingDirectory: '$(System.DefaultWorkingDirectory)'
- task: CopyFiles@2
inputs:
TargetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts@1
inputs:
artifactName: drop
Code Review Checklist
The Go language team maintains a list of common Code Review Comments for go that form the basis for a solid checklist for a team working in Go that should be followed in addition to the Code Review Checklist
- Does this code handle errors correctly? This includes not throwing away errors with
_
assignments and returning errors, instead of in-band error values? - Does this code follow Go standards for method receiver types?
- Does this code pass values when it should?
- Are interfaces in this code defined in the correct packages?
- Do go-routines in this code have clear lifetimes?
- Is parallelism in this code handled via go-routines and channels with synchronous methods?
- Does this code have meaningful Doc Comments?
- Does this code have meaningful Package Comments?
- Does this code use Contexts correctly?
- Do unit tests fail with meaningful messages?