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. | 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 | ## 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). | 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