Development¶
This guide covers setting up a development environment, running tests, and contributing to ZipReport Go.
Prerequisites¶
- Go 1.24+
- golangci-lint (for linting)
- zipreport-server (for testing PDF generation)
Getting Started¶
# Clone the repository
git clone https://github.com/zipreport/zipreport-go
cd zipreport-go
# Download dependencies
go mod download
# Build CLI
make build
# Run tests
make test
Makefile Targets¶
| Target | Description |
|---|---|
make test |
Run tests |
make test-verbose |
Run tests with verbose output |
make test-coverage |
Run tests with coverage report |
make lint |
Run golangci-lint |
make build |
Build CLI to bin/ |
make install |
Install CLI to GOPATH |
make clean |
Remove build artifacts |
Running Tests¶
All Tests¶
With Coverage¶
make test-coverage
# or
go test -coverprofile=coverage.out ./pkg/...
go tool cover -func=coverage.out
View HTML Coverage¶
Specific Package¶
Verbose Output¶
Linting¶
Project Structure¶
zipreport-go/
├── cmd/zipreport/ # CLI application
│ ├── main.go # Entry point
│ ├── build.go # build command
│ ├── debug.go # debug command
│ ├── info.go # info command
│ ├── list.go # list command
│ └── version.go # version command
├── pkg/
│ ├── api/ # High-level API
│ │ ├── zipreport.go # ZipReport, MIMEReport
│ │ └── zipreport_test.go
│ ├── fileutils/ # File system abstractions
│ │ ├── interface.go # FsInterface definition
│ │ ├── zipfs.go # In-memory ZIP filesystem
│ │ ├── diskfs.go # Disk-based filesystem
│ │ ├── pathcache.go # Path caching
│ │ └── *_test.go
│ ├── processor/ # Rendering backends
│ │ ├── interface.go # Backend interfaces
│ │ ├── backend_server.go # zipreport-server backend
│ │ ├── backend_local.go # Local backend (stub)
│ │ ├── mime.go # MIME processor
│ │ ├── zipreport.go # ZipReportProcessor
│ │ └── *_test.go
│ ├── report/ # Report types
│ │ ├── reportfile.go # ReportFile type
│ │ ├── job.go # ReportJob configuration
│ │ ├── const.go # Constants
│ │ ├── loader.go # Report loading
│ │ ├── builder.go # .zpt building
│ │ └── *_test.go
│ └── template/ # Template rendering
│ ├── render.go # MiyaRender
│ ├── environment.go # EnvironmentWrapper
│ ├── filters.go # Built-in filters
│ ├── loader.go # Template loader
│ └── *_test.go
├── examples/ # Standalone examples
├── docs/ # Documentation
└── output/ # Example outputs
Testing Guidelines¶
Test Coverage¶
Target: 75%+ for library code in pkg/.
Current coverage can be checked with:
Test Patterns¶
Use table-driven tests:
func TestFunction(t *testing.T) {
tests := []struct {
name string
input string
expected string
}{
{"empty", "", ""},
{"simple", "hello", "HELLO"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := Function(tt.input)
if result != tt.expected {
t.Errorf("got %q, want %q", result, tt.expected)
}
})
}
}
Mocking¶
Mock external dependencies:
// Mock HTTP server
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/pdf")
w.Write([]byte("%PDF-1.4..."))
}))
defer server.Close()
backend := processor.NewServerBackend(server.URL, "test-key")
Adding New Features¶
- Create a branch
- Write tests first
-
Implement feature
-
Run tests and linting
-
Update documentation
-
Create pull request
Code Style¶
- Follow standard Go conventions
- Run
golangci-lintbefore committing - Keep functions focused and small
- Prefer explicit error handling over panics
- Use meaningful variable names
- Add comments for exported functions
Commit Messages¶
Use clear, descriptive commit messages:
Add currency filter for template rendering
- Implement currency filter with locale support
- Add tests for various number formats
- Update documentation
Pull Request Process¶
- Ensure tests pass:
make test - Ensure linting passes:
make lint - Update documentation if needed
- Add tests for new functionality
- Request review
CI/CD¶
GitHub Actions runs on every push and pull request:
- Test - Runs all tests with coverage
- Lint - Runs golangci-lint
- Build Check - Builds for all platforms
Releasing¶
Releases are created via GitHub Actions when a tag is pushed:
This triggers:
- Building binaries for all platforms
- Creating GitHub release with binaries
- Updating Go package registry