<commit_before># Concourse Go Style Guide

This document serves to collect some guiding principles and resources to
consider when writing Go code for Concourse.

## Idiomatic Go

Generally the preferred manner of writing Go code follows the style and
conventions present in the [Go project's Standard Library
Packages](https://golang.org/pkg/#stdlib).  The style present in the stdlib
packages is often referred to as "Idiomatic Go", and serves as a consistent set
of conventions for Go programmers to follow in their projects.

In lieu of inventing Concourse's own set of styling rules for Go, below are some
useful resources which capture the sentiment of "Idiomatic Go".

### [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments)
> This page collects common comments made during reviews of Go code, so that a
> single detailed explanation can be referred to by shorthands. This is a 
> laundry list of common mistakes, not a comprehensive style guide.

### [Idiomatic Go](https://dmitri.shuralyov.com/idiomatic-go)
A good resource covering some common styling and pattern issues which deviate
from the idiomatic Go style and best practice. Some great demonstrations of the
importance of consistency and clarity; and where subtle differences matter
greatly

### [Go Proverbs](https://go-proverbs.github.io/)
A list of simple proverbs to consider when writing Go, with links to
[@rob_pike](https://twitter.com/rob_pike)'s talk of the same name.

Some *especially important* ones to keep in mind for Concourse:
- [Gofmt's style is no one's favorite, yet gofmt is everyone's favorite.](https://www.youtube.com/watch?v=PAAkCSZUG1c&t=8m43s)
- [Clear is better than clever.](https://www.youtube.com/watch?v=PAAkCSZUG1c&t=14m35s)
- [Don't just check errors, handle them gracefully.](https://www.youtube.com/watch?v=PAAkCSZUG1c&t=17m25s)
- [Documentation is for users.](https://www.youtube.com/watch?v=PAAkCSZUG1c&t=19m07s)


## Common Concourse Go Gotchas

The Concourse Go codebase is by no means perfect, or reflective of the
standards above, Its often easy to get tripped up, or follow the same pattern
as existing code, leading to some systemic patterns emerging in the code. Below
are some common ones to look out for to avoid, or address when you come across
them.

### A Public Interface For the Sake of a Mockable Interface

Extensive unit tests are present in most packages in the Concourse Go
code, and often [counterfeiter](https://github.com/maxbrunsfeld/counterfeiter) is
employed to auto-generate mocks for interfaces. Having the ability to
cleanly mock out an interface where the implementation(s) has(/have) side effects
is often desirable, but it can occasionally lead to exported interfaces
which serve little utility other than a surface area to mock out for a test.

Its important to consider what each package's public interface is before going
through the motions of making a public interface and a private struct which
implements that interface immediately after in the same `.go` file.

### Naming Packages and Their Contents

Naming anything is hard, but finding a concise name for a package which describes
its purpose is important in Go code. The same goes for the contents of packages -
especially the publicly exported contents available to other parts of the code.<commit_msg>Add suggestions for logging, testing, interfaces<commit_after># Concourse Go Style Guide

This document serves to collect some guiding principles and resources to
consider when writing Go code for Concourse.

## Idiomatic Go

Generally the preferred manner of writing Go code follows the style and
conventions present in the [Go project's Standard Library
Packages](https://golang.org/pkg/#stdlib).  The style present in the stdlib
packages is often referred to as "Idiomatic Go", and serves as a consistent set
of conventions for Go programmers to follow in their projects.

In lieu of inventing Concourse's own set of styling rules for Go, below are some
useful resources which capture the sentiment of "Idiomatic Go".

### [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments)
> This page collects common comments made during reviews of Go code, so that a
> single detailed explanation can be referred to by shorthands. This is a 
> laundry list of common mistakes, not a comprehensive style guide.

### [Idiomatic Go](https://dmitri.shuralyov.com/idiomatic-go)
A good resource covering some common styling and pattern issues which deviate
from the idiomatic Go style and best practice. Some great demonstrations of the
importance of consistency and clarity; and where subtle differences matter
greatly

### [Go Proverbs](https://go-proverbs.github.io/)
A list of simple proverbs to consider when writing Go, with links to
[@rob_pike](https://twitter.com/rob_pike)'s talk of the same name.

Some *especially important* ones to keep in mind for Concourse:
- [Gofmt's style is no one's favorite, yet gofmt is everyone's favorite.](https://www.youtube.com/watch?v=PAAkCSZUG1c&t=8m43s)
- [Clear is better than clever.](https://www.youtube.com/watch?v=PAAkCSZUG1c&t=14m35s)
- [Don't just check errors, handle them gracefully.](https://www.youtube.com/watch?v=PAAkCSZUG1c&t=17m25s)
- [Documentation is for users.](https://www.youtube.com/watch?v=PAAkCSZUG1c&t=19m07s)

## Logging

[Lager](https://github.com/cloudfoundry/lager) is our preferred logging framework for its opinionated structure, JSON
format, and punny name. Lager's log output is best when all of its features are properly leveraged by the component
doing the logging. Here are some things to consider when logging:

### Log Actions Not Messages
Each of [Lager's emission functions](https://github.com/cloudfoundry/lager/blob/1a7fb7de44c33d258236e250189099e48a4c7430/logger.go#L16-L19)'
signature takes a string named "action" as the first argument. It is generally
preferable to treat this value as the (terse) name of the action being
performed in proximity to the log - with words separated by `-` -  rather than
a (more verbose) message.

> eg. `lager.Info("writing-styleguide")` rather than `lager.Info("writing the style guide now")`


### Provide Valuable Data When Emitting Logs
Every new session, and each emission function can have a `lager.Data` provided, which allows arbitrary 
key-value data to be added to each log from the session, or individual log actions respectively.

Be sure to provide any relevant data (especially at the ERROR and DEBUG levels) which might help someone/something
reading those logs discern what happened.

> eg. 
> ```
> logger.Info("writing-styleguide", lager.Data{
> 		"section" : "Logging",
> })
> ```


## Testing

### Unit Test Frameworks

We use [Ginkgo](https://github.com/onsi/ginkgo) to write expressive BDD tests and 
[Gomega](https://github.com/onsi/gomega) for its 
[rich matching library](http://onsi.github.io/gomega/#provided-matchers) and compatibility with Ginkgo.

## Common Concourse Go Gotchas

The Concourse Go codebase is by no means perfect, or reflective of the
standards above, Its often easy to get tripped up, or follow the same pattern
as existing code, leading to some systemic patterns emerging in the code. Below
are some common ones to look out for to avoid, or address when you come across
them.

### A Public Interface For the Sake of a Mockable Interface

Extensive unit tests are present in most packages in the Concourse Go
code, and often [counterfeiter](https://github.com/maxbrunsfeld/counterfeiter) is
employed to auto-generate mocks for interfaces. Mocking out an interface where
the implementation has side effects is often desirable, but it can occasionally
lead to exported interfaces which serve little utility other than a surface
area to mock out for a test.

Its important to consider what each package's public interface is before going
through the motions of making a public interface and a private struct which
implements that interface immediately after in the same `.go` file.


Generally it is preferable to define smaller interfaces where dependencies are
consumed. Interfaces living with implementation leads to direct coupling in
source code, whereas smaller interfaces defined by the consumer encourages
[LSP](https://en.wikipedia.org/wiki/Liskov_substitution_principle) and
[Dependency Inversion](https://en.wikipedia.org/wiki/Dependency_inversion_principle) See:
[<NAME>'s Tweet on the Subject](https://twitter.com/davecheney/status/942593128355192832)

### Naming Packages and Their Contents

Naming anything is hard, but finding a concise name for a package which describes
its purpose is important in Go code. The same goes for the contents of packages -
especially the publicly exported contents available to other parts of the code.
{'fraction_non_alphanumeric': 0.06968243088873657, 'fraction_numerical': 0.010166780900159926, 'mean_word_length': 4.947690217391305, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 17, 'https://': 27, 'lorem ipsum': 0, 'www.': 8, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2980432', 'n_tokens_mistral': 2467, 'n_tokens_neox': 2307, 'n_words': 1136}