Skip to content

WhatIsHeDoing/Setup

Setup

Lint Install MIT License Security Policy

Cross-platform desktop setup using Ansible and Mise.

Targets macOS, Ubuntu, and Windows (via WSL2). Idempotent — run at any time to install missing tools or apply updates.

How It Works

Layer Tool Role
Orchestrator Ansible Idempotent install, config, and dotfile deployment
Runtimes Mise Node, Python, Rust version management
Package managers Homebrew / apt+snap+flatpak / WinGet Platform-native package installation

Ansible runs locally on macOS and Ubuntu (connection: local). On Windows, it runs from WSL2 and connects to the Windows host over WinRM using the WSL2 gateway address.

Quick Start

1. Bootstrap

Run once on a fresh machine to install the prerequisites Ansible and Just on all platforms, and Git for Windows:

# macOS
bash bootstrap/bootstrap_macos.sh

# Ubuntu / WSL2
bash bootstrap/bootstrap_ubuntu.sh

# Windows — run first in PowerShell as Administrator
.\bootstrap\bootstrap_windows.ps1

2. Install

just install

3. Upgrade

just upgrade

Dry run

Preview exactly what just install would change without touching the machine:

just dry-run

Runs the playbook with --check --diff: shows which tasks would make changes and diffs any file content that would be modified. The verification step is skipped because commands do not actually execute in check mode.

Running a subset

Each role is tagged so you can re-run it without running the full playbook:

Tag Role
bootstrap Package manager setup
runtimes Mise, Node, Python, Rust, global packages
tools CLI tools
apps GUI applications
dotfiles Config files and scripts
git Global git configuration
os_config VS Code extensions, macOS system defaults
just install-tags dotfiles              # redeploy config files only
just install-tags git                   # reapply git config (e.g. after editing local.yml)
just install-tags dotfiles git          # multiple roles at once
just dry-run-tags dotfiles              # preview config file changes only
just dry-run-tags git                   # preview git config changes only

Windows Setup

Windows packages are managed from WSL2 via Ansible + WinRM. The flow is:

  1. Run bootstrap\bootstrap_windows.ps1 in PowerShell as Administrator — installs Git, configures WinRM, sets up WSL2.
  2. In WSL2, clone this repo and run bash bootstrap/bootstrap_ubuntu.sh (installs Ansible).
  3. Run the install command above with the windows.yml inventory.

The Ansible playbook connects back to the Windows host over WinRM and installs everything via WinGet.

Repo Structure

.
├── ansible/
│   ├── inventory/
│   │   ├── group_vars/all.yml         # Cross-platform vars (git config, cargo/pip packages)
│   │   ├── group_vars/local.yml.example  # Template for gitignored personal overrides
│   │   ├── localhost.yml        # macOS / Ubuntu target
│   │   └── windows.yml         # Windows target (WinRM via WSL2 gateway)
│   ├── playbooks/
│   │   ├── install.yml          # Main install playbook (runs verify at end)
│   │   ├── upgrade.yml          # Upgrade all packages
│   │   └── verify.yml           # Verify tools are installed
│   ├── requirements.yml         # Ansible Galaxy collections
│   └── roles/
│       ├── bootstrap/           # Package manager setup (Homebrew, apt repos, WinGet)
│       ├── runtimes/            # Node, Python, Rust via Mise
│       ├── tools/               # CLI tools
│       ├── apps/                # GUI applications
│       ├── dotfiles/            # Config file and script deployment
│       ├── git/                 # Git global configuration
│       └── os_config/           # OS-level config (VS Code extensions, Docker group, etc.)
├── bootstrap/
│   ├── bootstrap_macos.sh       # Installs Homebrew, Ansible
│   ├── bootstrap_ubuntu.sh      # Installs pipx, Ansible
│   └── bootstrap_windows.ps1   # Installs Git, configures WinRM, sets up WSL2
├── config/
│   ├── starship.toml            # Starship prompt config
│   └── bottom.toml              # bottom system monitor config
├── docs/
│   ├── principles.md            # Architecture principles
│   └── adr/                     # Architecture Decision Records
├── scripts/
│   ├── ff                       # Fuzzy-find script (macOS, Ubuntu)
│   └── ll                       # Colourful directory listing (macOS, Ubuntu)
├── .mise.toml                   # Runtime version pins (Node, Python, Rust)
└── Justfile                     # Convenience wrappers around ansible-playbook

