Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ Package lists are flat YAML arrays grouped by category:
- **OS packages**: `homebrew_formulae` / `homebrew_casks` / `choco_packages` /
`apt_packages` / `snap_packages` / `dnf_packages` / `flatpak_packages` /
`appimage_packages`
- **Cross-platform**: `powershell_modules`, `pipx_packages`, `npm_global_packages`, `dotnet_tools`, `vscode_extensions`
- **Cross-platform**: `powershell_modules`, `pipx_packages`, `uv_tools`,
`npm_global_packages`, `dotnet_tools`, `vscode_extensions`
- **Git config**: `git_user_email`, `git_user_name`
- **Custom commands**: `custom_commands_user` (non-elevated), `custom_commands_elevated` (sudo)
- **Custom script**: `custom_script` (path to a script run at the end)
Expand Down Expand Up @@ -67,6 +68,12 @@ Package lists are flat YAML arrays grouped by category:
Cursor is installed this way on Linux; macOS uses Homebrew cask `cursor`,
Windows uses Chocolatey `cursoride`.
All platforms reuse the `vscode_extensions` list for Cursor extension installation.
- **`uv_tools`** installs Python CLI tools via `uv tool install`.
On macOS/Windows, `pipx_packages` is empty (uv is available via Homebrew/Chocolatey);
on Linux, `pipx_packages` retains only `uv` (pipx bootstraps uv,
then uv manages the rest).
The uv tools step is guarded on uv being installed --
if uv is not on PATH, the step is silently skipped.

## Running the Setup Scripts

Expand Down
11 changes: 8 additions & 3 deletions debian/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ development environment.

- **APT Package Management**: Installs essential development tools and applications
- **Flatpak Package Management**: Installs GUI applications via Flatpak
- **Python Setup**: Installs Python packages via pipx
- **Python Setup**: Bootstraps uv via pipx and installs Python CLI tools via uv
- **Node.js Setup**: Installs npm global packages
- **VS Code Extensions**: Configures VS Code with essential development extensions
- **Git Setup**: Configures Git with user information, Git LFS, and Git Credential Manager
Expand Down Expand Up @@ -117,8 +117,12 @@ powershell_modules:
- AWS.Tools.Common
- Terminal-Icons

# Python packages via pipx
# Bootstrap uv via pipx
pipx_packages:
- uv

# Python CLI tools via uv
uv_tools:
- poetry
- ruff

Expand Down Expand Up @@ -196,7 +200,8 @@ The playbook uses tags to allow selective execution of tasks:
- `flatpak`: Flatpak package installation
- `appimage`: AppImage package installation
- `powershell`: PowerShell installation and module setup
- `pipx`: Python package installation via pipx
- `pipx`: Python package installation via pipx (bootstraps uv)
- `uv`: Python CLI tool installation via uv
- `npm`: Node.js package installation
- `dotnet`: .NET SDK and tools installation
- `vscode`: VS Code extension installation
Expand Down
67 changes: 46 additions & 21 deletions debian/setup.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
# Ansible playbook for Debian development machine setup
# Manages APT packages, Flatpak packages, PowerShell modules, pipx modules, VS Code extensions, and Git configuration
# Manages APT packages, Flatpak packages, PowerShell modules, pipx modules, uv tools, VS Code extensions, and Git configuration

