Generate and manage cross-platform Ansible playbooks for development environment setup across macOS, Linux, and Termux...
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.
The repository contains a Go-based generator that creates Ansible playbooks for setting up development environments consistently across:
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 definitionsPackageData: Traditional system packages installed via platform package managers (apt, brew, pkg)
PlatformSpecificTool: Development tools with platform-specific installation methods
InstallMethod interfaceThe 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 checkingThe generator follows best practices for each platform:
pkg due to Termux's unconventional setup requiring patchesuv over pip (faster, better dependency resolution)go install with automatic version checking and upgrade logicTo add a system package that uses platform package managers:
packages array in packages_data.go:{command: "your-tool", debianPkgName: "debian-name", termuxPkgName: "termux-name", brewPkgName: "brew-name"}
{command: "ag", debianPkgName: "silversearcher-ag", termuxPkgName: "silversearcher-ag", brewPkgName: "the_silver_searcher"}
{command: "emacs", UbuntuPPA: "ppa:ubuntuhandhand1/emacs"}
{command: "emacs", brewPkgName: "emacs-plus", brewTap: "d12frosted/emacs-plus", brewOptions: []string{"with-native-comp", "with-dbus"}}
To add a tool with different installation methods per platform:
GoTool("tool-name", "github.com/user/repo/cmd/tool@latest")
{
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,
}
{
command: "tool-name",
platforms: map[string]InstallMethod{
"all": CargoInstallMethod{Name: "crate-name"},
},
Imports: nil,
}
After modifying the package definitions, regenerate the playbooks from the repository root:
make generate-ansible
This will:
.yml playbook filesBUILD.bazel file with test targets for each playbookREADME.org's manual playbooks listAfter 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:
packages_data.go to add the package definitionmake generate-ansible from the repo root to regenerate playbooks and BUILD.bazelbazel test //devtools/setup-dev/ansible:ansible_syntax_tests to validate syntaxmake from the repo root to run all tests and lintingdevtools/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 targetsAll 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
Tools can declare dependencies via the Imports field:
{command: "notmuch", Imports: []Import{{Playbook: "python3-notmuch2"}}}
Dependencies are automatically imported at the beginning of playbooks.
Some playbooks are not generated by the Go program and are maintained manually. These playbooks are typically used for:
setup-ssh-key.yml, setup-homebrew-env.yml).setup-shell-profile.yml).all.yml).When creating a manual playbook:
setup-<feature>.yml or just <feature>.yml.README.org.ALWAYS run make in the devtools/setup-dev/ansible directory after making changes, including adding manual playbooks.
cd devtools/setup-dev/ansible
make
The make command:
.yml files and updates README.org (including the manual playbooks list).Go and Cargo installation methods include automatic version checking:
go version -m and go list -m to check for updatescargo-install-update for update detectionUse this skill when you need to:
For more detailed information, consult:
devtools/setup-dev/ansible/README.org - Complete documentation with design rationale.go files for implementation details.yml files for examples of output playbooks