Thank you for your interest in contributing to GoForge! This document provides guidelines and instructions for contributing.
- Code of Conduct
- How Can I Contribute?
- Development Setup
- Pull Request Process
- Coding Standards
- Testing
- Documentation
This project adheres to a Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to the project maintainers.
Before creating bug reports, please check existing issues to avoid duplicates. When creating a bug report, include:
- Clear title and description
- Steps to reproduce the issue
- Expected behavior vs actual behavior
- Environment details (OS, Go version, etc.)
- Code samples or error messages
Enhancement suggestions are welcome! Please provide:
- Clear title and description
- Use case for the enhancement
- Expected behavior and implementation ideas
- Examples from other projects (if applicable)
To add support for a new web framework:
- Create template files in
internal/generator/templates/ - Add framework-specific handlers, middleware, and server files
- Update
getServerSpecificTemplates()ingenerator.go - Update validation in
validateServerType() - Add tests for the new framework
- Update documentation
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests (
make test) - Run linters (
make lint) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Go 1.26.2 or higher
- Git
- Make (optional, but recommended)
-
Clone the repository
git clone https://github.com/yourusername/goforge.git cd goforge -
Install dependencies
go mod download
-
Build the project
make build # OR go build -o goforge ./cmd/goforge -
Run tests
make test # OR go test -v -race ./...
-
Install locally
go install ./cmd/goforge
- Update documentation - Update README.md, code comments, and any relevant docs
- Add tests - Ensure new code has appropriate test coverage
- Pass all checks - Tests, linters, and CI must pass
- Keep commits clean - Use clear, descriptive commit messages
- One feature per PR - Keep PRs focused on a single feature or fix
- Update CHANGELOG - Add an entry describing your changes
- Tests added/updated and passing
- Documentation updated
- Linters pass (
make lint) - No breaking changes (or clearly documented)
- CHANGELOG.md updated
- Commits are clean and well-described
- Follow Effective Go
- Use
gofmtfor formatting - Use
golangci-lintfor linting - Write idiomatic Go code
goforge/
├── cmd/goforge/ # CLI entry point
├── internal/ # Private application code
│ ├── cmd/ # CLI commands (create, version, etc.)
│ ├── generator/ # Project generation logic
│ ├── interfaces/ # Dependency injection interfaces
│ ├── adapters/ # Real implementations
│ └── mocks/ # Mock implementations for testing
- Packages: lowercase, single word (e.g.,
generator,handler) - Files: lowercase with underscores (e.g.,
create_test.go) - Variables: camelCase (e.g.,
projectName) - Exported: PascalCase (e.g.,
NewGenerator) - Interfaces: noun or adjective (e.g.,
FileSystem,Commander)
// Good: Wrap errors with context
if err := doSomething(); err != nil {
return fmt.Errorf("failed to do something: %w", err)
}
// Good: Handle errors immediately
result, err := compute()
if err != nil {
return err
}
// Avoid: Ignoring errors
_ = doSomething() // Only when truly safe to ignoreAll external dependencies (filesystem, commands, I/O) should use interfaces:
// Define interface
type FileSystem interface {
Create(name string) (WriteCloser, error)
// ...
}
// Accept interface in constructors
func NewGenerator(fs FileSystem) *Generator {
// ...
}# All tests
make test
# With coverage
go test -v -race -coverprofile=coverage.out ./...
# View coverage
go tool cover -html=coverage.out
# Specific package
go test -v ./internal/cmd/...func TestFeature(t *testing.T) {
// Arrange
mockFS := &mocks.MockFileSystem{
CreateFunc: func(name string) (WriteCloser, error) {
return mockWriter, nil
},
}
// Act
result := DoSomething(mockFS)
// Assert
assert.NoError(t, err)
assert.Equal(t, expected, result)
}- Minimum: 80% overall coverage
- Critical paths: 100% coverage
- Error handling: All error paths tested
- Edge cases: Boundary conditions tested
// Package generator provides project generation functionality.
package generator
// Generator handles template processing and file generation.
type Generator struct {
config ProjectConfig
}
// Generate creates a new project from templates.
// It validates the project name, creates directories, and generates files.
func (g *Generator) Generate() error {
// Implementation
}When adding features:
- Update feature list
- Add usage examples
- Update command documentation
- Add troubleshooting tips (if needed)
## [Version] - YYYY-MM-DD
### Added
- New feature description
### Changed
- Changed feature description
### Fixed
- Bug fix description
### Removed
- Removed feature description- Create template file in
internal/generator/templates/ - Use
.tmplextension - Add to
commonFilesorgetServerSpecificTemplates() - Test with both Fiber and Gin (if applicable)
Available variables in templates:
{{.ProjectName}}- Project name{{.ProjectPath}}- Full project path{{.ModulePath}}- Go module path{{.ServerType}}- "fiber" or "gin"
// Available functions
{{toLower .ServerType}} // Convert to lowercase
{{toUpper .ServerType}} // Convert to uppercase
{{eq .ServerType "gin"}} // Equality check- Update version in
internal/cmd/version.go - Update CHANGELOG.md
- Create git tag:
git tag -a v1.x.x -m "Release v1.x.x" - Push tag:
git push origin v1.x.x - CI will create GitHub release automatically
- Open an issue for bug reports or feature requests
- Start a discussion for questions or ideas
- Check existing issues and discussions first
By contributing, you agree that your contributions will be licensed under the same license as the project.
Thank you for contributing to GoForge! 🚀