- name: Setup development environment on Debian
hosts: localhost
Expand Down Expand Up @@ -117,7 +117,7 @@
components: "{{ item.components }}"
architectures: "{{ item.architectures }}"
state: present
loop: "{{ external_apt_repositories }}"
loop: "{{ external_apt_repositories | default([], true) }}"
loop_control:
label: "Adding repository: {{ item.name }}"
when: item.supported_architectures is not defined or deb_architecture in item.supported_architectures
Expand All @@ -142,7 +142,7 @@
name: flatpak
state: present
become: yes
when: flatpak_packages | length > 0
when: (flatpak_packages | default([], true)) | length > 0
tags:
- flatpak
- packages
Expand All @@ -153,7 +153,7 @@
flatpakrepo_url: https://dl.flathub.org/repo/flathub.flatpakrepo
state: present
become: yes
when: flatpak_packages | length > 0
when: (flatpak_packages | default([], true)) | length > 0
tags:
- flatpak
- packages
Expand All @@ -164,7 +164,7 @@
state: present
remote: flathub
become: yes
loop: "{{ flatpak_packages }}"
loop: "{{ flatpak_packages | default([], true) }}"
when: item.supported_architectures is not defined or deb_architecture in item.supported_architectures
register: flatpak_install_result
failed_when: false
Expand All @@ -181,7 +181,7 @@
npm config set prefix ~/.local
args:
creates: ~/.local/lib/node_modules
when: npm_global_packages | length > 0
when: (npm_global_packages | default([], true)) | length > 0
tags:
- npm
- packages
Expand All @@ -194,7 +194,7 @@
register: npm_check_result
changed_when: false
failed_when: false
loop: "{{ npm_global_packages | default([]) }}"
loop: "{{ npm_global_packages | default([], true) }}"
loop_control:
label: "Checking npm package: {{ item }}"
tags:
Expand All @@ -206,7 +206,7 @@
ansible.builtin.shell: |
export PATH=~/.local/bin:$PATH
npm install -g {{ item.0 }}
loop: "{{ npm_global_packages | default([]) | zip(npm_check_result.results) | list }}"
loop: "{{ npm_global_packages | default([], true) | zip(npm_check_result.results) | list }}"
when: "item.1.rc != 0"
register: npm_install_result
changed_when: "npm_install_result.rc == 0"
Expand Down Expand Up @@ -243,7 +243,7 @@
- name: Ensure .NET global tools are installed
ansible.builtin.command:
cmd: dotnet tool install -g {{ item }}
loop: "{{ dotnet_tools | default([]) }}"
loop: "{{ dotnet_tools | default([], true) }}"
register: dotnet_tool_install_result
changed_when: "'already installed' not in dotnet_tool_install_result.stderr and dotnet_tool_install_result.rc == 0"
failed_when: false
Expand Down Expand Up @@ -287,7 +287,7 @@
cmd: pwsh -Command "Install-PSResource -Name {{ item }} -TrustRepository"
environment:
PATH: "{{ ansible_env.HOME }}/.dotnet/tools:{{ ansible_env.PATH }}"
loop: "{{ powershell_modules }}"
loop: "{{ powershell_modules | default([], true) }}"
register: pwsh_install_result
changed_when: "'is already installed' not in pwsh_install_result.stdout"
loop_control:
Expand All @@ -301,7 +301,7 @@
- name: Install pipx modules
ansible.builtin.shell: |
pipx install {{ item }}
loop: "{{ pipx_packages }}"
loop: "{{ pipx_packages | default([], true) }}"
register: pipx_install_result
changed_when: "'already installed' not in pipx_install_result.stdout"
loop_control:
Expand All @@ -310,11 +310,36 @@
- pipx
- modules

# uv tool setup
- name: Check if uv is installed
ansible.builtin.command:
cmd: which uv
register: uv_check
changed_when: false
failed_when: false
tags:
- uv
- tools

- name: Install uv tools
ansible.builtin.command:
cmd: uv tool install {{ item }}
when: uv_check.rc == 0
loop: "{{ uv_tools | default([], true) }}"
ignore_errors: yes
register: uv_tool_install_result
changed_when: "'already installed' not in uv_tool_install_result.stderr"
loop_control:
label: "Installing uv tool: {{ item }}"
tags:
- uv
- tools

