- **Go workspace** -- This module is part of a Go workspace at `~/Code/go.work`. Local development of sibling modules (go-io, config, go-i18n, cli) requires the workspace file.
- **QEMU** -- `qemu-system-x86_64` for running LinuxKit images on any platform.
- **Hyperkit** -- macOS-only alternative hypervisor.
- **LinuxKit** -- For building images from templates (`linuxkit build`).
- **GitHub CLI** (`gh`) -- For the GitHub image source.
## Running tests
```bash
# All tests
go test ./...
# With race detector
go test -race ./...
# Single test by name
go test -run TestState_Add_Good ./...
# Single package
go test ./sources/
go test ./devenv/
```
Tests use `testify` for assertions. Most tests are self-contained and do not require a running hypervisor -- they test command construction, state management, template parsing, and configuration loading in isolation.
## Test naming convention
Tests follow a `_Good`, `_Bad`, `_Ugly` suffix pattern:
cmd_templates.go # templates, templates show, templates vars commands
```
## Coding standards
- **UK English** in all strings, comments, and documentation (colour, organisation, honour).
- **Strict typing** -- All function parameters and return values are typed. No `interface{}` without justification.
- **Error wrapping** -- Use `fmt.Errorf("context: %w", err)` for all error returns.
- **`io.Medium` abstraction** -- File system operations go through `io.Medium` (from `go-io`) rather than directly calling `os` functions. This enables testing with mock file systems. The `io.Local` singleton is used for real file system access.
- **Compile-time interface checks** -- Use `var _ Interface = (*Impl)(nil)` to verify implementations at compile time (see `sources/cdn.go` and `sources/github.go`).
- **Context propagation** -- All operations that might block accept a `context.Context` as their first parameter.
## Adding a new hypervisor
1. Create a new struct implementing the `Hypervisor` interface in `hypervisor.go`: