Thank you for your interest in contributing to pgcov! This document provides guidelines and instructions for setting up your development environment and contributing to the project.
- Development Environment Setup
- Building the Project
- Running Tests
- Code Style
- Submitting Changes
- Troubleshooting
-
Go 1.21+
- Download from golang.org
- Verify:
go version
-
C Compiler (required for CGO)
Linux:
# Ubuntu/Debian sudo apt-get install build-essential # Fedora/RHEL sudo dnf install gcc # Arch Linux sudo pacman -S base-devel
macOS:
# Install Xcode Command Line Tools xcode-select --installWindows:
-
Download and install MSYS2
-
Open MSYS2 terminal:
pacman -Syu pacman -S mingw-w64-x86_64-gcc
-
Add
C:\msys64\mingw64\binto your system PATH
-
-
Docker (for integration tests)
- Linux: Docker Engine
- macOS/Windows: Docker Desktop
- Verify:
docker ps
-
PostgreSQL (optional, for manual testing)
- Version 13 or later
- Integration tests use Docker, but you may want a local instance for development
# Fork the repository on GitHub first, then:
git clone https://github.com/YOUR_USERNAME/pgcov.git
cd pgcov
# Add upstream remote
git remote add upstream https://github.com/cybertec-postgresql/pgcov.git
# Install dependencies
go mod download# Set CGO environment
export CGO_ENABLED=1
# Development build
go build -o pgcov ./cmd/pgcov
# Release build (optimized, smaller binary)
go build -ldflags="-s -w" -o pgcov ./cmd/pgcov
# Verify the build
./pgcov --version# Set CGO environment
$env:CGO_ENABLED = "1"
$env:CC = "C:\msys64\mingw64\bin\gcc.exe"
$env:PATH = "$env:PATH;C:\msys64\mingw64\bin"
# Development build
go build -o pgcov.exe .\cmd\pgcov
# Release build
go build -ldflags="-s -w" -o pgcov.exe .\cmd\pgcov
# Verify the build
.\pgcov.exe --versionCreate a build script for convenience:
Linux/macOS (build.sh):
#!/bin/bash
set -e
export CGO_ENABLED=1
echo "Building pgcov..."
go build -ldflags="-s -w" -o pgcov ./cmd/pgcov
echo "Build complete: $(./pgcov --version)"Windows (build.ps1):
$ErrorActionPreference = "Stop"
$env:CGO_ENABLED = "1"
$env:CC = "C:\msys64\mingw64\bin\gcc.exe"
$env:PATH = "$env:PATH;C:\msys64\mingw64\bin"
Write-Host "Building pgcov..."
go build -ldflags="-s -w" -o pgcov.exe .\cmd\pgcov
Write-Host "Build complete: $(.\pgcov.exe --version)"# Linux/macOS
export CGO_ENABLED=1
go test ./...
# Windows (PowerShell)
$env:CGO_ENABLED = "1"
$env:CC = "C:\msys64\mingw64\bin\gcc.exe"
$env:PATH = "$env:PATH;C:\msys64\mingw64\bin"
go test .\...Linux/macOS:
# Enable CGO
export CGO_ENABLED=1
# All tests with verbose output
go test -v ./...
# Integration tests only
go test -v ./internal -run TestEndToEndWithTestcontainers
# Run tests with race detection
go test -race ./...
# Run tests with coverage
go test -cover -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
# Run tests with timeout (important for integration tests)
go test -timeout 5m ./...
# Run tests in parallel
go test -parallel 4 ./...
# Clean test cache (force re-run)
go clean -testcache
go test ./...Windows (PowerShell):
# Enable CGO
$env:CGO_ENABLED = "1"
$env:CC = "C:\msys64\mingw64\bin\gcc.exe"
$env:PATH = "$env:PATH;C:\msys64\mingw64\bin"
# All tests with verbose output
go test -v .\...
# Integration tests only
go test -v .\internal -run TestEndToEndWithTestcontainers
# Run tests with coverage
go test -cover -coverprofile=coverage.out .\...
go tool cover -html=coverage.out -o coverage.html
# Run tests with timeout
go test -timeout 5m .\...
# Clean test cache
go clean -testcache
go test .\...-
Unit tests: Fast, no external dependencies
internal/discovery/*_test.gointernal/parser/*_test.gointernal/coverage/*_test.go
-
Integration tests: Use testcontainers (require Docker)
internal/integration_test.go- Full end-to-end workflow
Integration tests use testcontainers-go to spin up a real PostgreSQL instance:
-
Docker must be running
docker ps # Should not error -
Sufficient Docker resources
- Memory: At least 2GB available
- Disk: At least 1GB free space
-
Network access
- Tests pull
postgres:16-alpineimage - Tests pull
testcontainers/ryuk:0.13.0image
- Tests pull
# Linux/macOS
export CGO_ENABLED=1
# Run only discovery tests
go test -v ./internal/discovery
# Run only a specific test function
go test -v ./internal -run TestEndToEndWithTestcontainers/Discovery
# Run tests matching a pattern
go test -v ./... -run TestParse
# Skip integration tests (no Docker required)
go test -v -short ./...# Format all code
go fmt ./...
# Check for suspicious constructs
go vet ./...
# Install and run staticcheck
go install honnef.co/go/tools/cmd/staticcheck@latest
staticcheck ./...- Follow standard Go idioms and best practices
- Use
gofmtfor formatting - Write clear, self-documenting code
- Add comments for exported functions and types
- Keep functions small and focused
- Use meaningful variable names
-
Error Handling
- Always check and handle errors
- Wrap errors with context:
fmt.Errorf("operation failed: %w", err) - Use custom error types in
internal/errorspackage
-
Testing
- Write tests for new features
- Maintain or improve code coverage
- Use table-driven tests where appropriate
- Test error paths, not just happy paths
-
Documentation
- Update README.md for user-facing changes
- Add godoc comments for exported symbols
- Include examples in documentation
-
Commits
- Write clear, descriptive commit messages
- Use conventional commit format:
type(scope): description - Example:
feat(parser): add support for SQL functions - Types:
feat,fix,docs,test,refactor,chore
-
Ensure all tests pass
go test ./... -
Format your code
go fmt ./... go vet ./...
-
Update documentation
- Update README.md if adding features
- Add/update godoc comments
- Update CHANGELOG.md (if exists)
-
Test your changes manually
# Build and test the binary go build -o pgcov ./cmd/pgcov ./pgcov run ./testdata/simple
-
Create a feature branch
git checkout -b feature/your-feature-name
-
Make your changes
- Keep commits focused and atomic
- Write clear commit messages
-
Push to your fork
git push origin feature/your-feature-name
-
Open a Pull Request
- Provide a clear description
- Reference any related issues
- Include screenshots/examples if applicable
-
Address review feedback
- Make requested changes
- Push updates to the same branch
Error: gcc: command not found
# Linux
sudo apt-get install build-essential
# macOS
xcode-select --install
# Windows - ensure MSYS2 MinGW64 is in PATHError: cannot find -lpthread
# Linux - install development libraries
sudo apt-get install build-essentialWindows: Missing DLL errors
# Add MinGW bin to PATH
$env:PATH = "$env:PATH;C:\msys64\mingw64\bin"
# Or permanently via System Properties > Environment VariablesIntegration test fails: "Cannot connect to Docker"
# Verify Docker is running
docker ps
# Linux - ensure user is in docker group
sudo usermod -aG docker $USER
# Log out and back inIntegration test fails: "Failed to pull image"
# Pull images manually
docker pull postgres:16-alpine
docker pull testcontainers/ryuk:0.13.0Test timeout
# Increase timeout
go test -timeout 10m ./...Error: package github.com/pganalyze/pg_query_go/v6: cannot find package
# Download missing dependencies
go mod download
go mod tidy- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: Check README.md and code comments
By contributing, you agree that your contributions will be licensed under the MIT License.