Thank you for your interest in contributing to Hosts Manager! This document provides guidelines and instructions for contributors.
- Code of Conduct
- Getting Started
- Development Setup
- Contributing Process
- Code Style and Standards
- Testing
- Documentation
- Release Process
This project follows the Go Community Code of Conduct. Please be respectful and inclusive in all interactions.
- Go 1.19 or higher
- Git
- Make (optional but recommended)
- golangci-lint (for linting)
- gosec (for security checks)
-
Fork and Clone
git clone https://github.com/your-username/hosts-manager.git cd hosts-manager -
Install Dependencies
make init # Installs development tools make deps # Downloads Go dependencies
-
Verify Setup
make validate # Runs fmt, vet, lint, and test -
Build and Test
make build # Build binary make test # Run tests make coverage # Generate coverage report
Before starting work, please:
- Check existing issues to avoid duplication
- Create an issue describing the bug or feature
- Discuss the approach with maintainers
- Wait for approval before starting significant work
Use descriptive branch names:
feature/add-xxxfor new featuresbugfix/fix-xxxfor bug fixesdocs/update-xxxfor documentationrefactor/improve-xxxfor refactoring
# Create feature branch
git checkout -b feature/add-new-command
# Make your changes
# ...
# Test your changes
make validate
# Commit with descriptive message
git commit -m "feat: add new command for bulk operations
- Implement bulk add/remove operations
- Add tests for bulk operations
- Update documentation
- Closes #123"Follow Conventional Commits:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Types:
feat: new featurefix: bug fixdocs: documentation onlystyle: formatting, no code changerefactor: code change that neither fixes bug nor adds featuretest: adding missing testschore: changes to build process or auxiliary tools
Examples:
feat(tui): add vim-style navigation keybindings
fix(parser): handle malformed IP addresses correctly
docs(readme): update installation instructions
-
Create Pull Request
- Use descriptive title and description
- Link related issues with "Closes #123"
- Fill out the PR template completely
-
PR Requirements
- All tests pass
- Code coverage maintained or improved
- Documentation updated
- No linting errors
- Commit messages follow convention
-
Review Process
- Address all review comments
- Update commits or create fixup commits
- Request re-review after changes
Follow standard Go practices:
- Use
go fmt(automated in make commands) - Follow Effective Go
- Use meaningful variable and function names
- Add comments for exported functions and complex logic
- Keep functions small and focused
-
Error Handling
// Good if err != nil { return fmt.Errorf("failed to parse hosts file: %w", err) } // Avoid if err != nil { panic(err) }
-
Logging and Output
// Use structured logging if verbose { fmt.Println("Backup created successfully") } // For errors, use stderr fmt.Fprintf(os.Stderr, "Error: %v\n", err)
-
Configuration
- Use the existing config system
- Add new options to
internal/config/config.go - Update default configuration appropriately
cmd/hosts-manager/ # Main application
internal/ # Internal packages
├── config/ # Configuration management
├── hosts/ # Hosts file operations
├── tui/ # Terminal user interface
└── backup/ # Backup and restore
pkg/ # Reusable packages
├── platform/ # Platform-specific code
└── search/ # Search functionality
make test # Run all tests
make coverage # Generate coverage report
make bench # Run benchmarks-
Test File Naming
parser.go -> parser_test.go config.go -> config_test.go -
Test Function Naming
func TestParser_Parse(t *testing.T) { ... } func TestConfig_Load(t *testing.T) { ... }
-
Table-Driven Tests
func TestFormatEntry(t *testing.T) { tests := []struct { name string entry Entry expected string }{ { name: "basic entry", entry: Entry{ IP: "127.0.0.1", Hostnames: []string{"localhost"}, Enabled: true, }, expected: "127.0.0.1 localhost", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := formatEntry(tt.entry) if result != tt.expected { t.Errorf("expected %q, got %q", tt.expected, result) } }) } }
-
Test Coverage
- Aim for >80% coverage
- Focus on critical paths and edge cases
- Don't sacrifice readability for coverage
For tests that modify system files:
func TestIntegration(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test in short mode")
}
// Use temporary files for testing
tmpFile := createTempHostsFile(t)
defer os.Remove(tmpFile)
// Run test with temporary file
}- Document all exported functions, types, and packages
- Use Go doc conventions
- Include examples for complex functions
// ParseHostsFile parses a hosts file and returns a structured representation.
// It handles both enabled and disabled entries, organizing them by category.
//
// Example:
// parser := hosts.NewParser("/etc/hosts")
// hostsFile, err := parser.Parse()
// if err != nil {
// return err
// }
func (p *Parser) Parse() (*HostsFile, error) { ... }- Update README.md for new features
- Add examples to EXAMPLES.md
- Update command help text
- Consider adding blog posts for major features
Update help text in cobra commands:
cmd := &cobra.Command{
Use: "add <ip> <hostname> [hostname...]",
Short: "Add a new hosts entry",
Long: `Add a new entry to the hosts file with the specified IP and hostnames.
The entry will be added to the specified category (default: custom) and can
include a comment for documentation purposes.`,
Example: ` # Add simple entry
hosts-manager add 127.0.0.1 myapp.local
# Add with category and comment
hosts-manager add 192.168.1.100 api.dev --category development --comment "Dev API"`,
}We follow Semantic Versioning:
MAJOR.MINOR.PATCH- Major: breaking changes
- Minor: new features, backwards compatible
- Patch: bug fixes, backwards compatible
-
Pre-release
# Update version in relevant files # Update CHANGELOG.md # Run full test suite make ci
-
Create Release
git tag -a v1.2.3 -m "Release v1.2.3" git push origin v1.2.3 -
Build Release Assets
make release # Cross-compile for all platforms make dist # Create distribution packages
-
GitHub Release
- Create GitHub release from tag
- Upload distribution packages
- Write release notes
- Questions: Open a GitHub issue with the "question" label
- Bugs: Open a GitHub issue with the "bug" label
- Features: Open a GitHub issue with the "enhancement" label
- Security: Email maintainers privately for security issues
Contributors are recognized in:
- CONTRIBUTORS.md file
- GitHub contributors page
- Release notes for significant contributions
Thank you for contributing to Hosts Manager!