Skip to content

Commit 5a1e5fd

Browse files
alexandearCopilot
andauthored
chore: Add Copilot instructions (#1437)
* chore: Add Copilot instructions * Update .github/copilot-instructions.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * update DEVELOPING * move to instructions * update DEVELOPING --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent b969b8b commit 5a1e5fd

File tree

2 files changed

+251
-0
lines changed

2 files changed

+251
-0
lines changed
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
---
2+
description: 'Instructions for writing Go code following idiomatic Go practices and community standards'
3+
applyTo: '**/*.go,**/go.mod,**/go.sum'
4+
---
5+
6+
# Go Development Instructions
7+
8+
Follow idiomatic Go practices and community standards when writing Go code.
9+
These instructions are based on [Effective Go](https://go.dev/doc/effective_go),
10+
[Go Code Review Comments](https://go.dev/wiki/CodeReviewComments),
11+
[Go Test Code Comments](https://go.dev/wiki/TestComments),
12+
and [Google's Go Style Guide](https://google.github.io/styleguide/go/).
13+
14+
## General Instructions
15+
16+
- Write simple, clear, and idiomatic Go code
17+
- Favor clarity and simplicity over cleverness
18+
- Follow the principle of least surprise
19+
- Keep the happy path left-aligned (minimize indentation)
20+
- Return early to reduce nesting
21+
- Make the zero value useful
22+
- Document exported types, functions, methods, and packages
23+
- Use Go modules for dependency management
24+
25+
## Naming Conventions
26+
27+
### Packages
28+
29+
- Use lowercase, single-word package names
30+
- Avoid underscores, hyphens, or mixedCaps
31+
- Choose names that describe what the package provides, not what it contains
32+
- Avoid generic names like `util`, `common`, or `base`
33+
- Package names should be singular, not plural
34+
35+
### Variables and Functions
36+
37+
- Use mixedCaps or MixedCaps (camelCase) rather than underscores
38+
- Keep names short but descriptive
39+
- Use single-letter variables only for very short scopes (like loop indices)
40+
- Exported names start with a capital letter
41+
- Unexported names start with a lowercase letter
42+
- Avoid stuttering (e.g., avoid `http.HTTPServer`, prefer `http.Server`)
43+
44+
### Interfaces
45+
46+
- Name interfaces with -er suffix when possible (e.g., `Reader`, `Writer`, `Formatter`)
47+
- Single-method interfaces should be named after the method (e.g., `Read``Reader`)
48+
- Keep interfaces small and focused
49+
50+
### Constants
51+
52+
- Use MixedCaps for exported constants
53+
- Use mixedCaps for unexported constants
54+
- Group related constants using `const` blocks
55+
- Consider using typed constants for better type safety
56+
57+
## Code Style and Formatting
58+
59+
### Formatting
60+
61+
- Always use `gofmt` to format code
62+
- Use `goimports` to manage imports automatically
63+
- Keep line length reasonable (no hard limit, but consider readability)
64+
- Add blank lines to separate logical groups of code
65+
66+
### Comments
67+
68+
- Write comments in complete sentences
69+
- Start sentences with the name of the thing being described
70+
- Package comments should start with "Package [name]"
71+
- Use line comments (`//`) for most comments
72+
- Use block comments (`/* */`) only for files in `testdata`
73+
- Document why, not what, unless the what is complex
74+
75+
### Error Handling
76+
77+
- Check errors immediately after the function call
78+
- Don't ignore errors using `_` unless you have a good reason (document why)
79+
- Wrap errors with context using `fmt.Errorf` with `%w` verb
80+
- Create custom error types when you need to check for specific errors
81+
- Place error returns as the last return value
82+
- Name error variables `err`
83+
- Keep error messages lowercase and don't end with punctuation
84+
85+
## Architecture and Project Structure
86+
87+
### Package Organization
88+
89+
- Follow standard Go project layout conventions
90+
- Use `internal/` for packages that shouldn't be imported by external projects
91+
- Group related functionality into packages
92+
- Avoid circular dependencies
93+
94+
### Dependency Management
95+
96+
- Use Go modules (`go.mod` and `go.sum`)
97+
- Keep dependencies minimal
98+
- Regularly update dependencies for security patches
99+
- Use `go mod tidy` to clean up unused dependencies
100+
101+
## Type Safety and Language Features
102+
103+
### Type Definitions
104+
105+
- Define types to add meaning and type safety
106+
- Use struct tags for JSON, XML, database mappings
107+
- Prefer explicit type conversions
108+
- Use type assertions carefully and check the second return value
109+
110+
### Pointers vs Values
111+
112+
- Use pointers for large structs or when you need to modify the receiver
113+
- Use values for small structs and when immutability is desired
114+
- Be consistent within a type's method set
115+
- Consider the zero value when choosing pointer vs value receivers
116+
117+
### Interfaces and Composition
118+
119+
- Accept interfaces, return concrete types
120+
- Keep interfaces small (1-3 methods is ideal)
121+
- Use embedding for composition
122+
- Define interfaces close to where they're used, not where they're implemented
123+
- Don't export interfaces unless necessary
124+
125+
## Concurrency
126+
127+
### Goroutines
128+
129+
- Don't create goroutines in libraries; let the caller control concurrency
130+
- Always know how a goroutine will exit
131+
- Use `sync.WaitGroup` or channels to wait for goroutines
132+
- Avoid goroutine leaks by ensuring cleanup
133+
134+
### Channels
135+
136+
- Use channels to communicate between goroutines
137+
- Don't communicate by sharing memory; share memory by communicating
138+
- Close channels from the sender side, not the receiver
139+
- Use buffered channels when you know the capacity
140+
- Use `select` for non-blocking operations
141+
142+
### Synchronization
143+
144+
- Use `sync.Mutex` for protecting shared state
145+
- Keep critical sections small
146+
- Use `sync.RWMutex` when you have many readers
147+
- Prefer channels over mutexes when possible
148+
- Use `sync.Once` for one-time initialization
149+
150+
## Error Handling Patterns
151+
152+
### Creating Errors
153+
154+
- Use `errors.New` for simple static errors
155+
- Use `fmt.Errorf` for dynamic errors
156+
- Create custom error types for domain-specific errors
157+
- Export error variables for sentinel errors
158+
- Use `errors.Is` and `errors.As` for error checking
159+
160+
### Error Propagation
161+
162+
- Add context when propagating errors up the stack
163+
- Don't log and return errors (choose one)
164+
- Handle errors at the appropriate level
165+
- Consider using structured errors for better debugging
166+
167+
## Performance Optimization
168+
169+
### Memory Management
170+
171+
- Minimize allocations in hot paths
172+
- Reuse objects when possible (consider `sync.Pool`)
173+
- Use value receivers for small structs
174+
- Preallocate slices when size is known
175+
- Avoid unnecessary string conversions
176+
177+
### Profiling
178+
179+
- Use built-in profiling tools (`pprof`)
180+
- Benchmark critical code paths
181+
- Profile before optimizing
182+
- Focus on algorithmic improvements first
183+
- Consider using `testing.B` for benchmarks
184+
185+
## Testing
186+
187+
### Test Organization
188+
189+
- Keep tests in the same package (white-box testing)
190+
- Use `_test` package suffix for black-box testing
191+
- Name test files with `_test.go` suffix
192+
- Place test files next to the code they test
193+
194+
### Writing Tests
195+
196+
- Use table-driven tests for multiple test cases
197+
- Name tests descriptively using `TestStructName_FunctionName`
198+
- Use subtests with `t.Run` for better organization
199+
- Test both success and error cases
200+
- Avoid the use of `assert` libraries for clearer test failures
201+
- When you use `t.Run` to create a subtest, the first argument is used as a descriptive name for the test
202+
- Test outputs should output the actual value that the function returned before printing the value that was expected
203+
204+
### Test Helpers
205+
206+
- Mark helper functions with `t.Helper()`
207+
- Create test fixtures for complex setup
208+
- Clean up resources using `t.Cleanup()`
209+
210+
## Documentation
211+
212+
### Code Documentation
213+
214+
- Document all exported symbols
215+
- Start documentation with the symbol name
216+
- Keep documentation close to code
217+
- Update documentation when code changes
218+
219+
## Tools and Development Workflow
220+
221+
### Essential Tools
222+
223+
- `go fmt`: Format code
224+
- `go vet`: Find suspicious constructs
225+
- `go test`: Run tests
226+
- `go mod`: Manage dependencies
227+
- `revive` or `golangci-lint`: Additional linting
228+
229+
### Development Practices
230+
231+
- Run tests before committing
232+
- Keep commits focused and atomic
233+
- Write meaningful commit messages
234+
- Review diffs before committing
235+
236+
## Common Pitfalls to Avoid
237+
238+
- Not checking errors
239+
- Ignoring race conditions
240+
- Creating goroutine leaks
241+
- Not using defer for cleanup
242+
- Modifying maps concurrently
243+
- Not understanding nil interfaces vs nil pointers
244+
- Forgetting to close resources (files, connections)
245+
- Using global variables unnecessarily
246+
- Over-using empty interfaces (`interface{}` or `any`)
247+
- Not considering the zero value of types

‎DEVELOPING.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ DEBUG=1 go run main.go
3131

3232
This will output debug information to `stderr` and to the log file `revive.log` created in the current working directory.
3333

34+
## Coding standards
35+
36+
Follow [the instructions](.github/instructions/) which contain Go coding standards and conventions used by both humans and GitHub Copilot.
37+
3438
## Development of rules
3539

3640
If you want to develop a new rule, follow as an example the already existing rules in the [rule package](https://github.com/mgechev/revive/tree/master/rule).

0 commit comments

Comments
 (0)