description: How to build, test, and contribute to go-ansible.
---
# Development
## Prerequisites
- **Go 1.26+** (the module requires Go 1.26 features)
- SSH access to a test host (for integration testing, not required for unit tests)
## Building
The package is a library -- there is no standalone binary. The CLI integration lives in `cmd/ansible/` and is compiled as part of the `core` CLI binary.
```bash
# Verify the module compiles
go build ./...
# If working within the Go workspace
go work sync
```
## Running Tests
```bash
# Run all tests
go test ./...
# Run tests with race detection
go test -race ./...
# Run a specific test
go test -run TestParsePlaybook_Good_SimplePlay
# Run tests with verbose output
go test -v ./...
```
The test suite uses a mock SSH client infrastructure (`mock_ssh_test.go`) to test module handlers without requiring real SSH connections. Tests are organised into separate files by category:
The package is intentionally flat -- a single `ansible` package with no sub-packages. This keeps the API surface small and avoids circular dependencies.
When adding new functionality:
- **New module**: Add a `module{Name}` method to `Executor` in `modules.go`, add the case to the `executeModule` switch statement, and add the module name to `KnownModules` in `types.go` (both FQCN and short forms). Write tests in the appropriate `modules_*_test.go` file.
- **New parser feature**: Extend the relevant `Parse*` method in `parser.go`. If it involves new YAML keys on `Task`, update the `knownKeys` map in `UnmarshalYAML` to prevent them from being mistakenly identified as module names.
- **New type**: Add to `types.go` with appropriate YAML and JSON struct tags.
## Coding Standards
- **UK English** in comments and documentation (colour, organisation, centre).
- All functions must have typed parameters and return types.
- Use `log.E(scope, message, err)` from `go-log` for contextual errors in SSH and parser code.
- Use `fmt.Errorf` with `%w` for wrapping errors in the executor.
- Test assertions use `testify/assert` (soft) and `testify/require` (hard, stops test on failure).
## Adding a New Module
Here is a walkthrough for adding a hypothetical `ansible.builtin.hostname` module (which already exists -- this is illustrative):