Phase 2: Chezmoi dotfile orchestration + fastfetch
This commit is contained in:
parent
ac7e575957
commit
f554eb8901
51
CLAUDE.md
51
CLAUDE.md
@ -1,10 +1,11 @@
|
|||||||
# CLI Standardization
|
# CLI Standardization
|
||||||
|
|
||||||
Ansible project to deploy a modern CLI environment (Fish + Starship + modern coreutils)
|
Ansible project to deploy a modern CLI environment (Fish + Starship + modern coreutils)
|
||||||
to Arch and Ubuntu/Debian hosts.
|
to Arch and Ubuntu/Debian hosts. Includes optional Chezmoi dotfile orchestration.
|
||||||
|
|
||||||
## What it installs
|
## What it installs
|
||||||
|
|
||||||
|
**Phase 1 — packages and config templates:**
|
||||||
- **Fish shell** 4.x (PPA on Ubuntu, pacman on Arch)
|
- **Fish shell** 4.x (PPA on Ubuntu, pacman on Arch)
|
||||||
- **Starship** prompt (official binary installer)
|
- **Starship** prompt (official binary installer)
|
||||||
- **fzf** — fuzzy finder
|
- **fzf** — fuzzy finder
|
||||||
@ -13,8 +14,14 @@ to Arch and Ubuntu/Debian hosts.
|
|||||||
- **eza** — modern ls
|
- **eza** — modern ls
|
||||||
- **fd** — modern find
|
- **fd** — modern find
|
||||||
- **ripgrep** — fast grep
|
- **ripgrep** — fast grep
|
||||||
|
- **fastfetch** — system info on login
|
||||||
- **Fisher** plugin manager + plugins
|
- **Fisher** plugin manager + plugins
|
||||||
|
|
||||||
|
**Phase 2 — Chezmoi dotfile sync (opt-in):**
|
||||||
|
- **Chezmoi** — dotfile manager synced from Gitea
|
||||||
|
- Manages: Fish config, Starship, Ghostty, Zellij
|
||||||
|
- Machine-type aware: servers skip Ghostty/Zellij configs
|
||||||
|
|
||||||
## Dev workflow
|
## Dev workflow
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -27,9 +34,11 @@ ansible-playbook playbook.yml --syntax-check
|
|||||||
# Dry run
|
# Dry run
|
||||||
ansible-playbook playbook.yml -i inventory.yml --check --diff
|
ansible-playbook playbook.yml -i inventory.yml --check --diff
|
||||||
|
|
||||||
# Deploy
|
# Deploy (Phase 1 only — default)
|
||||||
ansible-playbook playbook.yml -i inventory.yml
|
ansible-playbook playbook.yml -i inventory.yml
|
||||||
ansible-playbook playbook.yml -i inventory.yml --limit manjaro-dev
|
|
||||||
|
# Deploy with Chezmoi (Phase 2)
|
||||||
|
ansible-playbook playbook.yml -i inventory.yml -e cli_modern_install_chezmoi=true -e cli_modern_chezmoi_repo=git@gitea:herbygitea/dotfiles.git
|
||||||
```
|
```
|
||||||
|
|
||||||
## Role structure
|
## Role structure
|
||||||
@ -43,15 +52,47 @@ roles/cli_modern/
|
|||||||
│ ├── packages-debian.yml # Ubuntu/Debian packages + Fish PPA
|
│ ├── packages-debian.yml # Ubuntu/Debian packages + Fish PPA
|
||||||
│ ├── starship.yml # Starship binary install
|
│ ├── starship.yml # Starship binary install
|
||||||
│ ├── fisher.yml # Fisher + plugin sync
|
│ ├── fisher.yml # Fisher + plugin sync
|
||||||
│ ├── config.yml # Deploy config templates
|
│ ├── config.yml # Deploy config templates (Phase 1)
|
||||||
│ └── default-shell.yml # Set Fish as login shell
|
│ ├── default-shell.yml # Set Fish as login shell
|
||||||
|
│ └── chezmoi.yml # Chezmoi install + apply (Phase 2)
|
||||||
└── templates/
|
└── templates/
|
||||||
├── config.fish.j2 # Fish shell config
|
├── config.fish.j2 # Fish shell config
|
||||||
├── starship.toml.j2 # Starship prompt config
|
├── starship.toml.j2 # Starship prompt config
|
||||||
└── fish_plugins.j2 # Fisher plugin list
|
└── fish_plugins.j2 # Fisher plugin list
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Dotfiles repo (Phase 2)
|
||||||
|
|
||||||
|
Separate repo at `/opt/projects/pbs-workshop/dotfiles/`, to be pushed to Gitea.
|
||||||
|
Contains placeholder configs — replace with real dotfiles before enabling Chezmoi.
|
||||||
|
|
||||||
|
```
|
||||||
|
dotfiles/
|
||||||
|
├── .chezmoi.toml.tmpl # Prompted config (name, email, machine type)
|
||||||
|
├── .chezmoiignore # Skips Ghostty/Zellij on servers
|
||||||
|
├── dot_config/
|
||||||
|
│ ├── fish/config.fish # PLACEHOLDER
|
||||||
|
│ ├── fish/fish_plugins # Fisher plugin list
|
||||||
|
│ ├── ghostty/config # PLACEHOLDER (workstations only)
|
||||||
|
│ ├── starship.toml # PLACEHOLDER
|
||||||
|
│ └── zellij/config.kdl # PLACEHOLDER (workstations only)
|
||||||
|
```
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
All options are in `roles/cli_modern/defaults/main.yml`. Override per-host
|
All options are in `roles/cli_modern/defaults/main.yml`. Override per-host
|
||||||
in `host_vars/` or per-group in `group_vars/`.
|
in `host_vars/` or per-group in `group_vars/`.
|
||||||
|
|
||||||
|
### Phase 1 vs Phase 2 config management
|
||||||
|
|
||||||
|
Phase 1 deploys Fish/Starship configs via Ansible templates. Phase 2 uses
|
||||||
|
Chezmoi from a Git repo. When enabling Chezmoi, set the Phase 1 template
|
||||||
|
flags to false to avoid conflicts:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
cli_modern_deploy_fish_config: false
|
||||||
|
cli_modern_deploy_starship_config: false
|
||||||
|
cli_modern_install_chezmoi: true
|
||||||
|
cli_modern_chezmoi_repo: "git@gitea:herbygitea/dotfiles.git"
|
||||||
|
cli_modern_chezmoi_machine_type: "workstation" # or "server"
|
||||||
|
```
|
||||||
|
|||||||
@ -37,6 +37,9 @@ cli_modern_install_fd: true
|
|||||||
# ripgrep — fast grep
|
# ripgrep — fast grep
|
||||||
cli_modern_install_ripgrep: true
|
cli_modern_install_ripgrep: true
|
||||||
|
|
||||||
|
# fastfetch — system info on login (neofetch successor)
|
||||||
|
cli_modern_install_fastfetch: true
|
||||||
|
|
||||||
# Fisher plugin manager — auto-installed on first Fish launch
|
# Fisher plugin manager — auto-installed on first Fish launch
|
||||||
cli_modern_install_fisher: true
|
cli_modern_install_fisher: true
|
||||||
|
|
||||||
@ -48,6 +51,14 @@ cli_modern_fisher_plugins:
|
|||||||
- "meaningful-ooo/sponge"
|
- "meaningful-ooo/sponge"
|
||||||
- "jorgebucaran/autopair.fish"
|
- "jorgebucaran/autopair.fish"
|
||||||
|
|
||||||
# Deploy config templates
|
# Deploy config templates (Phase 1 — Ansible-managed templates)
|
||||||
|
# Set to false when using Chezmoi (Phase 2) to avoid conflicts
|
||||||
cli_modern_deploy_fish_config: true
|
cli_modern_deploy_fish_config: true
|
||||||
cli_modern_deploy_starship_config: true
|
cli_modern_deploy_starship_config: true
|
||||||
|
|
||||||
|
# ── Phase 2: Chezmoi dotfile orchestration ──────────────────
|
||||||
|
cli_modern_install_chezmoi: false
|
||||||
|
# Gitea repo URL for dotfiles (SSH format)
|
||||||
|
cli_modern_chezmoi_repo: ""
|
||||||
|
# Machine type passed to chezmoi init ("workstation" or "server")
|
||||||
|
cli_modern_chezmoi_machine_type: "server"
|
||||||
|
|||||||
81
roles/cli_modern/tasks/chezmoi.yml
Normal file
81
roles/cli_modern/tasks/chezmoi.yml
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
---
|
||||||
|
# Phase 2: Install Chezmoi and apply dotfiles from Gitea repo.
|
||||||
|
|
||||||
|
- name: Check if Chezmoi is already installed
|
||||||
|
ansible.builtin.command: chezmoi --version
|
||||||
|
register: cli_modern_chezmoi_check
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
# --- Install Chezmoi (Arch) ---
|
||||||
|
|
||||||
|
- name: Install Chezmoi via pacman
|
||||||
|
become: true
|
||||||
|
community.general.pacman:
|
||||||
|
name: chezmoi
|
||||||
|
state: present
|
||||||
|
when:
|
||||||
|
- cli_modern_chezmoi_check.rc != 0
|
||||||
|
- ansible_os_family == "Archlinux"
|
||||||
|
|
||||||
|
# --- Install Chezmoi (Debian/Ubuntu) ---
|
||||||
|
|
||||||
|
- name: Download Chezmoi install script
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: https://get.chezmoi.io
|
||||||
|
dest: /tmp/chezmoi-install.sh
|
||||||
|
mode: "0755"
|
||||||
|
when:
|
||||||
|
- cli_modern_chezmoi_check.rc != 0
|
||||||
|
- ansible_os_family == "Debian"
|
||||||
|
|
||||||
|
- name: Install Chezmoi via official installer
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command: /tmp/chezmoi-install.sh -b /usr/local/bin
|
||||||
|
args:
|
||||||
|
creates: /usr/local/bin/chezmoi
|
||||||
|
when:
|
||||||
|
- cli_modern_chezmoi_check.rc != 0
|
||||||
|
- ansible_os_family == "Debian"
|
||||||
|
|
||||||
|
- name: Clean up Chezmoi installer
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /tmp/chezmoi-install.sh
|
||||||
|
state: absent
|
||||||
|
when:
|
||||||
|
- cli_modern_chezmoi_check.rc != 0
|
||||||
|
- ansible_os_family == "Debian"
|
||||||
|
|
||||||
|
# --- Initialize and apply dotfiles ---
|
||||||
|
|
||||||
|
- name: Check if Chezmoi is already initialized
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ cli_modern_user_home }}/.local/share/chezmoi"
|
||||||
|
register: cli_modern_chezmoi_dir
|
||||||
|
|
||||||
|
- name: Initialize Chezmoi from dotfiles repo
|
||||||
|
become: true
|
||||||
|
become_user: "{{ cli_modern_user }}"
|
||||||
|
ansible.builtin.command: >
|
||||||
|
chezmoi init {{ cli_modern_chezmoi_repo }}
|
||||||
|
--promptString "Your name={{ cli_modern_user }}"
|
||||||
|
--promptString "Your email="
|
||||||
|
--promptChoice "Machine type={{ cli_modern_chezmoi_machine_type }}"
|
||||||
|
--no-tty
|
||||||
|
args:
|
||||||
|
chdir: "{{ cli_modern_user_home }}"
|
||||||
|
creates: "{{ cli_modern_user_home }}/.local/share/chezmoi/.git"
|
||||||
|
when:
|
||||||
|
- cli_modern_chezmoi_repo | length > 0
|
||||||
|
- not cli_modern_chezmoi_dir.stat.exists
|
||||||
|
|
||||||
|
- name: Apply Chezmoi dotfiles
|
||||||
|
become: true
|
||||||
|
become_user: "{{ cli_modern_user }}"
|
||||||
|
ansible.builtin.command: chezmoi apply --no-tty
|
||||||
|
args:
|
||||||
|
chdir: "{{ cli_modern_user_home }}"
|
||||||
|
register: cli_modern_chezmoi_apply
|
||||||
|
changed_when: cli_modern_chezmoi_apply.rc == 0
|
||||||
|
when:
|
||||||
|
- cli_modern_chezmoi_repo | length > 0
|
||||||
@ -24,3 +24,8 @@
|
|||||||
- name: Set Fish as default shell
|
- name: Set Fish as default shell
|
||||||
ansible.builtin.include_tasks: default-shell.yml
|
ansible.builtin.include_tasks: default-shell.yml
|
||||||
when: cli_modern_set_default_shell
|
when: cli_modern_set_default_shell
|
||||||
|
|
||||||
|
# Phase 2: Chezmoi dotfile orchestration
|
||||||
|
- name: Install Chezmoi and apply dotfiles
|
||||||
|
ansible.builtin.include_tasks: chezmoi.yml
|
||||||
|
when: cli_modern_install_chezmoi
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
(['bat'] if cli_modern_install_bat else []) +
|
(['bat'] if cli_modern_install_bat else []) +
|
||||||
(['eza'] if cli_modern_install_eza else []) +
|
(['eza'] if cli_modern_install_eza else []) +
|
||||||
(['fd'] if cli_modern_install_fd else []) +
|
(['fd'] if cli_modern_install_fd else []) +
|
||||||
(['ripgrep'] if cli_modern_install_ripgrep else [])
|
(['ripgrep'] if cli_modern_install_ripgrep else []) +
|
||||||
|
(['fastfetch'] if cli_modern_install_fastfetch else [])
|
||||||
}}
|
}}
|
||||||
when: cli_modern_arch_packages | length > 0
|
when: cli_modern_arch_packages | length > 0
|
||||||
|
|||||||
@ -63,7 +63,8 @@
|
|||||||
(['bat'] if cli_modern_install_bat else []) +
|
(['bat'] if cli_modern_install_bat else []) +
|
||||||
(['eza'] if cli_modern_install_eza else []) +
|
(['eza'] if cli_modern_install_eza else []) +
|
||||||
(['fd-find'] if cli_modern_install_fd else []) +
|
(['fd-find'] if cli_modern_install_fd else []) +
|
||||||
(['ripgrep'] if cli_modern_install_ripgrep else [])
|
(['ripgrep'] if cli_modern_install_ripgrep else []) +
|
||||||
|
(['fastfetch'] if cli_modern_install_fastfetch else [])
|
||||||
}}
|
}}
|
||||||
when: cli_modern_deb_packages | length > 0
|
when: cli_modern_deb_packages | length > 0
|
||||||
|
|
||||||
|
|||||||
@ -54,4 +54,13 @@ if status is-interactive
|
|||||||
# Suppress Fish greeting
|
# Suppress Fish greeting
|
||||||
set -g fish_greeting
|
set -g fish_greeting
|
||||||
|
|
||||||
|
{% if cli_modern_install_fastfetch %}
|
||||||
|
# ── System Info ─────────────────────────────────────────
|
||||||
|
# Show machine identity on first shell in a login session.
|
||||||
|
# Skips nested shells and non-login to keep things snappy.
|
||||||
|
if status is-login
|
||||||
|
fastfetch
|
||||||
|
end
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user