Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
c9b887c
Clarify guidance for grouping consecutive variable declarations (#140)
mway Jan 18, 2022
c1c8fca
Add note about parallel test table variables (#144)
mway Mar 15, 2022
6bc36c4
Guidance: Use field tags in marshaled structs (#148)
beebeeep Mar 30, 2022
a5830ae
Add link to French translation (#149)
rm3l Apr 18, 2022
6e7643e
remove: redundant sentence (#150)
shirakiyo May 6, 2022
eb520d6
Don't use deprecated methods from ioutil (#151)
kwarabei Jun 21, 2022
736056e
Add a note on Go versions (#152)
sywhang Jun 21, 2022
8445ac6
README: add zh_tw translation (#153)
ianchen0119 Aug 15, 2022
c675ab1
add Turkish language translation link (#156)
ksckaan1 Oct 3, 2022
7e4a675
README: Add Ukrainian translation (#157)
vorobeyme Oct 17, 2022
4478e67
Add guidance on goroutine lifecycle management (#158)
abhinav Oct 19, 2022
621006f
Update .golangci.yml (#160)
faustind Oct 22, 2022
c2f48e2
fix typo (#161)
cuishuang Nov 10, 2022
e0b30ca
Fix typo (#162)
hpurmann Nov 24, 2022
f66d881
style: Lint with markdownlint (#164)
pan93412 Feb 1, 2023
9242f02
style.md: Split into separate files (#168)
abhinav Mar 2, 2023
24fa057
style.md: Add warning that the file is generated (#169)
abhinav Mar 3, 2023
ac884fe
interface-receiver: Clarify why value receiver can be called (#170)
abhinav Mar 3, 2023
f94e5ea
make: Fix lint target (#172)
abhinav Mar 5, 2023
cb642aa
Fix link to empty slices (#171)
cgrinds Mar 5, 2023
819516a
Bump actions/setup-go from 3 to 4 (#175)
dependabot[bot] Mar 20, 2023
a61a8f5
make: Fix stitchmd path (#176)
mway Mar 22, 2023
88c42cf
Bump go.abhg.dev/stitchmd from 0.4.0 to 0.5.0 in /tools (#177)
dependabot[bot] Mar 27, 2023
42f94b6
Handle errors once (#179)
abhinav Apr 13, 2023
0bfd9f1
ci/stitchmd: Don't build from source, use action (#180)
abhinav Apr 25, 2023
d3ca5c2
ci/stitchmd: Support updating PRs from forks (#181)
abhinav May 9, 2023
a325647
ci/stitchmd: Fix write mode for PRs (#182)
abhinav May 9, 2023
bd5d08e
ci/stitchmd: Run git-auto-commit-action on pull_request_target (#183)
abhinav May 9, 2023
e0d2d1a
table tests: make guidance less prescriptive (#174)
tyler-french May 9, 2023
301dcaa
fix(test-table): reduce width and replace tabs (#184)
tyler-french May 9, 2023
7f06a53
exit-once: Clarify that `run()` ins't prescriptive (#190)
abhinav Jul 26, 2023
0b272b3
Bump actions/checkout from 3 to 4 (#191)
dependabot[bot] Sep 12, 2023
b5e3642
README: Add Persian translation (#196)
jamalkaksouri Sep 22, 2023
55fc8cf
Bump stefanzweifel/git-auto-commit-action from 4 to 5 (#199)
dependabot[bot] Oct 9, 2023
09114fa
Fix header for string-byte-slice (#202)
alex-semenyuk Nov 28, 2023
274463a
Add link to PT-BR translation (#205)
alcir-junior-caju Jan 21, 2024
6faf782
chore: Update external Go links (#207)
vorobeyme Jan 24, 2024
27820cf
feat: [Vietnamese version] (#212)
nc-minh May 28, 2024
a66b53b
give guidance to reduce scope of constants (#217)
tyler-french Aug 9, 2024
62b6af7
Update BAD Example in `import-alias.md` (#220)
martinyonatann Nov 17, 2024
efdc911
docs(README): add Arabic translation link to the list of community tr…
anqorithm Mar 1, 2025
9731441
docs(README): add Indonesian translation to the translation link list…
stanleydv12 May 27, 2025
66c785a
Update WaitGroup example
jhn Oct 23, 2025
01b1501
Auto-update style.md
jhn Oct 23, 2025
0b48aed
Update src/goroutine-exit.md
moisesvega Oct 23, 2025
c6dc055
Update style.md
moisesvega Oct 23, 2025
fbb4a88
Merge pull request #236 from jhn/master
moisesvega Oct 23, 2025
0a69c1d
Remove redundant variable assignment in tests (go 1.22) (#254)
jjpinto Dec 27, 2025
860b988
Replace golint with revive in linting guidelines (#253)
jjpinto Dec 27, 2025
2e1f9a9
Change map type to use proper comparison (#247)
jjpinto Dec 27, 2025
652a83f
no go func in init: NewWorker missing return w (#246)
jjpinto Dec 27, 2025
3195313
Fix typo in goroutine-forget.md (#245)
jjpinto Dec 27, 2025
6a51cda
Fix grammar in error-once.md (#244)
jjpinto Dec 27, 2025
e2c8a0e
Removed extra word in test-table.md (#255)
jjpinto Dec 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/tools"
schedule:
interval: "daily"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
48 changes: 48 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: CI

on:
push:
branches: [ main ]
pull_request_target:
branches: [ '*' ]

jobs:
stitchmd:
name: Check or update style.md
runs-on: ubuntu-latest

# Needed to give the job permission
# to push to branches.
permissions:
contents: write

steps:
- name: Check out repository
uses: actions/checkout@v4
with:
# Check out the pull request repository and branch.
# If the PR is made from a fork, this will check out the fork.
# This is necessary for git-auto-commit-action to update PRs made by forks.
# See
# https://github.com/stefanzweifel/git-auto-commit-action#use-in-forks-from-public-repositories
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.head_ref }}

- name: Check or update style.md
uses: abhinav/stitchmd-action@v1
with:
# For pull requests, run in 'write' mode so that edits made
# directly in the GitHub UI get propagated to style.md
# without a local checkout.
#
# Otherwise, run in 'check' mode to fail CI if style.md is out-of-date.
mode: ${{ github.event_name == 'pull_request_target' && 'write' || 'check' }}
summary: src/SUMMARY.md
preface: src/preface.txt
output: style.md

- uses: stefanzweifel/git-auto-commit-action@v5
if: ${{ github.event_name == 'pull_request_target' }}
with:
file_pattern: style.md
commit_message: 'Auto-update style.md'
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/bin
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Refer to golangci-lint's example config file for more options and information:
# https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml
# https://github.com/golangci/golangci-lint/blob/master/.golangci.reference.yml

run:
timeout: 5m
Expand Down
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
# 2023-05-09

- Test tables: Discourage tables with complex, branching test bodies.

# 2023-04-13

- Errors: Add guidance on handling errors only once.

# 2023-03-03

- Receivers and Interfaces: Clarify subtlety with pointer receivers and values.

# 2022-10-18

- Add guidance on managing goroutine lifecycles.

# 2022-03-30

- Add guidance on using field tags in marshaled structs.

# 2021-11-16

- Add guidance on use of `%w` vs `%v` with `fmt.Errorf`, and where to use
Expand Down
74 changes: 74 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Contributing

Before making any changes,
please discuss your plans on GitHub
and get agreement on the general direction of the change.

## Making changes

- style.md is generated from the contents of the src/ folder.
All changes must be made to files in the src/ folder.
- For new entries, create a new file with a short name
(see [File names](#file-names)) and add it to [SUMMARY.md](src/SUMMARY.md).
The file must have a single level 1 heading and any number of subsections.
- Use tables for side-by-side code samples.
- Link to other sections with their file names (`[..](foo.md)`).

## Writing style

### Line breaks

Use [semantic line breaks](https://sembr.org/) in your writing.
This keeps the Markdown files easily reviewable and editable.

### File names

Files in src/ follow a rough naming convention of:

{subject}-{desc}.md

Where `{subject}` is the **singular form** of subject that the entry is about
(e.g `string`, `struct`, `time`, `var`, `error`)
and `{desc}` is a short one or two word description of the topic.
For subjects where their name is enough, the `-{desc}` may be omitted.

### Code samples

Use two spaces to indent code samples.
Horizontal space is limited in side-by-side samples.

### Side-by-side samples

Create side-by-side code samples with the following template:

~~~
<table>
<thead><tr><th>Bad</th><th>Good</th></tr></thead>
<tbody>
<tr><td>

```go
BAD CODE GOES HERE
```

</td><td>

```go
GOOD CODE GOES HERE
```

</td></tr>
</tbody></table>
~~~

The empty lines between the HTML tags and code samples are necessary.

If you need to add labels or descriptions below the code samples,
add another row before the `</tbody></table>` line.

~~~
<tr>
<td>DESCRIBE BAD CODE</td>
<td>DESCRIBE GOOD CODE</td>
</tr>
~~~
27 changes: 27 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
SHELL = /bin/bash

# Setting GOBIN makes 'go install' put the binary in the bin/ directory.
export GOBIN ?= $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/bin

STITCHMD = $(GOBIN)/stitchmd

# Keep these options in-sync with .github/workflows/ci.yml.
STITCHMD_ARGS = -o style.md -preface src/preface.txt src/SUMMARY.md

.PHONY: all
all: style.md

.PHONY: lint
lint: $(STITCHMD)
@DIFF=$$($(STITCHMD) -d $(STITCHMD_ARGS)); \
if [[ -n "$$DIFF" ]]; then \
echo "style.md is out of date:"; \
echo "$$DIFF"; \
false; \
fi

style.md: $(STITCHMD) $(wildcard src/*)
$(STITCHMD) $(STITCHMD_ARGS)

$(STITCHMD):
go install go.abhg.dev/stitchmd@latest
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,21 @@ See [Uber Go Style Guide](style.md) for the style guide.
We are aware of the following translations of this guide by the Go community.

- **中文翻译** (Chinese): [xxjwxc/uber_go_guide_cn](https://github.com/xxjwxc/uber_go_guide_cn)
- **繁體中文** (Traditional Chinese):[ianchen0119/uber_go_guide_tw](https://github.com/ianchen0119/uber_go_guide_tw)
- **한국어 번역** (Korean): [TangoEnSkai/uber-go-style-guide-kr](https://github.com/TangoEnSkai/uber-go-style-guide-kr)
- **日本語訳** (Japanese): [knsh14/uber-style-guide-ja](https://github.com/knsh14/uber-style-guide-ja)
- **Traducción al Español** (Spanish): [friendsofgo/uber-go-guide-es](https://github.com/friendsofgo/uber-go-guide-es)
- **แปลภาษาไทย** (Thai): [pallat/uber-go-style-guide-th](https://github.com/pallat/uber-go-style-guide-th)
- **Tradução em português** (Portuguese): [lucassscaravelli/uber-go-guide-pt](https://github.com/lucassscaravelli/uber-go-guide-pt)
- **Tradução em português** (Portuguese BR): [alcir-junior-caju/uber-go-style-guide-pt-br](https://github.com/alcir-junior-caju/uber-go-style-guide-pt-br)
- **Tłumaczenie polskie** (Polish): [DamianSkrzypczak/uber-go-guide-pl](https://github.com/DamianSkrzypczak/uber-go-guide-pl)
- **Русский перевод** (Russian): [sau00/uber-go-guide-ru](https://github.com/sau00/uber-go-guide-ru)
- **Français** (French): [rm3l/uber-go-style-guide-fr](https://github.com/rm3l/uber-go-style-guide-fr)
- **Türkçe** (Turkish): [ksckaan1/uber-go-style-guide-tr](https://github.com/ksckaan1/uber-go-style-guide-tr)
- **Український переклад** (Ukrainian): [vorobeyme/uber-go-style-guide-uk](https://github.com/vorobeyme/uber-go-style-guide-uk)
- **ترجمه فارسی** (Persian): [jamalkaksouri/uber-go-guide-ir](https://github.com/jamalkaksouri/uber-go-guide-ir)
- **Tiếng việt** (Vietnamese): [nc-minh/uber-go-guide-vi](https://github.com/nc-minh/uber-go-guide-vi)
- **العربية** (Arabic): [anqorithm/uber-go-guide-ar](https://github.com/anqorithm/uber-go-guide-ar)
- **Bahasa Indonesia** (Indonesian): [stanleydv12/uber-go-guide-id](https://github.com/stanleydv12/uber-go-guide-id)

If you have a translation, feel free to submit a PR adding it to the list.
2 changes: 2 additions & 0 deletions src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The contents of this directory are used to generate the top-level style.md.
The layout is controlled by SUMMARY.md.
66 changes: 66 additions & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Uber Go Style Guide

- [Introduction](intro.md)
- Guidelines
- [Pointers to Interfaces](interface-pointer.md)
- [Verify Interface Compliance](interface-compliance.md)
- [Receivers and Interfaces](interface-receiver.md)
- [Zero-value Mutexes are Valid](mutex-zero-value.md)
- [Copy Slices and Maps at Boundaries](container-copy.md)
- [Defer to Clean Up](defer-clean.md)
- [Channel Size is One or None](channel-size.md)
- [Start Enums at One](enum-start.md)
- [Use `"time"` to handle time](time.md)
- Errors
- [Error Types](error-type.md)
- [Error Wrapping](error-wrap.md)
- [Error Naming](error-name.md)
- [Handle Errors Once](error-once.md)
- [Handle Type Assertion Failures](type-assert.md)
- [Don't Panic](panic.md)
- [Use go.uber.org/atomic](atomic.md)
- [Avoid Mutable Globals](global-mut.md)
- [Avoid Embedding Types in Public Structs](embed-public.md)
- [Avoid Using Built-In Names](builtin-name.md)
- [Avoid `init()`](init.md)
- [Exit in Main](exit-main.md)
- [Exit Once](exit-once.md)
- [Use field tags in marshaled structs](struct-tag.md)
- [Don't fire-and-forget goroutines](goroutine-forget.md)
- [Wait for goroutines to exit](goroutine-exit.md)
- [No goroutines in `init()`](goroutine-init.md)
- [Performance](performance.md)
- [Prefer strconv over fmt](strconv.md)
- [Avoid repeated string-to-byte conversions](string-byte-slice.md)
- [Prefer Specifying Container Capacity](container-capacity.md)
- Style
- [Avoid overly long lines](line-length.md)
- [Be Consistent](consistency.md)
- [Group Similar Declarations](decl-group.md)
- [Import Group Ordering](import-group.md)
- [Package Names](package-name.md)
- [Function Names](function-name.md)
- [Import Aliasing](import-alias.md)
- [Function Grouping and Ordering](function-order.md)
- [Reduce Nesting](nest-less.md)
- [Unnecessary Else](else-unnecessary.md)
- [Top-level Variable Declarations](global-decl.md)
- [Prefix Unexported Globals with _](global-name.md)
- [Embedding in Structs](struct-embed.md)
- [Local Variable Declarations](var-decl.md)
- [nil is a valid slice](slice-nil.md)
- [Reduce Scope of Variables](var-scope.md)
- [Avoid Naked Parameters](param-naked.md)
- [Use Raw String Literals to Avoid Escaping](string-escape.md)
- Initializing Structs
- [Use Field Names to Initialize Structs](struct-field-key.md)
- [Omit Zero Value Fields in Structs](struct-field-zero.md)
- [Use `var` for Zero Value Structs](struct-zero.md)
- [Initializing Struct References](struct-pointer.md)
- [Initializing Maps](map-init.md)
- [Format Strings outside Printf](printf-const.md)
- [Naming Printf-style Functions](printf-name.md)
- Patterns
- [Test Tables](test-table.md)
- [Functional Options](functional-option.md)
- [Linting](lint.md)
57 changes: 57 additions & 0 deletions src/atomic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Use go.uber.org/atomic

Atomic operations with the [sync/atomic] package operate on the raw types
(`int32`, `int64`, etc.) so it is easy to forget to use the atomic operation to
read or modify the variables.

[go.uber.org/atomic] adds type safety to these operations by hiding the
underlying type. Additionally, it includes a convenient `atomic.Bool` type.

[go.uber.org/atomic]: https://pkg.go.dev/go.uber.org/atomic
[sync/atomic]: https://pkg.go.dev/sync/atomic

<table>
<thead><tr><th>Bad</th><th>Good</th></tr></thead>
<tbody>
<tr><td>

```go
type foo struct {
running int32 // atomic
}

func (f* foo) start() {
if atomic.SwapInt32(&f.running, 1) == 1 {
// already running…
return
}
// start the Foo
}

func (f *foo) isRunning() bool {
return f.running == 1 // race!
}
```

</td><td>

```go
type foo struct {
running atomic.Bool
}

func (f *foo) start() {
if f.running.Swap(true) {
// already running…
return
}
// start the Foo
}

func (f *foo) isRunning() bool {
return f.running.Load()
}
```

</td></tr>
</tbody></table>
Loading