# Agent Guidelines for my-log ## Build/Test/Lint Commands - Build: `make build` or `go build -o my-log` - Test all: `make test` (runs fmt + test with race + coverage) - Test single: `go test ./path/to/package -run TestName` - Format: `make fmt` or `go fmt ./...` - Coverage report: `make report` (generates cover.html) ## Code Style - **Module**: `codeberg.org/danjones000/my-log` - **Go version**: 1.21.5 - **Imports**: Standard library first, then external packages, then local packages. Use short aliases for common imports (e.g., `fp` for `path/filepath`, `mapst` for `mitchellh/mapstructure`) - **Formatting**: Always run `go fmt` before commits (included in test target) - **Types**: Use explicit types (e.g., `int64`, `float64`). Convert numbers appropriately when unmarshaling JSON - **Naming**: PascalCase for exported, camelCase for unexported. Use descriptive names - **Don't reinvent the wheel**: Use standard library functions (e.g., `slices.Contains` instead of custom contains functions) - **Error handling**: Return wrapped errors with context. Define custom errors in models/errors.go. Use `ErrorIs` for error checking - **Testing**: Use github.com/nalgeon/be. Table-driven tests with helper functions. Test both marshal/unmarshal for encoding types. Use `t.ArtifactDir()` instead of `t.TempDir()` and `t.Context()` instead of `context.Background()` - **Concurrency**: Use channels and goroutines with WaitGroups for parallel processing (see entry.go patterns) - **Comments**: Include license header on cmd files. Document exported functions and types ## Config System - Viper instance is stored in context using a custom key type (`confKeyType`) - Use `config.New(ctx, path)` to create a new viper instance - Use `config.RetrieveFromContext(ctx)` to get both viper and the unmarshaled Config struct - Formatters can use `v.Sub("formatters." + kind)` to get their own sub-config and unmarshal into their specific config struct - Test files must create viper instances and add them to context using `config.AddToContext` ## Git Commit Guidelines - **Format**: Prepend commit messages with a gitmoji emoji (see https://gitmoji.dev) - **Style**: Write detailed commit messages that explain what changed and why - **Examples**: `✨ Add JSON export functionality for log entries`, `🐛 Fix date parsing for RFC3339 timestamps`, `📝 Update README with configuration examples` ## Git Flow Workflow - **Main branches**: `stable` (production-ready), `develop` (integration branch) - **Development**: Always commit new features/fixes to `develop` branch or appropriate feature branches - **Branch prefixes**: - `feat/feature-name` - New features, merge to `develop` when complete - `bug/bug-name` - Bug fixes (non-urgent), merge to `develop` when complete - `hot/version` - Hotfixes for production issues, merge to **both** `stable` and `develop` - `rel/version` - Release preparation branches - **Version tags**: Prefix all version tags with `v` (e.g., `v1.0.2`, `v0.0.6`) - **Releases**: Update CHANGELOG.md with a summary of changes for each new version - **Never commit directly to**: `stable` branch (only merge from `rel/` or `hot/` branches) - **Before starting work**: Ensure you're on `develop` branch or create an appropriate feature branch from it ## Project Structure - `cmd/my-log/`: Main application entrypoint - `internal/testutil/bep`: Reusable test assertions to complement those used by github.com/nalgeon/be - `cli/`: Cobra commands (root, drop, config) - `models/`: Core types (Entry, Log, Meta) with marshal/unmarshal implementations - `config/`: TOML-based configuration with viper, env overrides, and context propagation - `formatters/`: Output formatters (plain, json, null) with their own sub-configs - `files/`: File operations (append) - `tools/`: Utilities (date parsing, string parsing, write buffers)