Developer Getting Started
Welcome to govman development! This guide will help you set up your development environment and make your first contribution.
Prerequisites
Required
- Go 1.25 or later - Install Go
- Git - Version control
- Make - Build automation (optional but recommended)
Recommended
- Docker - For testing installation scripts
- VS Code - With Go extension
- Code editor with Go support
Quick Start
1. Clone the Repository
git clone https://github.com/justjundana/govman.git
cd govman
2. Install Dependencies
go mod download
go mod verify
3. Build the Project
# Using Make
make build
# Or directly with Go
go build -o govman ./cmd/govman
4. Run Tests
# Run all tests
go test ./...
# With verbose output
go test -v ./...
# With coverage
go test -cover ./...
5. Run govman Locally
./govman --version
./govman --help
Development Workflow
Building
# Development build
make build
# Build for all platforms
make build-all
# Clean build artifacts
make clean
Testing
# Unit tests
make test
# Integration tests
make test-integration
# Coverage report
make test-coverage
# Run specific test
go test -v ./internal/manager -run TestInstall
Code Quality
# Format code
make fmt
# Or: go fmt ./...
# Lint code
make lint
# Or: golangci-lint run
# Vet code
go vet ./...
Project Commands
Makefile Targets
make help # Show all available targets
make build # Build the binary
make test # Run tests
make fmt # Format code
make lint # Run linters
make clean # Clean build artifacts
make install # Install to ~/.govman/bin
make uninstall # Remove from ~/.govman/bin
Development Environment
VS Code Setup
Create .vscode/settings.json:
{
"go.lintTool": "golangci-lint",
"go.lintOnSave": "workspace",
"go.formatTool": "gofmt",
"editor.formatOnSave": true,
"go.useLanguageServer": true,
"go.testFlags": ["-v"],
"go.coverOnSave": true
}
Debugging
Create .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug govman",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "${workspaceFolder}/cmd/govman",
"args": ["list", "--verbose"]
}
]
}
Making Changes
1. Create a Branch
git checkout -b feature/my-new-feature
# Or
git checkout -b fix/bug-description
2. Make Your Changes
Follow the Project Structure to understand the codebase.
3. Write Tests
Every new feature should include tests:
func TestMyNewFeature(t *testing.T) {
// Arrange
expected := "value"
// Act
result := MyNewFeature()
// Assert
if result != expected {
t.Errorf("Expected %s, got %s", expected, result)
}
}
4. Run Tests
go test ./...
5. Commit Your Changes
Follow Conventional Commits:
git add .
git commit -m "feat: add new awesome feature"
# Or
git commit -m "fix: resolve issue with version switching"
6. Push and Create PR
git push origin feature/my-new-feature
Then create a Pull Request on GitHub.
Code Style Guidelines
Go Code
- Follow Effective Go
- Use
gofmtfor formatting - Keep functions small and focused
- Write descriptive variable names
- Add comments for exported functions
Example
// Manager handles Go version management operations.
// It coordinates between configuration, downloads, and shell integration.
type Manager struct {
config *config.Config
downloader *downloader.Downloader
shell shell.Shell
}
// New creates a Manager with the provided configuration.
// It initializes a downloader and detects the user's shell.
func New(cfg *config.Config) *Manager {
return &Manager{
config: cfg,
downloader: downloader.New(cfg),
shell: shell.Detect(),
}
}
Comments
- Add package documentation
- Document exported types and functions
- Explain complex logic
- Use TODO for future improvements
// TODO: Add support for custom mirror URLs
// TODO(username): Optimize caching strategy
Testing Guidelines
Unit Tests
- Test each function in isolation
- Use table-driven tests for multiple cases
- Mock external dependencies
func TestCompareVersions(t *testing.T) {
tests := []struct {
name string
v1 string
v2 string
expected int
}{
{"equal versions", "1.21.5", "1.21.5", 0},
{"v1 greater", "1.21.5", "1.20.12", 1},
{"v2 greater", "1.20.12", "1.21.5", -1},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := CompareVersions(tt.v1, tt.v2)
if result != tt.expected {
t.Errorf("Expected %d, got %d", tt.expected, result)
}
})
}
}
Integration Tests
Place in *_integration_test.go files:
//go:build integration
// +build integration
func TestInstallIntegration(t *testing.T) {
// Test actual installation
}
Run with:
go test -tags=integration ./...
Debugging Tips
Print Debugging
import "log"
log.Printf("Debug: value = %v", value)
Delve Debugger
# Install delve
go install github.com/go-delve/delve/cmd/dlv@latest
# Debug govman
dlv debug ./cmd/govman -- list
Verbose Mode
Use the --verbose flag to see detailed output:
./govman --verbose install 1.21.5
Common Development Tasks
Adding a New Command
- Create command file in
internal/cli/:
// internal/cli/mynewcmd.go
package cli
func newMyNewCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "mynew",
Short: "Description",
RunE: func(cmd *cobra.Command, args []string) error {
// Implementation
return nil
},
}
return cmd
}
- Register in
internal/cli/command.go:
func addCommands() {
rootCmd.AddCommand(
// ... existing commands
newMyNewCmd(),
)
}
Adding Configuration Option
- Add to
internal/config/config.go:
type Config struct {
// ... existing fields
MyNewOption string `mapstructure:"my_new_option"`
}
- Add to
setDefaults():
func (c *Config) setDefaults() {
// ... existing defaults
c.MyNewOption = "default_value"
}
Adding a Shell
- Create shell implementation in
internal/shell/:
type MyShell struct{}
func (s *MyShell) Name() string { return "myshell" }
func (s *MyShell) DisplayName() string { return "My Shell" }
func (s *MyShell) ConfigFile() string { return "~/.myshellrc" }
// ... implement other methods
- Add to
Detect()ininternal/shell/shell.go
Release Process
Creating a Release
- Update version in
internal/version/version.go - Update
CHANGELOG.md - Create git tag:
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0
- GitHub Actions will build and publish
Resources
- Project Structure - Codebase organization
- Architecture - System design
- Dependencies - External packages
- Data Flow - How data moves through the system
Getting Help
- 💬 GitHub Discussions
- 🐛 Issue Tracker
- 📖 Read the code - It's well-documented!
Next Steps
- Read Project Structure
- Explore Architecture
- Check Open Issues
- Make your first contribution!
Happy coding! 🚀