# VS Code extension setup
- name: Ensure VS Code extensions are installed
ansible.builtin.command:
cmd: code --install-extension {{ item }}
loop: "{{ vscode_extensions }}"
loop: "{{ vscode_extensions | default([], true) }}"
register: vscode_ext_result
changed_when: "'already installed' not in vscode_ext_result.stdout"
loop_control:
Expand All @@ -329,7 +354,7 @@
path: "{{ appimage_install_dir }}"
state: directory
mode: '0755'
when: appimage_packages is defined and appimage_packages | length > 0
when: (appimage_packages | default([], true)) | length > 0
tags:
- appimage

Expand All @@ -338,15 +363,15 @@
path: "{{ ansible_env.HOME }}/.local/share/applications"
state: directory
mode: '0755'
when: appimage_packages is defined and appimage_packages | length > 0
when: (appimage_packages | default([], true)) | length > 0
tags:
- appimage

- name: Check if AppImage already exists
ansible.builtin.stat:
path: "{{ appimage_install_dir }}/{{ item.name }}.AppImage"
register: appimage_stat
loop: "{{ appimage_packages | default([]) }}"
loop: "{{ appimage_packages | default([], true) }}"
when: item.supported_architectures is not defined or deb_architecture in item.supported_architectures
loop_control:
label: "Checking AppImage: {{ item.name }}"
Expand All @@ -359,7 +384,7 @@
dest: "{{ appimage_install_dir }}/{{ item.0.name }}.AppImage"
mode: '0755'
checksum: "{{ item.0.checksum | default(omit) }}"
loop: "{{ appimage_packages | default([]) | zip(appimage_stat.results | default([])) | list }}"
loop: "{{ appimage_packages | default([], true) | zip(appimage_stat.results | default([], true)) | list }}"
when:
- item.1.stat is defined
- not item.1.stat.exists
Expand All @@ -383,7 +408,7 @@
MimeType={{ item.mime_types | default('') }}
Categories={{ item.categories | default('Application;') }}
mode: '0644'
loop: "{{ appimage_packages | default([]) }}"
loop: "{{ appimage_packages | default([], true) }}"
when: item.supported_architectures is not defined or deb_architecture in item.supported_architectures
loop_control:
label: "Creating desktop entry: {{ item.name }}"
Expand All @@ -396,7 +421,7 @@
dest: "{{ appimage_install_dir }}/{{ item.name }}"
state: link
force: true
loop: "{{ appimage_packages | default([]) }}"
loop: "{{ appimage_packages | default([], true) }}"
when: item.supported_architectures is not defined or deb_architecture in item.supported_architectures
loop_control:
label: "Creating symlink: {{ item.name }}"
Expand All @@ -423,7 +448,7 @@
environment:
PATH: "{{ appimage_install_dir }}:{{ ansible_env.PATH }}"
ignore_errors: yes
loop: "{{ vscode_extensions }}"
loop: "{{ vscode_extensions | default([], true) }}"
register: cursor_ext_result
changed_when: "'already installed' not in cursor_ext_result.stdout"
when:
Expand Down Expand Up @@ -470,7 +495,7 @@
# Custom user commands
- name: Execute custom user commands
ansible.builtin.shell: "{{ item.command }}"
loop: "{{ custom_commands_user }}"
loop: "{{ custom_commands_user | default([], true) }}"
loop_control:
label: "Executing: {{ item.description }}"
tags:
Expand All @@ -481,7 +506,7 @@
- name: Execute custom elevated commands
ansible.builtin.shell: "{{ item.command }}"
become: yes
loop: "{{ custom_commands_elevated }}"
loop: "{{ custom_commands_elevated | default([], true) }}"
loop_control:
label: "Executing: {{ item.description }}"
tags:
Expand Down
5 changes: 4 additions & 1 deletion debian/vars.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,15 @@ powershell_modules:

# pipx modules
pipx_packages:
- uv

# uv tools
uv_tools:
- aws-sam-cli
- cfn-lint
- poetry
- ruff
- taskcat
- uv

