This guide outlines the best practices for Go development within this project, modeled after high-quality TUI applications.
- cmd/: Contains the main applications. Each subdirectory should be a main package (e.g.,
cmd/bv/main.go). - pkg/: Library code organized by domain. This project uses
pkg/for all packages:- pkg/ui/: User Interface components (Bubble Tea models, views).
- pkg/model/: Domain models and data structures.
- pkg/analysis/: Graph analysis and metrics computation.
- pkg/loader/: Beads file discovery and parsing.
- pkg/export/: Export functionality (Markdown, HTML, SQLite).
- tests/: End-to-end and integration tests.
- Formatting: Always use
gofmt(orgoimports). - Naming:
- Use
CamelCasefor exported identifiers. - Use
camelCasefor unexported identifiers. - Keep variable names short but descriptive (e.g.,
ifor index,ctxfor context). - Package names should be short, lowercase, and singular (e.g.,
model,ui,auth).
- Use
- Error Handling:
- Return errors as the last return value.
- Check errors immediately.
- Use
fmt.Errorfwith%wto wrap errors for context. - Don't panic unless it's a truly unrecoverable initialization error.
- Architecture: Follow The Elm Architecture (Model, View, Update) via
bubbletea. - Components: Break down complex UIs into smaller, reusable
tea.Modelcomponents (e.g.,ListView,DetailView,FilterBar). - Styling: Use
lipglossfor all styling. Define a centralstyles.goto maintain consistency (colors, margins, padding). - State: Keep the main model clean. Delegate update logic to sub-models.
- Config: Use struct-based configuration. Load from environment variables or config files (YAML/JSON).
- Data Access: separate data loading (Loader/Repository pattern) from the UI logic. The UI should receive data, not fetch it directly if possible.
- Write unit tests for logic-heavy packages.
- Use table-driven tests for parser/validator logic.
- Run tests with
go test ./....
- Use
go modfor dependency management. - specific versions should be pinned in
go.mod. - Vendor dependencies if necessary for offline builds, but standard
go modis usually sufficient.
- Add comments to exported functions and types (
// TypeName represents...). - Maintain a
README.mdwith installation and usage instructions.
- Use channels for communication between goroutines.
- Use
sync.Mutexfor protecting shared state if not using channels. - Avoid global state where possible.