Skip to content

Commit 4ab31cd

Browse files
authored
Feat/golang instructions (#38)
* feat: ✨ Add comprehensive Go development instructions - Introduced a detailed guide for writing Go code adhering to idiomatic practices. - Covers general instructions, naming conventions, code style, error handling, and security best practices. - References established resources like Effective Go and Google's Go Style Guide. * feat: ✨ Add Go development instructions - Introduced guidelines for writing Go code that adhere to idiomatic Go practices and community standards.
1 parent 6ee517a commit 4ab31cd

File tree

2 files changed

+293
-0
lines changed

2 files changed

+293
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Team and project-specific instructions to enhance GitHub Copilot's behavior for
3232
- [.NET MAUI](instructions/dotnet-maui.instructions.md) - .NET MAUI component and application patterns
3333
- [Genaiscript](instructions/genaiscript.instructions.md) - AI-powered script generation guidelines
3434
- [Generate Modern Terraform Code For Azure](instructions/generate-modern-terraform-code-for-azure.instructions.md) - Guidelines for generating modern Terraform code for Azure
35+
- [Go Development Instructions](instructions/go.instructions.md) - Instructions for writing Go code following idiomatic Go practices and community standards
3536
- [Guidance for Localization](instructions/localization.instructions.md) - Guidelines for localizing markdown documents
3637
- [Markdown](instructions/markdown.instructions.md) - Documentation and content creation standards
3738
- [Next.js + Tailwind Development Instructions](instructions/nextjs-tailwind.instructions.md) - Next.js + Tailwind development standards and instructions

instructions/go.instructions.md

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

0 commit comments

Comments
 (0)