5.1 KiB
Claude Development Guide for Miller
Project Overview
Miller is a command-line data processing tool for working with CSV, TSV, JSON, and other data formats. It's written in Go (v1.18+) and provides SQL-like operations on data.
Initial Setup
Setting Up staticcheck
The make staticcheck target requires the staticcheck tool. To set it up:
go install honnef.co/go/tools/cmd/staticcheck@latest
This installs staticcheck to ~/go/bin/ (the default Go binaries directory). For make staticcheck to work, you need ~/go/bin in your PATH.
Add to your shell profile (.bashrc, .zshrc, or equivalent):
export PATH="$PATH:$HOME/go/bin"
Verify the installation:
staticcheck -version
If this works, you can use make staticcheck without any further setup.
Setting Up golangci-lint
CI runs golangci-lint (config in .golangci.yml) on every push and PR via
.github/workflows/golangci-lint.yml. To run it locally, install the version
matching CI (currently v2.12.2) per the
official instructions, e.g.:
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.12.2
This also installs to ~/go/bin/, so the same PATH addition above covers it.
Verify the installation:
golangci-lint --version
Build & Test
Building
make build # Build the mlr executable
make quiet # Build silently (no output messages)
Testing
make check # Run all tests (unit + regression)
make unit-test # Run unit tests only
make regression-test # Run regression tests only
make bench # Run benchmarks
Code Quality
make fmt # Format code with go fmt
make staticcheck # Run static analysis (see Initial Setup section above)
make lint # Run golangci-lint, same invocation as CI (see Initial Setup section above)
make lint runs golangci-lint run ./cmd/mlr ./pkg/..., matching
.github/workflows/golangci-lint.yml exactly, so a clean local run means CI's
lint job will pass too. It is not part of make check or make dev, so run
it explicitly before pushing.
Full Developer Workflow
make dev # Format, build, test, generate docs (comprehensive check before pushing)
Project Structure
cmd/mlr- Main Miller executable entry pointpkg/- Core library code organized by functionalitypkg/lib/- Utility librariespkg/scan/- Input scanningpkg/mlrval/- Miller value typespkg/bifs/- Built-in functionspkg/input/- Input format handlers
regression_test.go- Regression test suitedocs/- Documentation (Markdown with live code samples)man/- Man page generation
Development Conventions
Code Style
- Follow Go conventions and
go fmtoutput - Use meaningful variable and function names
- Keep functions focused and testable
Testing
- Add unit tests for new functionality in
pkg/*/directories - Use
go testfor unit tests - Run
make regression-testfor integration testing - The
mlr regtestcommand provides more control for interactive debugging
Documentation
- Update relevant
.md.infiles indocs/src/when adding features - These are processed into live documentation with actual code examples
- Run
make devto rebuild documentation
Git Workflow
- Create descriptive commit messages
- Reference issue numbers when fixing bugs or implementing features
- Test locally with
make checkbefore committing - For major changes, run
make devto ensure docs and tests pass
Key Dependencies
Miller uses the Go standard library. Check go.mod for specific versions.
Common Tasks
Adding a New Built-in Function
- Implement in appropriate package (likely
pkg/bifs/) - Add unit tests alongside
- Update documentation in
docs/src/ - Run
make checkto verify
Fixing a Bug
- Create a minimal test case (unit test or regression test)
- Fix the code
- Verify with
make check - Commit with reference to issue number
Performance Optimization
- Run
make benchto establish baseline - Make changes
- Run benchmarks again to measure improvement
- Consider adding permanent benchmark in test files
Documentation Building
Documentation is built from .md.in template files that contain live code samples executed via Miller itself. When you make changes that affect command output or behavior, you may need to update these templates and rebuild docs with make -C docs/src forcebuild.
Before Pushing
Always run:
make dev
make lint
make dev ensures code formatting, builds successfully, passes all tests, and documentation is up to date. make lint is separate (not part of make dev/make check) and mirrors the CI lint job.