# npm global packages
npm_global_packages:
Expand Down
12 changes: 6 additions & 6 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ graph LR
subgraph "Package Managers"
G --> L[brew install]
H --> M[Install-PSResource]
I --> N[pipx install]
I --> N[uv tool install]
J --> O[code --install-extension]
end
```
Expand Down Expand Up @@ -140,7 +140,7 @@ graph LR
subgraph "Package Managers"
F --> K[choco install]
G --> L[Install-PSResource]
H --> M[pipx install]
H --> M[uv tool install]
I --> N[code --install-extension]
end
```
Expand Down Expand Up @@ -172,7 +172,7 @@ graph LR
G --> L[apt install]
H --> M[snap install]
I --> N[Install-PSResource]
J --> O[pipx install]
J --> O[uv tool install]
K --> P[code --install-extension]
end
```
Expand Down Expand Up @@ -206,7 +206,7 @@ graph LR
G --> L[apt install]
H --> M[flatpak install]
I --> N[Install-PSResource]
J --> O[pipx install]
J --> O[uv tool install]
K --> P[code --install-extension]
end
```
Expand Down Expand Up @@ -240,7 +240,7 @@ graph LR
G --> L[dnf install]
H --> M[flatpak install]
I --> N[Install-PSResource]
J --> O[pipx install]
J --> O[uv tool install]
K --> P[code --install-extension]
end
```
Expand Down Expand Up @@ -301,7 +301,7 @@ Each platform organizes packages into logical categories:
| Applications | `homebrew_casks` | `choco_packages` | `snap_packages` | `flatpak_packages` | `flatpak_packages` |
| VS Code Extensions | `vscode_extensions` | `vscode_extensions` | `vscode_extensions` | `vscode_extensions` | `vscode_extensions` |
| PowerShell Modules | `powershell_modules` | `powershell_modules` | `powershell_modules` | `powershell_modules` | `powershell_modules` |
| Python Packages | `pipx_packages` | `pipx_packages` | `pipx_packages` | `pipx_packages` | `pipx_packages` |
| Python Packages | `uv_tools` | `uv_tools` | `uv_tools` | `uv_tools` | `uv_tools` |
| Node.js Packages | `npm_global_packages` | `npm_global_packages` | `npm_global_packages` | `npm_global_packages` | `npm_global_packages` |
| .NET Tools | `dotnet_tools` | `dotnet_tools` | `dotnet_tools` | `dotnet_tools` | `dotnet_tools` |

Expand Down
22 changes: 13 additions & 9 deletions docs/configuration-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ vscode_extensions: [] # List of VS Code extensions
# PowerShell modules (all platforms)
powershell_modules: [] # List of PowerShell modules

# Python packages via pipx (all platforms)
pipx_packages: [] # List of Python CLI tools
# Python packages via pipx (bootstraps uv on Linux; empty on macOS/Windows)
pipx_packages: [] # List of Python packages

# Python CLI tools via uv (all platforms)
uv_tools: [] # List of Python CLI tools
```

## macOS Configuration Reference
Expand Down Expand Up @@ -498,21 +501,22 @@ powershell_modules:
- Microsoft.Graph.Authentication # Microsoft Graph
```

### Python Packages (pipx)
### Python CLI Tools (uv)

Python CLI tools installed via pipx:
Python CLI tools installed via `uv tool install`.
On macOS and Windows, uv is available via the system package manager
(Homebrew/Chocolatey).
On Linux, pipx bootstraps uv, then uv manages the rest:

```yaml
pipx_packages:
uv_tools:
# Development tools
- poetry # Dependency management
- black # Code formatter
- flake8 # Linting
- mypy # Type checking
- ruff # Linting and formatting

# AWS tools
- taskcat # CloudFormation testing
- awscli-local # LocalStack CLI
- cfn-lint # CloudFormation linting

# DevOps tools
- ansible # Automation (where not system package)
Expand Down
Loading