🔧 Where my dotfiles lives in harmony and peace, most of the time
1#!/usr/bin/env bash
2
3set -euo pipefail
4
5info() {
6 printf "→ %s\n" "$*"
7}
8
9success() {
10 printf "✓ %s\n" "$*"
11}
12
13skip() {
14 printf -- "- %s\n" "$*"
15}
16
17warn() {
18 printf "✗ %s\n" "$*" >&2
19}
20
21error() {
22 warn "$*"
23 exit 1
24}
25
26run_task() {
27 local description=$1
28 shift
29
30 info "$description"
31 if "$@" &>/dev/null; then
32 success "$description"
33 return 0
34 fi
35
36 warn "$description failed (continuing)"
37 return 1
38}
39
40cleanup_docker() {
41 if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
42 run_task "Docker cleanup" docker system prune --volumes --all --force
43 else
44 skip "Docker cleanup (docker unavailable)"
45 fi
46}
47
48cleanup_uv() {
49 if command -v uv >/dev/null 2>&1; then
50 run_task "uv cache cleanup" uv cache clean
51 run_task "uv tool upgrade" uv tool upgrade --all
52 else
53 skip "uv maintenance (uv not installed)"
54 fi
55}
56
57cleanup_pacman() {
58 if ! command -v pacman >/dev/null 2>&1; then
59 skip "pacman cleanup (pacman not installed)"
60 return
61 fi
62
63 run_task "pacman cache cleanup" sudo pacman --noconfirm -Sc
64
65 local -a orphans=()
66 if mapfile -t orphans < <(pacman -Qtdq 2>/dev/null) && ((${#orphans[@]} > 0)); then
67 run_task "pacman orphan removal" sudo pacman --noconfirm -Rns "${orphans[@]}"
68 else
69 skip "pacman orphan removal (none found)"
70 fi
71}
72
73cleanup_paru() {
74 if ! command -v paru >/dev/null 2>&1; then
75 skip "paru cleanup (paru not installed)"
76 return
77 fi
78
79 run_task "paru cache cleanup" paru --sudo sudo -Sc --noconfirm
80}
81
82cleanup_journal() {
83 if command -v journalctl >/dev/null 2>&1; then
84 run_task "systemd journal vacuum (<=200M)" sudo journalctl --vacuum-size=200M
85 else
86 skip "journal vacuum (journalctl not installed)"
87 fi
88}
89
90cleanup_paru_clone_cache() {
91 local clone_dir="$HOME/.cache/paru/clone"
92 if [[ -d $clone_dir ]]; then
93 run_task "paru clone cache cleanup" rm -rf -- "$clone_dir"
94 else
95 skip "paru clone cache cleanup (directory missing)"
96 fi
97}
98
99cleanup_cliphist() {
100 if ! command -v cliphist >/dev/null 2>&1; then
101 skip "cliphist cleanup (cliphist not installed)"
102 return
103 fi
104
105 local cliphist_cache="$HOME/.cache/cliphist"
106 if [[ -d $cliphist_cache ]]; then
107 run_task "cliphist history cleanup" rm -rf -- "$cliphist_cache"
108 else
109 skip "cliphist history cleanup (cache missing)"
110 fi
111}
112
113is_btrfs_root() {
114 [[ $(findmnt -no FSTYPE /) == "btrfs" ]]
115}
116
117btrfs_maintenance() {
118 if ! command -v btrfs >/dev/null 2>&1; then
119 skip "btrfs maintenance (btrfs-progs not installed)"
120 return
121 fi
122
123 if ! is_btrfs_root; then
124 skip "btrfs maintenance (root fs not btrfs)"
125 return
126 fi
127
128 run_task "btrfs scrub (root)" sudo btrfs scrub start -Bd /
129 run_task "btrfs balance (dusage=75,musage=75)" sudo btrfs balance start -dusage=75 -musage=75 /
130}
131
132main() {
133 info "Starting maintenance tasks"
134
135 # Core maintenance tasks from Makefile
136 cleanup_docker
137 cleanup_uv
138 cleanup_pacman
139 cleanup_paru
140 cleanup_paru_clone_cache
141 cleanup_journal
142 cleanup_cliphist
143 btrfs_maintenance
144
145 success "Maintenance tasks completed"
146}
147
148# Parse command line arguments
149while [[ $# -gt 0 ]]; do
150 case $1 in
151 --help|-h)
152 echo "Usage: $0 [--with-update] [--help]"
153 echo ""
154 echo "Options:"
155 echo " --with-update Also run system update (paru/pacman)"
156 echo " --help, -h Show this help message"
157 exit 0
158 ;;
159 *)
160 error "Unknown option: $1"
161 ;;
162 esac
163done
164
165main "$@"