📙
LDS Guidelines
  • Home
  • How to contribute
  • Presentation Guidelines
  • Development management guidelines
  • Application development guidelines
  • Languages & Tools
    • Golang
    • Git
Powered by GitBook
On this page
  • Coding guidelines
  • General style
  • Variables, functions, packages and modules
  • Errors and log
  • Testing
  • Versioning
  • Useful tools
  • References

Was this helpful?

  1. Languages & Tools

Golang

This section contains development guidelines about writing code in Go.

PreviousApplication development guidelinesNextGit

Last updated 4 years ago

Was this helpful?

Coding guidelines

General style

A1. Go projects should follow the . To this end you may use the .

A2. Code should be formatted according to the rules of and . Example or a working Make target used in several projects, that allows to format a Go module:

test_fmt:
	@echo Checking correct formatting of files
	@{ \
		files=$$( go fmt ./... ); \
		if [ -n "$$files" ]; then \
		echo "Files not properly formatted: $$files"; \
		exit 1; \
		fi; \
		if ! go vet ./...; then \
		exit 1; \
		fi \
	}

A3. Code should adhere to the rules. Example of a working Make target used in several projects, that allows to check a Go module linting:

test_lint:
	@echo Checking linting of files
	@{ \
		GO111MODULE=off go get -u golang.org/x/lint/golint; \
		el=$(EXCLUDE_LINT); \
		lintfiles=$$( golint ./... | egrep -v "$$el" ); \
		if [ -n "$$lintfiles" ]; then \
		echo "Lint errors:"; \
		echo "$$lintfiles"; \
		exit 1; \
		fi \
	}

A4. To set up local variables in if and switch control structures, you should use whenever applicable the initialisation statement construct.

if err := file.Chmod(0664); err != nil {
    log.Print(err)
    return err
}

A5. To loop over an array, slice, string or map, or reading from a channel, you should use the range clause.

for key, value := range oldMap {
    newMap[key] = value
}

A6. To generate cryptographic keys, you must not use math/rand. Use crypto/rand's Reader instead, and print to hexadecimal or base64 if you need text. crypto/rand should always be used, even in tests or in contexts that does not have high security requirements, to avoid the introduction of vulnerabilities in later development stages stemming from incautious copy-paste operations.

import (
	"crypto/rand"
	// "encoding/base64"
	// "encoding/hex"
	"fmt"
)

func Key() string {
	buf := make([]byte, 16)
	_, err := rand.Read(buf)
	if err != nil {
		panic(err)  // out of randomness, should never happen
	}
	return fmt.Sprintf("%x", buf)
	// or hex.EncodeToString(buf)
	// or base64.StdEncoding.EncodeToString(buf)
}

A7. When declaring an empty slice, prefer this notation:

var t []string

Variables, functions, packages and modules

B1. MixedCaps should be used to write multiword names.

B2. Words in names that are initialisms or acronyms (e.g. "URL" or "NATO") should have a consistent case. For example, "URL" should appear as "URL" or "url" (as in "urlPony", or "URLPony"), never as "Url". This rule also applies to "ID" when it is short for "identifier", so you should write "appID" instead of "appId".

B3. Named result parameters should be used only in short functions.

B4. The defer statement should be used to release resources used by functions (e.g. I/O operations).

B5. Security credentials, tracing information, deadlines, and cancellation signals should be passed across functions as values of the context.Context type.

B6. Functions using a Context should accept it as first parameter.

B7. A function that is never request-specific may use context.Background() instead of Context.

B8. Functions should always return an error or boolean to indicate whether its other return values are valid or not, and not rely on special or magic return values to indicate error.

B9. Packages should have single-word names, and they must match the base name of their source directory.

As an example, the package insrc/encoding/base64 should have name base64(and be imported asencoding/base64).

Errors and log

C1. Functions should always return an error or boolean to indicate wether its other return values are valid or not, and not rely on special or magic return values to indicate error. For severe errors which cause the application to crash, the panic function may be used instead.

C2. The panic function should be used with caution and not for normal error handling. If used, it should be properly documented so that it has the chance to be caught.

C3. The log.Fatal function should not be used.

C4. Error and log strings should not be capitalised nor end with punctuation.

Testing

D2. If your tests depend on external components (e.g. a database, network, etc.), the calls to these dependencies should be properly separated from the main code by an interface, and the interfaces mocked to simulate the external component during tests.

D3. The tests should be easily executable and automated. Example or a working Make target used in several projects, that allows to execute tests:

test_local:
	go test -v -race -short -p=1 ./...

Versioning

Useful tools

References

B10. Modules should be defined by using .

D1. Testing of Go projects should be implemented by using the provided by the Go's standard library, and run by using the . Note that you must implement your tests in a file whose name ends in _test.go, and you must put it in the same package of the file it tests (not in a separate xxx_test package).

E1. Go modules must comply to in order to be importable. Note that this is particularly important for versions >= v2, as this requires changes in the go.mod and source files (see point E2).

E2. Before releasing a new version, follow the guide on .

Mocking frameworks that may be used for Go projects are and .

A TOML parser that may be used in Go applications is .

A lexer/parser that may be used to make more robust the parsing of the CLI arguments of Go applications is .

Packages that may be used to perform logging in Go applications are , and, for distributed applications, .

Standard Go Project Layout
Go Project Template
go fmt
go vet
golint
go.mod
built-in testing package
test command
Semantic Import Versioning
how to prepare new releases
gomock
pegomock
go-toml
goyacc
log
logrus
trace
https://golang.org/doc/effective_go.html
https://github.com/golang/go/wiki/CodeReviewComments
https://dave.cheney.net/practical-go/presentations/qcon-china.html
https://go-proverbs.github.io/