mirror of
				https://github.com/mgechev/revive.git
				synced 2025-10-30 23:37:49 +02:00 
			
		
		
		
	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>
This commit is contained in:
		
							
								
								
									
										247
									
								
								.github/instructions/go.instructions.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										247
									
								
								.github/instructions/go.instructions.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,247 @@ | ||||
| --- | ||||
| description: 'Instructions for writing Go code following idiomatic Go practices and community standards' | ||||
| applyTo: '**/*.go,**/go.mod,**/go.sum' | ||||
| --- | ||||
|  | ||||
| # Go Development Instructions | ||||
|  | ||||
| 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), | ||||
| [Go Test Code Comments](https://go.dev/wiki/TestComments), | ||||
| and [Google's Go Style Guide](https://google.github.io/styleguide/go/). | ||||
|  | ||||
| ## General Instructions | ||||
|  | ||||
| - Write simple, clear, and idiomatic Go code | ||||
| - Favor clarity and simplicity over cleverness | ||||
| - Follow the principle of least surprise | ||||
| - Keep the happy path left-aligned (minimize indentation) | ||||
| - Return early to reduce nesting | ||||
| - Make the zero value useful | ||||
| - Document exported types, functions, methods, and packages | ||||
| - Use Go modules for dependency management | ||||
|  | ||||
| ## Naming Conventions | ||||
|  | ||||
| ### Packages | ||||
|  | ||||
| - Use lowercase, single-word package names | ||||
| - Avoid underscores, hyphens, or mixedCaps | ||||
| - Choose names that describe what the package provides, not what it contains | ||||
| - Avoid generic names like `util`, `common`, or `base` | ||||
| - Package names should be singular, not plural | ||||
|  | ||||
| ### Variables and Functions | ||||
|  | ||||
| - Use mixedCaps or MixedCaps (camelCase) rather than underscores | ||||
| - Keep names short but descriptive | ||||
| - Use single-letter variables only for very short scopes (like loop indices) | ||||
| - Exported names start with a capital letter | ||||
| - Unexported names start with a lowercase letter | ||||
| - Avoid stuttering (e.g., avoid `http.HTTPServer`, prefer `http.Server`) | ||||
|  | ||||
| ### Interfaces | ||||
|  | ||||
| - Name interfaces with -er suffix when possible (e.g., `Reader`, `Writer`, `Formatter`) | ||||
| - Single-method interfaces should be named after the method (e.g., `Read` → `Reader`) | ||||
| - Keep interfaces small and focused | ||||
|  | ||||
| ### Constants | ||||
|  | ||||
| - Use MixedCaps for exported constants | ||||
| - Use mixedCaps for unexported constants | ||||
| - Group related constants using `const` blocks | ||||
| - Consider using typed constants for better type safety | ||||
|  | ||||
| ## Code Style and Formatting | ||||
|  | ||||
| ### Formatting | ||||
|  | ||||
| - Always use `gofmt` to format code | ||||
| - Use `goimports` to manage imports automatically | ||||
| - Keep line length reasonable (no hard limit, but consider readability) | ||||
| - Add blank lines to separate logical groups of code | ||||
|  | ||||
| ### Comments | ||||
|  | ||||
| - Write comments in complete sentences | ||||
| - Start sentences with the name of the thing being described | ||||
| - Package comments should start with "Package [name]" | ||||
| - Use line comments (`//`) for most comments | ||||
| - Use block comments (`/* */`) only for files in `testdata` | ||||
| - Document why, not what, unless the what is complex | ||||
|  | ||||
| ### Error Handling | ||||
|  | ||||
| - Check errors immediately after the function call | ||||
| - Don't ignore errors using `_` unless you have a good reason (document why) | ||||
| - Wrap errors with context using `fmt.Errorf` with `%w` verb | ||||
| - Create custom error types when you need to check for specific errors | ||||
| - Place error returns as the last return value | ||||
| - Name error variables `err` | ||||
| - Keep error messages lowercase and don't end with punctuation | ||||
|  | ||||
| ## Architecture and Project Structure | ||||
|  | ||||
| ### Package Organization | ||||
|  | ||||
| - Follow standard Go project layout conventions | ||||
| - Use `internal/` for packages that shouldn't be imported by external projects | ||||
| - Group related functionality into packages | ||||
| - Avoid circular dependencies | ||||
|  | ||||
| ### Dependency Management | ||||
|  | ||||
| - Use Go modules (`go.mod` and `go.sum`) | ||||
| - Keep dependencies minimal | ||||
| - Regularly update dependencies for security patches | ||||
| - Use `go mod tidy` to clean up unused dependencies | ||||
|  | ||||
| ## Type Safety and Language Features | ||||
|  | ||||
| ### Type Definitions | ||||
|  | ||||
| - Define types to add meaning and type safety | ||||
| - Use struct tags for JSON, XML, database mappings | ||||
| - Prefer explicit type conversions | ||||
| - Use type assertions carefully and check the second return value | ||||
|  | ||||
| ### Pointers vs Values | ||||
|  | ||||
| - Use pointers for large structs or when you need to modify the receiver | ||||
| - Use values for small structs and when immutability is desired | ||||
| - Be consistent within a type's method set | ||||
| - Consider the zero value when choosing pointer vs value receivers | ||||
|  | ||||
| ### Interfaces and Composition | ||||
|  | ||||
| - Accept interfaces, return concrete types | ||||
| - Keep interfaces small (1-3 methods is ideal) | ||||
| - Use embedding for composition | ||||
| - Define interfaces close to where they're used, not where they're implemented | ||||
| - Don't export interfaces unless necessary | ||||
|  | ||||
| ## Concurrency | ||||
|  | ||||
| ### Goroutines | ||||
|  | ||||
| - Don't create goroutines in libraries; let the caller control concurrency | ||||
| - Always know how a goroutine will exit | ||||
| - Use `sync.WaitGroup` or channels to wait for goroutines | ||||
| - Avoid goroutine leaks by ensuring cleanup | ||||
|  | ||||
| ### Channels | ||||
|  | ||||
| - Use channels to communicate between goroutines | ||||
| - Don't communicate by sharing memory; share memory by communicating | ||||
| - Close channels from the sender side, not the receiver | ||||
| - Use buffered channels when you know the capacity | ||||
| - Use `select` for non-blocking operations | ||||
|  | ||||
| ### Synchronization | ||||
|  | ||||
| - Use `sync.Mutex` for protecting shared state | ||||
| - Keep critical sections small | ||||
| - Use `sync.RWMutex` when you have many readers | ||||
| - Prefer channels over mutexes when possible | ||||
| - Use `sync.Once` for one-time initialization | ||||
|  | ||||
| ## Error Handling Patterns | ||||
|  | ||||
| ### Creating Errors | ||||
|  | ||||
| - Use `errors.New` for simple static errors | ||||
| - Use `fmt.Errorf` for dynamic errors | ||||
| - Create custom error types for domain-specific errors | ||||
| - Export error variables for sentinel errors | ||||
| - Use `errors.Is` and `errors.As` for error checking | ||||
|  | ||||
| ### Error Propagation | ||||
|  | ||||
| - Add context when propagating errors up the stack | ||||
| - Don't log and return errors (choose one) | ||||
| - Handle errors at the appropriate level | ||||
| - Consider using structured errors for better debugging | ||||
|  | ||||
| ## Performance Optimization | ||||
|  | ||||
| ### Memory Management | ||||
|  | ||||
| - Minimize allocations in hot paths | ||||
| - Reuse objects when possible (consider `sync.Pool`) | ||||
| - Use value receivers for small structs | ||||
| - Preallocate slices when size is known | ||||
| - Avoid unnecessary string conversions | ||||
|  | ||||
| ### Profiling | ||||
|  | ||||
| - Use built-in profiling tools (`pprof`) | ||||
| - Benchmark critical code paths | ||||
| - Profile before optimizing | ||||
| - Focus on algorithmic improvements first | ||||
| - Consider using `testing.B` for benchmarks | ||||
|  | ||||
| ## Testing | ||||
|  | ||||
| ### Test Organization | ||||
|  | ||||
| - Keep tests in the same package (white-box testing) | ||||
| - Use `_test` package suffix for black-box testing | ||||
| - Name test files with `_test.go` suffix | ||||
| - Place test files next to the code they test | ||||
|  | ||||
| ### Writing Tests | ||||
|  | ||||
| - Use table-driven tests for multiple test cases | ||||
| - Name tests descriptively using `TestStructName_FunctionName` | ||||
| - Use subtests with `t.Run` for better organization | ||||
| - Test both success and error cases | ||||
| - Avoid the use of `assert` libraries for clearer test failures | ||||
| - When you use `t.Run` to create a subtest, the first argument is used as a descriptive name for the test | ||||
| - Test outputs should output the actual value that the function returned before printing the value that was expected | ||||
|  | ||||
| ### Test Helpers | ||||
|  | ||||
| - Mark helper functions with `t.Helper()` | ||||
| - Create test fixtures for complex setup | ||||
| - Clean up resources using `t.Cleanup()` | ||||
|  | ||||
| ## Documentation | ||||
|  | ||||
| ### Code Documentation | ||||
|  | ||||
| - Document all exported symbols | ||||
| - Start documentation with the symbol name | ||||
| - Keep documentation close to code | ||||
| - Update documentation when code changes | ||||
|  | ||||
| ## Tools and Development Workflow | ||||
|  | ||||
| ### Essential Tools | ||||
|  | ||||
| - `go fmt`: Format code | ||||
| - `go vet`: Find suspicious constructs | ||||
| - `go test`: Run tests | ||||
| - `go mod`: Manage dependencies | ||||
| - `revive` or `golangci-lint`: Additional linting | ||||
|  | ||||
| ### Development Practices | ||||
|  | ||||
| - Run tests before committing | ||||
| - Keep commits focused and atomic | ||||
| - Write meaningful commit messages | ||||
| - Review diffs before committing | ||||
|  | ||||
| ## Common Pitfalls to Avoid | ||||
|  | ||||
| - Not checking errors | ||||
| - Ignoring race conditions | ||||
| - Creating goroutine leaks | ||||
| - Not using defer for cleanup | ||||
| - Modifying maps concurrently | ||||
| - Not understanding nil interfaces vs nil pointers | ||||
| - Forgetting to close resources (files, connections) | ||||
| - Using global variables unnecessarily | ||||
| - Over-using empty interfaces (`interface{}` or `any`) | ||||
| - Not considering the zero value of types | ||||
| @@ -31,6 +31,10 @@ DEBUG=1 go run main.go | ||||
|  | ||||
| This will output debug information to `stderr` and to the log file `revive.log` created in the current working directory. | ||||
|  | ||||
| ## Coding standards | ||||
|  | ||||
| Follow [the instructions](.github/instructions/) which contain Go coding standards and conventions used by both humans and GitHub Copilot. | ||||
|  | ||||
| ## Development of rules | ||||
|  | ||||
| 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). | ||||
|   | ||||
		Reference in New Issue
	
	Block a user