1
1
# AdGuard Go Team Development Guidelines
2
2
3
- Following this document is obligatory for all new Go code. Some of the rules
3
+ Following this document is obligatory for all new Go code. Some of the rules
4
4
aren't enforced as thoroughly or remain broken in old code, but this is still
5
5
the place to find out about what we ** want** our code to look like and how to
6
6
improve it.
@@ -31,16 +31,16 @@ The rules are mostly sorted in the alphabetical order.
31
31
## <a href =" #code " id =" code " name =" code " >Code</a >
32
32
33
33
* <a href =" #li-cb105c8c " id =" li-cb105c8c " name =" li-cb105c8c " >§</a >
34
- Avoid ` break ` and ` continue ` with labels. Most of the time the code can be
34
+ Avoid ` break ` and ` continue ` with labels. Most of the time the code can be
35
35
rewritten without them, and most of the time the resulting new code is also
36
36
clearer.
37
37
38
38
* <a href =" #li-5305b436 " id =" li-5305b436 " name =" li-5305b436 " >§</a >
39
- Always ` recover ` from panics in new goroutines. Preferably in the very
40
- first statement. If all you want there is a log message, use ` log.OnPanic ` .
39
+ Always ` recover ` from panics in new goroutines. Preferably in the very
40
+ first statement. If all you want there is a log message, use ` log.OnPanic ` .
41
41
42
42
* <a href =" #li-02028202 " id =" li-02028202 " name =" li-02028202 " >§</a >
43
- Avoid ` fallthrough ` . It makes it harder to rearrange ` case ` s, to reason
43
+ Avoid ` fallthrough ` . It makes it harder to rearrange ` case ` s, to reason
44
44
about the code, and also to switch the code to a handler approach, if that
45
45
becomes necessary later.
46
46
@@ -51,15 +51,15 @@ The rules are mostly sorted in the alphabetical order.
51
51
Avoid ` init ` and use explicit initialization functions instead.
52
52
53
53
* <a href =" #li-fa33e482 " id =" li-fa33e482 " name =" li-fa33e482 " >§</a >
54
- Avoid lazy initialization. Constructors should validate their arguments and
54
+ Avoid lazy initialization. Constructors should validate their arguments and
55
55
return meaningful errors.
56
56
57
57
* <a href =" #li-6ae6bc94 " id =" li-6ae6bc94 " name =" li-6ae6bc94 " >§</a >
58
58
Avoid ` new ` , especially with structs, unless a temporary value is needed,
59
59
for example when checking the type of an error using ` errors.As ` .
60
60
61
61
* <a href =" #li-c9d7fde7 " id =" li-c9d7fde7 " name =" li-c9d7fde7 " >§</a >
62
- Avoid packages ` reflect ` and ` unsafe ` unless absolutely necessary. Always
62
+ Avoid packages ` reflect ` and ` unsafe ` unless absolutely necessary. Always
63
63
provide a comment explaining why you are using it.
64
64
65
65
* <a href =" #li-9d94cb85 " id =" li-9d94cb85 " name =" li-9d94cb85 " >§</a >
@@ -69,7 +69,7 @@ The rules are mostly sorted in the alphabetical order.
69
69
For example, if you have a long function that makes an HTTP request and
70
70
defers the close of the body at the beginning and then does more stuff, it's
71
71
better to factor out the HTTP request and the response parsing into
72
- a separate method. Same goes for mutexes.
72
+ a separate method. Same goes for mutexes.
73
73
74
74
That is, do ** not** do this:
75
75
@@ -83,7 +83,7 @@ The rules are mostly sorted in the alphabetical order.
83
83
v , err := decode (r)
84
84
check (err)
85
85
86
- // Lots of slow stuff with v. r is only closed once Foo exits.
86
+ // Lots of slow stuff with v. r is only closed once Foo exits.
87
87
}
88
88
```
89
89
@@ -109,11 +109,11 @@ The rules are mostly sorted in the alphabetical order.
109
109
110
110
* <a href=" #li-d027c6cd" id=" li-d027c6cd" name=" li-d027c6cd" >§</a>
111
111
Be aware of structure alignment as well as the number of [pointer
112
- bytes][ptr]. Exceptions could be made if a suboptimal alignment produces
112
+ bytes][ptr]. Exceptions could be made if a suboptimal alignment produces
113
113
significantly better readability.
114
114
115
115
` ` ` go
116
- // Bad! Lots of padding between the uint64s and bools. Pointers are at the
116
+ // Bad! Lots of padding between the uint64s and bools. Pointers are at the
117
117
// end of the structure.
118
118
type bad struct {
119
119
a uint64
@@ -129,7 +129,7 @@ The rules are mostly sorted in the alphabetical order.
129
129
z *otherType
130
130
}
131
131
132
- // Good. The padding is minimized, and the pointers are closer to the top.
132
+ // Good. The padding is minimized, and the pointers are closer to the top.
133
133
type good struct {
134
134
y *otherType
135
135
z *otherType
@@ -166,9 +166,9 @@ The rules are mostly sorted in the alphabetical order.
166
166
` ` `
167
167
168
168
* <a href=" #li-eaba198b" id=" li-eaba198b" name=" li-eaba198b" >§</a>
169
- Context values should be considered immutable. Do not use modifications
170
- of context values as a means of communicating something up the stack. That
171
- is, do **not** do this:
169
+ Context values should be considered immutable. Do not use modifications of
170
+ context values as a means of communicating something up the stack. That is,
171
+ do **not** do this:
172
172
173
173
` ` ` go
174
174
// Bad! Function outer expects inner to mutate logEntry.
@@ -194,12 +194,12 @@ The rules are mostly sorted in the alphabetical order.
194
194
` ` `
195
195
196
196
* <a href=" #li-450c3236" id=" li-450c3236" name=" li-450c3236" >§</a>
197
- Don ' t rely only on file names for build tags to work. Always add build tags
197
+ Don ' t rely only on file names for build tags to work. Always add build tags
198
198
as well.
199
199
200
200
* <a href="#li-7a36cc4c" id="li-7a36cc4c" name="li-7a36cc4c">§</a>
201
201
Don' t use ` fmt.Sprintf` where a more structured approach to string
202
- conversion could be used. For example, ` netutil.JoinHostPort` ,
202
+ conversion could be used. For example, ` netutil.JoinHostPort` ,
203
203
` net.JoinHostPort` or ` url.(*URL).String` .
204
204
205
205
* <a href=" #li-71081433" id=" li-71081433" name=" li-71081433" >§</a>
@@ -216,24 +216,24 @@ The rules are mostly sorted in the alphabetical order.
216
216
217
217
* <a href=" #li-b97aacf8" id=" li-b97aacf8" name=" li-b97aacf8" >§</a>
218
218
No name shadowing, including of predeclared identifiers, since it can often
219
- lead to subtle bugs, especially with errors. This rule does not apply to
219
+ lead to subtle bugs, especially with errors. This rule does not apply to
220
220
struct fields, since they are always used together with the name of the
221
221
struct value, so there isn' t any confusion.
222
222
223
223
* <a href="#li-74517cf1 " id="li-74517cf1 " name="li-74517cf1">§</a>
224
224
Prefer build constraints to `runtime.GOOS`.
225
225
226
226
* <a href="#li-851dedf8" id="li-851dedf8" name="li-851dedf8">§</a>
227
- Prefer constants to variables where possible. Avoid global variables unless
228
- necessary. Use [constant errors] instead of `errors.New`.
227
+ Prefer constants to variables where possible. Avoid global variables unless
228
+ necessary. Use [constant errors] instead of `errors.New`.
229
229
230
230
* <a href="#li-3a7f3909" id="li-3a7f3909" name="li-3a7f3909">§</a>
231
231
Prefer defining `Foo.String` and `ParseFoo` in terms of `Foo.MarshalText`
232
232
and `Foo.UnmarshalText` correspondingly and not the other way around.
233
233
234
234
* <a href="#li-edd678a8" id="li-edd678a8" name="li-edd678a8">§</a>
235
235
Prefer to use pointers to structs in function arguments, including method
236
- receivers, unless there is a reason to do the opposite. Among valid reasons
236
+ receivers, unless there is a reason to do the opposite. Among valid reasons
237
237
are:
238
238
239
239
* the struct is small, which typically means less than a few machine
@@ -262,8 +262,8 @@ The rules are mostly sorted in the alphabetical order.
262
262
Don' t forget to also [set the tab width][tab] in your editor' s settings.
263
263
264
264
* <a href="#li-4bfdabf9" id="li-4bfdabf9" name="li-4bfdabf9">§</a>
265
- Use linters. `make go-lint`, if the project has one. A minimum of
266
- `go vet`, ` errcheck`, and staticcheck if the project does not.
265
+ Use linters. `make go-lint`, if the project has one. A minimum of `go vet`,
266
+ `errcheck`, and staticcheck if the project does not.
267
267
268
268
* <a href="#li-29dc9ef0" id="li-29dc9ef0" name="li-29dc9ef0">§</a>
269
269
When returning an error from a function that also returns a non-nilable
@@ -360,7 +360,7 @@ See also the [text guidelines][text].
360
360
361
361
* <a href=" #li-dca638fe" id=" li-dca638fe" name=" li-dca638fe" >§</a>
362
362
Write names of RFCs without a hyphen and don' t put a newline between the
363
- letters and the numbers. Godoc and pkg.go.dev both will add a link to the
363
+ letters and the numbers. Godoc and pkg.go.dev both will add a link to the
364
364
RFC, but only if the RFC is spelled that way.
365
365
366
366
So, do this:
@@ -386,16 +386,16 @@ See also the [text guidelines][text].
386
386
387
387
* <a href="#li-92230a03" id="li-92230a03" name="li-92230a03">§</a>
388
388
Document important contracts (assertions, pre- and postconditions) of
389
- fields, functions and methods. That is, nilness of arguments, state of
390
- mutexes, relationship between struct fields, and so on. As an exception,
389
+ fields, functions and methods. That is, nilness of arguments, state of
390
+ mutexes, relationship between struct fields, and so on. As an exception,
391
391
a method receiver can be generally considered to be required to be non-nil,
392
392
unless a different behavior is explicitly documented.
393
393
394
394
For example:
395
395
396
396
```go
397
397
// needsNonNil is an example of a method that requires a non-nil argument.
398
- // m must not be nil. r.mu is expected to be locked.
398
+ // m must not be nil. r.mu is expected to be locked.
399
399
func (r *Receiver) needsNonNil(m *Message) (err error) {
400
400
// …
401
401
}
@@ -406,7 +406,7 @@ See also the [text guidelines][text].
406
406
## <a href="#errors" id="errors" name="errors">Error Handling</a>
407
407
408
408
* <a href="#li-651fcd50" id="li-651fcd50" name="li-651fcd50">§</a>
409
- Add context to errors but avoid duplication. For example, `os.Open` always
409
+ Add context to errors but avoid duplication. For example, `os.Open` always
410
410
adds the path to its error, so this is redundant:
411
411
412
412
```go
@@ -418,7 +418,7 @@ See also the [text guidelines][text].
418
418
```
419
419
420
420
If a function returns enough context, or a deferred helper is used, document
421
- that. Prefer to use a standard comment across a project. For example:
421
+ that. Prefer to use a standard comment across a project. For example:
422
422
423
423
```go
424
424
err = f()
@@ -429,9 +429,9 @@ See also the [text guidelines][text].
429
429
```
430
430
431
431
* <a href="#li-17e872ff" id="li-17e872ff" name="li-17e872ff">§</a>
432
- Avoid having multiple errors in a function. In situations when it' s not
433
- feasible, use meaningful names. For example, ` closeErr` for errors
434
- from ` Close()` or ` testErr` for subtest errors.
432
+ Avoid having multiple errors in a function. In situations when it' s not
433
+ feasible, use meaningful names. For example, ` closeErr` for errors from
434
+ ` Close()` or ` testErr` for subtest errors.
435
435
436
436
* <a href=" #li-9e172a2e" id=" li-9e172a2e" name=" li-9e172a2e" >§</a>
437
437
Avoid using the word ` error` inside error messages.
@@ -463,7 +463,7 @@ See also the [text guidelines][text].
463
463
project has its own conventions regarding uppercase letters.
464
464
465
465
* <a href=" #li-6d1104bd" id=" li-6d1104bd" name=" li-6d1104bd" >§</a>
466
- Use ` panic` **only** to indicate critical assertion failures. **Do not**
466
+ Use ` panic` **only** to indicate critical assertion failures. **Do not**
467
467
use panics for normal error handling.
468
468
469
469
* <a href=" #li-f6d13b11" id=" li-f6d13b11" name=" li-f6d13b11" >§</a>
@@ -500,7 +500,7 @@ See also the [text guidelines][text].
500
500
with empty lines unless it' s the only statement in that block.
501
501
502
502
* <a href="#li-82784b41" id="li-82784b41" name="li-82784b41">§</a>
503
- Don' t group type declarations together. Unlike with blocks of ` const` s,
503
+ Don' t group type declarations together. Unlike with blocks of ` const` s,
504
504
where a ` iota` may be used or where all constants belong to a certain type ,
505
505
there is no reason to group ` type` s.
506
506
@@ -589,7 +589,7 @@ See also the [text guidelines][text].
589
589
590
590
* <a href=" #li-46a924cd" id=" li-46a924cd" name=" li-46a924cd" >§</a>
591
591
Put deferred calls of destructors, for example ` f.Close()` , into the same
592
- paragraph as constructors. This is an exception to the [paragraph
592
+ paragraph as constructors. This is an exception to the [paragraph
593
593
rule][par].
594
594
595
595
` ` ` go
@@ -613,7 +613,7 @@ See also the [text guidelines][text].
613
613
` ` `
614
614
615
615
* <a href=" #li-f2156af9" id=" li-f2156af9" name=" li-f2156af9" >§</a>
616
- Start a new paragraph after the final closing curly brace of a block. So
616
+ Start a new paragraph after the final closing curly brace of a block. So
617
617
this:
618
618
619
619
` ` ` go
@@ -654,7 +654,7 @@ See also the [text guidelines][text].
654
654
* <a href=" #li-d9b8f5a8" id=" li-d9b8f5a8" name=" li-d9b8f5a8" >§</a>
655
655
When a function' s definition becomes [too long][long], first make the
656
656
function' s arguments vertically placed and only then do the same with the
657
- return values. That is, do this:
657
+ return values. That is, do this:
658
658
659
659
` ` ` go
660
660
func functionWithALongName(
@@ -725,7 +725,7 @@ See also the [text guidelines][text].
725
725
726
726
* <a href=" #li-cc358586" id=" li-cc358586" name=" li-cc358586" >§</a>
727
727
Don ' t use underscores in file and package names, unless they' re build tags
728
- or for tests. This is to prevent accidental build errors with weird tags.
728
+ or for tests. This is to prevent accidental build errors with weird tags.
729
729
730
730
* <a href=" #li-5a2d4941" id=" li-5a2d4941" name=" li-5a2d4941" >§</a>
731
731
For brands or words with more than 1 capital letter, lowercase all letters:
@@ -745,7 +745,7 @@ See also the [text guidelines][text].
745
745
` ` `
746
746
747
747
* <a href=" #li-a3a30716" id=" li-a3a30716" name=" li-a3a30716" >§</a>
748
- Name benchmarks and tests using the same convention as examples. For
748
+ Name benchmarks and tests using the same convention as examples. For
749
749
example:
750
750
751
751
` ` ` go
@@ -758,7 +758,7 @@ See also the [text guidelines][text].
758
758
* <a href=" #li-4b3adb1b" id=" li-4b3adb1b" name=" li-4b3adb1b" >§</a>
759
759
Name ` context.Context` helper functions that return values from the context
760
760
` FooFromContext` and the ones that return a new contest with new values,
761
- ` ContextWithFoo` or ` WithFoo` . Just like in the standard library, the
761
+ ` ContextWithFoo` or ` WithFoo` . Just like in the standard library, the
762
762
parent context should be called ` parent` .
763
763
764
764
` ` ` go
@@ -863,15 +863,15 @@ See also the [text guidelines][text].
863
863
` ` `
864
864
865
865
* <a href=" #li-a52e192a" id=" li-a52e192a" name=" li-a52e192a" >§</a>
866
- Prefer to put all tests into a separate [test package ][tpkg]. Tests in the
866
+ Prefer to put all tests into a separate [test package ][tpkg]. Tests in the
867
867
same package that check unexported APIs should be put into a separate file
868
868
named ` foo_internal_test.go` .
869
869
870
870
* <a href=" #li-b4f670ce" id=" li-b4f670ce" name=" li-b4f670ce" >§</a>
871
- Strive to make the test suite finish quickly. If you have long-running
872
- integration test or fuzzes, document them, put them into a separate Makefile
873
- target, and include them into the CI pipeline, but not the main ` make test `
874
- target.
871
+ Strive to make the test suite finish quickly. If you have long-running
872
+ integration test or fuzzes, document them, put them into a separate
873
+ Makefile target, and include them into the CI pipeline, but not the main
874
+ ` make test ` target.
875
875
876
876
* <a href=" #li-9124bf62" id=" li-9124bf62" name=" li-9124bf62" >§</a>
877
877
Use ` assert.NoError` and ` require.NoError` instead of ` assert.Nil` and
0 commit comments