- Add package comment to cmd/bd/dep.go - Change directory permissions from 0755 to 0750 in init.go - Simplify getNextID signature (remove unused error return) - Configure golangci-lint exclusions for false positives - Document linting policy in LINTING.md The remaining ~100 lint warnings are documented false positives: - 73 errcheck: deferred cleanup (idiomatic Go) - 17 revive: Cobra interface requirements and naming choices - 7 gosec: false positives on validated SQL and user file paths - 2 dupl: acceptable test code duplication - 1 goconst: test constant repetition See LINTING.md for full rationale. Contributors should focus on avoiding NEW issues rather than the documented baseline. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
6.0 KiB
Contributing to bd
Thank you for your interest in contributing to bd! This document provides guidelines and instructions for contributing.
Development Setup
Prerequisites
- Go 1.25 or later
- Git
- (Optional) golangci-lint for local linting
Getting Started
# Clone the repository
git clone https://github.com/steveyegge/beads
cd beads
# Build the project
go build -o bd ./cmd/bd
# Run tests
go test ./...
# Run with race detection
go test -race ./...
# Build and install locally
go install ./cmd/bd
Project Structure
beads/
├── cmd/bd/ # CLI entry point and commands
├── internal/
│ ├── types/ # Core data types (Issue, Dependency, etc.)
│ └── storage/ # Storage interface and implementations
│ └── sqlite/ # SQLite backend
├── .golangci.yml # Linter configuration
└── .github/workflows/ # CI/CD pipelines
Running Tests
# Run all tests
go test ./...
# Run tests with coverage
go test -v -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
# Run specific package tests
go test ./internal/storage/sqlite -v
# Run tests with race detection
go test -race ./...
Code Style
We follow standard Go conventions:
- Use
gofmtto format your code (runs automatically in most editors) - Follow the Effective Go guidelines
- Keep functions small and focused
- Write clear, descriptive variable names
- Add comments for exported functions and types
Linting
We use golangci-lint for code quality checks:
# Install golangci-lint
brew install golangci-lint # macOS
# or
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
# Run linter
golangci-lint run ./...
Note: The linter currently reports ~100 warnings. These are documented false positives and idiomatic Go patterns (deferred cleanup, Cobra interface requirements, etc.). See LINTING.md for details. When contributing, focus on avoiding new issues rather than the baseline warnings.
CI will automatically run linting on all pull requests.
Making Changes
Workflow
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Make your changes
- Add tests for new functionality
- Run tests and linter locally
- Commit your changes with clear messages
- Push to your fork
- Open a pull request
Commit Messages
Write clear, concise commit messages:
Add cycle detection for dependency graphs
- Implement recursive CTE-based cycle detection
- Add tests for simple and complex cycles
- Update documentation with examples
Pull Requests
- Keep PRs focused on a single feature or fix
- Include tests for new functionality
- Update documentation as needed
- Ensure CI passes before requesting review
- Respond to review feedback promptly
Testing Guidelines
- Write table-driven tests when testing multiple scenarios
- Use descriptive test names that explain what is being tested
- Clean up resources (database files, etc.) in test teardown
- Use
t.Run()for subtests to organize related test cases
Example:
func TestIssueValidation(t *testing.T) {
tests := []struct {
name string
issue *types.Issue
wantErr bool
}{
{
name: "valid issue",
issue: &types.Issue{Title: "Test", Status: types.StatusOpen, Priority: 2},
wantErr: false,
},
{
name: "missing title",
issue: &types.Issue{Status: types.StatusOpen, Priority: 2},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.issue.Validate()
if (err != nil) != tt.wantErr {
t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
Documentation
- Update README.md for user-facing changes
- Update relevant .md files in the project root
- Add inline code comments for complex logic
- Include examples in documentation
Feature Requests and Bug Reports
Reporting Bugs
Include in your bug report:
- Steps to reproduce
- Expected behavior
- Actual behavior
- Version of bd (
bd versionif implemented) - Operating system and Go version
Feature Requests
When proposing new features:
- Explain the use case
- Describe the proposed solution
- Consider backwards compatibility
- Discuss alternatives you've considered
Code Review Process
All contributions go through code review:
- Automated checks (tests, linting) must pass
- At least one maintainer approval required
- Address review feedback
- Maintainer will merge when ready
Development Tips
Testing Locally
# Build and test your changes quickly
go build -o bd ./cmd/bd && ./bd init --prefix test
# Test specific functionality
./bd create "Test issue" -p 1 -t bug
./bd dep add test-2 test-1
./bd ready
Database Inspection
# Inspect the SQLite database directly
sqlite3 .beads/test.db
# Useful queries
SELECT * FROM issues;
SELECT * FROM dependencies;
SELECT * FROM events WHERE issue_id = 'test-1';
Debugging
Use Go's built-in debugging tools:
# Run with verbose logging
go run ./cmd/bd -v create "Test"
# Use delve for debugging
dlv debug ./cmd/bd -- create "Test issue"
Release Process
(For maintainers)
- Update version in code
- Update CHANGELOG.md
- Tag release:
git tag v0.x.0 - Push tag:
git push origin v0.x.0 - GitHub Actions will build and publish
Questions?
License
By contributing, you agree that your contributions will be licensed under the MIT License.
Code of Conduct
Be respectful and professional in all interactions. We're here to build something great together.
Thank you for contributing to bd! 🎉