Contributing Guidelines
Relevant source files
The following files were used as context for generating this wiki page:
Docktree is a Go-based CLI designed to manage Docker Compose services across multiple Git worktrees by providing isolation for ports, container names, and volumes. These guidelines outline the technical standards, development workflows, and project structures required for contributors to successfully propose changes to the codebase.
The project emphasizes technical accuracy, automated testing (specifically regarding concurrency and race conditions), and maintaining a clean library/CLI separation. Contributors are expected to follow the established project layout and utilize the provided task runner for consistent builds and linting.
Sources: CONTRIBUTING.md:1-12, README.md:1-12
Project Architecture and Layout
The repository follows a standard Go project structure designed to separate the entry point from core logic. This ensures that the library code under internal/ can be tested independently of the CLI interface.
| Directory | Purpose |
|---|---|
cmd/docktree/ | CLI entry point and main executable logic. |
internal/ | Core library code (Compose handling, port allocation, TUI, config). |
tests/ | Integration and end-to-end smoke tests. |
testdata/ | Static fixtures and mock Compose files used by tests. |
Formula/ | Homebrew distribution metadata. |
skills/ | Markdown definitions for AI agent integration. |
Sources: CONTRIBUTING.md:46-52, README.md:43-50
Development Workflow
Contributors should use the just task runner to manage common development lifecycle tasks. The following diagram illustrates the standard workflow for preparing a contribution:
The main branch is protected, requiring all changes to land via pull requests with at least one approving review from the code owner (@Bnjoroge1).
Sources: CONTRIBUTING.md:54-62, CONTRIBUTING.md:103-113
Technical Standards and Conventions
Testing Requirements
The project enforces high testing standards, particularly for behavior under contention. Contributions must include tests for new behaviors and bug fixes.
- Unit Tests: Located under
internal/.... - Race Detection: CI runs with
-race -count=1 ./.... - Concurrency: Integration tests (e.g.,
TestConcurrentUp) verify that port allocation and state files remain consistent under simultaneous execution. - Fixtures: Use
testdata/fixtures instead of live Docker where possible; mocks are discouraged in favor of real fixtures.
Sources: CONTRIBUTING.md:73-86, tests/concurrent_smoke_test.go:20-35
Code Quality and Linting
Static analysis is enforced via golangci-lint and go vet. The codebase also requires strictly tidy Go modules.
- Formatting must match
gofmt -w .. - Modules must be tidied via
go mod tidy. - Commit subjects should be imperative (e.g., "Add port range override") and under 72 characters.
Sources: CONTRIBUTING.md:88-97
CLI and Configuration Logic
JSON Output for AI and Automation
Docktree is "agent-native," meaning native commands MUST support a --json global flag. This flag is handled before the subcommand and ensures that stdout contains exactly one JSON object.
Native commands that support this include status, ports, volumes, clean, sync, and init. Docker Compose passthroughs (like build or logs) do not follow this JSON envelope and return raw Docker output.
Sources: internal/cli/render.go:15-30, README.md:38-41
Configuration Management
The docktree.yml file is the central configuration point. The internal/config package handles loading, merging defaults, and validation.
type Config struct {
Compose ComposeConfig `yaml:"compose"`
Setup SetupConfig `yaml:"setup"`
Shared SharedConfig `yaml:"shared,omitempty"`
Volumes VolumeSetConfig `yaml:"volumes"`
Ports PortsConfig `yaml:"ports"`
State StateConfig `yaml:"state"`
}
- Defaults: Port range defaults to
41000-49999and bind host to127.0.0.1. - Validation:
ValidateSharedensures that services marked as shared do not conflict with shared volumes and that tenancy modes (e.g.,full_share,per_database) are valid for the service kind.
Sources: internal/config/config.go:12-23, internal/config/config.go:111-125, internal/config/config.go:189-200
Initialization and Scaffolding
The init subcommand provides a mechanism to bootstrap a project. It scans for existing Compose files and identifies "shareable" services (PostgreSQL, MySQL, Redis, etc.).
Scaffolding Flow
The internal/cli/init.go file contains the logic for building proposals and identifying "Secrets Wrappers" (like Infisical or Doppler) that might interfere with environment variable injection.
Sources: internal/cli/init.go:56-85, internal/cli/init.go:275-298
Summary
Contributors should focus on maintaining the isolation guarantees provided by the CLI while ensuring that all new features respect the --json output requirement and pass concurrency-stress integration tests. By adhering to the just workflow and ensuring high test coverage within the internal/ packages, developers can contribute to the stability and performance of Docktree across diverse development environments.
Sources: CONTRIBUTING.md:120-123, README.md:73-75