What Gets Installed

all means macOS, Ubuntu, and Windows.

Runtimes

Runtime Platforms Manager
Node.js all Mise (macOS/Ubuntu), WinGet (Windows)
Python all Mise (macOS/Ubuntu), WinGet (Windows)
Rust all Mise (macOS/Ubuntu), WinGet/rustup (Windows)
.NET all Homebrew (macOS), apt (Ubuntu), WinGet (Windows)
Docker all OrbStack (macOS), apt (Ubuntu), Docker Desktop via WinGet (Windows)
PowerShell Ubuntu, Windows apt (Ubuntu), WinGet (Windows)

Tools

Tool Platforms Description
asciinema macOS, Ubuntu Record and share terminal sessions
bat all cat clone with syntax highlighting
bottom all Terminal system monitor
delta all Syntax-highlighted diffs; configured as git pager
eza all Modern ls replacement
fd all Fast and user-friendly find alternative
fzf all Command-line fuzzy finder
gh all GitHub CLI
Git LFS all Git Large File Storage
jq all sed for JSON
just all Task runner
lazygit all TUI for git
less all Terminal pager
pandoc all Universal markup converter
pnpm all Fast JavaScript package manager
ripgrep all Fast regex search
ripgrep-all all ripgrep across PDFs, Office docs, etc.
shellcheck all Shell script linter
Starship all Cross-shell prompt
UPX all Executable packer
zoxide all Smarter cd that learns your habits
zsh-autocomplete macOS Real-time tab completion for Zsh
zsh-autosuggestions macOS Fish-style history suggestions for Zsh
NuGet all .NET package manager
PuTTY Windows SSH client
VS Build Tools Windows MSVC compiler toolchain
Docker (apt) Ubuntu Container runtime
Flatpak Ubuntu Application distribution
ffmpeg all Media processing

Apps

App Platforms Description
VS Code all Code editor
draw.io all Diagramming
Obsidian all Note-taking
Spotify all Music
Telegram all Messaging
ghostty macOS, Ubuntu Fast, native terminal emulator
OrbStack macOS Container and VM runtime (Docker Desktop replacement)
Raindrop.io macOS, Windows Bookmark manager
7-Zip Windows File archiver
Caesium Ubuntu, Windows Image compressor
DBeaver all Universal database tool
Amberol Ubuntu Music player
Firefox all Web browser

Cross-Platform Packages

Installed on all platforms via their respective package managers:

Type Packages
Cargo cargo-modules, cargo-outdated, cargo-update, diskonaut, wasm-pack
pip ansible-core, ansible-lint, checkov, ipykernel, pre-commit, setuptools
pnpm cspell
VS Code GitLens, EditorConfig, Markdownlint, Night Owl theme, VS Code Icons

Scripts

Deployed to ~/.local/bin on macOS and Ubuntu:

Command Description
ff <term> Fuzzy find files matching a search term, previewed with bat
ll [path] List files with eza (long format, git-aware, human-readable)

Customisation

Machine-specific settings that should not be committed live in a gitignored file:

cp ansible/inventory/group_vars/local.yml.example ansible/inventory/group_vars/local.yml

Edit local.yml and fill in your details:

git_user_name: "Your Name"
git_user_email: "you@example.com"

Ansible picks this file up automatically. If it is absent the identity tasks are skipped — nothing breaks. The .example file documents the available options.

Documentation

Testing

Test the code in this repo with:

just pre-commit
just ansible-lint
just spellcheck

About

Scripts that set up my common environments.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Contributors