| name | ansible-dev-setup |
| description | Generate and manage cross-platform Ansible playbooks for development environment setup across macOS, Linux, and Termux. Use when working with development environment automation, package installation configuration, or Ansible playbook generation. |
Ansible Development Setup Generator
This skill helps you work with the Ansible-based development environment setup system in this repository, which generates playbooks for installing development tools across multiple platforms.
Overview
The repository contains a Go-based generator that creates Ansible playbooks for setting up development environments consistently across:
- macOS (using Homebrew)
- Debian/Ubuntu (using apt with PPA support)
- Termux (Android terminal with pkg)
The generator is located in devtools/setup-dev/ansible/ and consists of:
generate_packages.go- Main generator and entry pointtypes.go- Core data structures and interfacesinstall_methods.go- Platform-specific installation method implementationstemplates.go- Ansible playbook templatespackages_data.go- Package and tool definitions
Key Concepts
Package Types
PackageData: Traditional system packages installed via platform package managers (apt, brew, pkg)
- Supports different package names per platform
- Supports Ubuntu PPAs and Homebrew taps
- Example: emacs, git, curl
PlatformSpecificTool: Development tools with platform-specific installation methods
- Uses unified
InstallMethodinterface - Can use different installation approaches per platform
- Example: starship (brew on macOS, cargo on Debian, pkg on Termux)
- Uses unified
Installation Methods
The system supports multiple installation methods via the InstallMethod interface:
PackageInstallMethod- System package managers (apt, yum, dnf)BrewInstallMethod- Homebrew with tap and options supportTermuxPkgInstallMethod- Termux pkg commandPipInstallMethod- Python pip packagesGoInstallMethod- Go install with version checkingCargoInstallMethod- Rust cargo with cargo-update integrationNpmInstallMethod- Node.js npm global packagesUvInstallMethod- Python uv toolShellInstallMethod- Custom shell commands with version checking
Platform-Specific Installation Strategy
The generator follows best practices for each platform:
- Termux: Strongly prefer
pkgdue to Termux's unconventional setup requiring patches - Debian/Ubuntu: Prefer alternative methods when packages are outdated; use PPAs for actively developed software
- Python packages: Prefer
uvoverpip(faster, better dependency resolution) - Go packages: Use
go installwith automatic version checking and upgrade logic - macOS: Use Homebrew with tap and option support
Common Tasks
Adding a New Package
To add a system package that uses platform package managers:
- Add to the
packagesarray inpackages_data.go:
{command: "your-tool", debianPkgName: "debian-name", termuxPkgName: "termux-name", brewPkgName: "brew-name"}
- For packages with different names per platform, specify each:
{command: "ag", debianPkgName: "silversearcher-ag", termuxPkgName: "silversearcher-ag", brewPkgName: "the_silver_searcher"}
- For Ubuntu PPAs:
{command: "emacs", UbuntuPPA: "ppa:ubuntuhandhand1/emacs"}
- For Homebrew taps with options:
{command: "emacs", brewPkgName: "emacs-plus", brewTap: "d12frosted/emacs-plus", brewOptions: []string{"with-native-comp", "with-dbus"}}
Adding a Platform-Specific Tool
To add a tool with different installation methods per platform:
- For Go tools (simplest case):
GoTool("tool-name", "github.com/user/repo/cmd/tool@latest")
- For tools with different methods per platform:
{
command: "tool-name",
platforms: map[string]InstallMethod{
"darwin": BrewInstallMethod{Name: "tool-name"},
"termux": TermuxPkgInstallMethod{Name: "tool-name"},
"debian-like": UvInstallMethod{Name: "tool-name"},
},
Imports: nil,
}
- For cargo packages with auto-update:
{
command: "tool-name",
platforms: map[string]InstallMethod{
"all": CargoInstallMethod{Name: "crate-name"},
},
Imports: nil,
}
Regenerating Playbooks
After modifying the package definitions, regenerate the playbooks from the repository root:
make generate-ansible
This will:
- Generate all
.ymlplaybook files - Update the
BUILD.bazelfile with test targets for each playbook - Update
README.org's manual playbooks list
Testing Playbooks
After regenerating playbooks, validate them with Bazel syntax tests:
# Test all playbooks
bazel test //devtools/setup-dev/ansible:ansible_syntax_tests
# Test a specific playbook
bazel test //devtools/setup-dev/ansible:emacs_syntax_test
Recommended workflow when adding a new package:
- Edit
packages_data.goto add the package definition - Run
make generate-ansiblefrom the repo root to regenerate playbooks and BUILD.bazel - Run
bazel test //devtools/setup-dev/ansible:ansible_syntax_teststo validate syntax - Optionally run
makefrom the repo root to run all tests and linting
Important Files
devtools/setup-dev/ansible/generate_packages.go- Main generatordevtools/setup-dev/ansible/packages_data.go- Package definitions (edit this to add tools)devtools/setup-dev/ansible/types.go- Type definitionsdevtools/setup-dev/ansible/install_methods.go- Installation method implementationsdevtools/setup-dev/ansible/templates.go- Ansible YAML templatesdevtools/setup-dev/ansible/README.org- Detailed documentationdevtools/setup-dev/ansible/ensure.sh- Script to run playbooksdevtools/setup-dev/ansible/BUILD.bazel- Generated test targets
Design Patterns
Include Guards
All generated playbooks include guards to prevent multiple inclusion:
- name: Include guard for tool playbook
block:
- name: Stop early if the tool playbook is already included
meta: end_play
when: tool_playbook_imported is defined
- name: Ensure the tool playbook is not included
set_fact:
tool_playbook_imported: true
Dependency Management
Tools can declare dependencies via the Imports field:
{command: "notmuch", Imports: []Import{{Playbook: "python3-notmuch2"}}}
Dependencies are automatically imported at the beginning of playbooks.
Version Checking
Go and Cargo installation methods include automatic version checking:
- Go: Uses
go version -mandgo list -mto check for updates - Cargo: Uses
cargo-install-updatefor update detection - Shell: Supports custom version checking with regex and GitHub API
When to Use This Skill
Use this skill when you need to:
- Add a new development tool to the setup system
- Modify package installation configuration
- Understand how the Ansible playbook generator works
- Add support for a new installation method
- Debug playbook generation issues
- Update package definitions or platform-specific installation strategies
- Work with the BUILD.bazel test generation
- Understand the platform-specific installation strategy
References
For more detailed information, consult:
devtools/setup-dev/ansible/README.org- Complete documentation with design rationale- Individual
.gofiles for implementation details - Generated
.ymlfiles for examples of output playbooks