theamify-cli 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +286 -0
- package/bin/theamify.js +2 -0
- package/package.json +52 -0
- package/src/cli.js +109 -0
- package/src/commands/manage.js +122 -0
- package/src/core/engine.js +100 -0
- package/src/lib/chafa.js +143 -0
- package/src/lib/conf.js +55 -0
- package/src/lib/tools.js +76 -0
- package/src/wizard/browse.js +165 -0
- package/vendor/config/themes.conf +36 -0
- package/vendor/lib/colors.sh +151 -0
- package/vendor/lib/grub.sh +179 -0
- package/vendor/lib/themes.sh +283 -0
- package/vendor/lib/utils.sh +135 -0
- package/vendor/theamify +565 -0
package/vendor/theamify
ADDED
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# -----------------------------------------------------------------------------
|
|
3
|
+
# theamify - GRUB Theme Manager
|
|
4
|
+
# Author : Don Artkins (Opiyo Don Paul) - github.com/DonArtkins
|
|
5
|
+
# License : MIT
|
|
6
|
+
# -----------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
# -----------------------------------------------------------------------------
|
|
11
|
+
# VERSION & TOOL NAME
|
|
12
|
+
# -----------------------------------------------------------------------------
|
|
13
|
+
readonly VERSION="1.0.0"
|
|
14
|
+
readonly TOOL="theamify"
|
|
15
|
+
|
|
16
|
+
# -----------------------------------------------------------------------------
|
|
17
|
+
# DETECT INSTALL LOCATION (dev clone vs system install)
|
|
18
|
+
# -----------------------------------------------------------------------------
|
|
19
|
+
_SCRIPT_DIR="$(cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")" && pwd)"
|
|
20
|
+
if [[ -f "${_SCRIPT_DIR}/lib/colors.sh" ]]; then
|
|
21
|
+
INSTALL_DIR="${_SCRIPT_DIR}"
|
|
22
|
+
elif [[ -f "/usr/local/share/${TOOL}/lib/colors.sh" ]]; then
|
|
23
|
+
INSTALL_DIR="/usr/local/share/${TOOL}"
|
|
24
|
+
else
|
|
25
|
+
echo "ERROR: Cannot locate theamify installation. Run install.sh first." >&2
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
readonly INSTALL_DIR
|
|
29
|
+
|
|
30
|
+
# -----------------------------------------------------------------------------
|
|
31
|
+
# PATH CONSTANTS
|
|
32
|
+
# -----------------------------------------------------------------------------
|
|
33
|
+
readonly LIB_DIR="${INSTALL_DIR}/lib"
|
|
34
|
+
readonly CONFIG_DIR="${INSTALL_DIR}/config"
|
|
35
|
+
readonly THEMES_CACHE_DIR="${INSTALL_DIR}/themes"
|
|
36
|
+
readonly REPO_CACHE_DIR="${INSTALL_DIR}/.repo_cache"
|
|
37
|
+
readonly THEMES_CONF="${CONFIG_DIR}/themes.conf"
|
|
38
|
+
readonly GRUB_CFG="/etc/default/grub"
|
|
39
|
+
|
|
40
|
+
# -----------------------------------------------------------------------------
|
|
41
|
+
# GLOBAL FLAGS
|
|
42
|
+
# -----------------------------------------------------------------------------
|
|
43
|
+
OPT_YES=false
|
|
44
|
+
OPT_QUIET=false
|
|
45
|
+
OPT_VERBOSE=false
|
|
46
|
+
|
|
47
|
+
# -----------------------------------------------------------------------------
|
|
48
|
+
# SOURCE LIBRARIES
|
|
49
|
+
# -----------------------------------------------------------------------------
|
|
50
|
+
# shellcheck source=lib/colors.sh
|
|
51
|
+
source "${LIB_DIR}/colors.sh"
|
|
52
|
+
# shellcheck source=lib/utils.sh
|
|
53
|
+
source "${LIB_DIR}/utils.sh"
|
|
54
|
+
# shellcheck source=lib/grub.sh
|
|
55
|
+
source "${LIB_DIR}/grub.sh"
|
|
56
|
+
# shellcheck source=lib/themes.sh
|
|
57
|
+
source "${LIB_DIR}/themes.sh"
|
|
58
|
+
|
|
59
|
+
# -----------------------------------------------------------------------------
|
|
60
|
+
# VALIDATE REGISTRY
|
|
61
|
+
# -----------------------------------------------------------------------------
|
|
62
|
+
[[ -f "${THEMES_CONF}" ]] || {
|
|
63
|
+
echo "ERROR: Theme registry missing: ${THEMES_CONF}" >&2
|
|
64
|
+
echo " Re-run install.sh to restore." >&2
|
|
65
|
+
exit 1
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
# =============================================================================
|
|
69
|
+
# COMMAND: help
|
|
70
|
+
# =============================================================================
|
|
71
|
+
cmd_help() {
|
|
72
|
+
print_banner
|
|
73
|
+
echo -e "${C_TITLE}USAGE${RESET}"
|
|
74
|
+
echo -e " ${BOLD_WHITE}${TOOL}${RESET} ${C_INFO}[COMMAND]${RESET} ${C_DIM}[OPTIONS]${RESET}\n"
|
|
75
|
+
|
|
76
|
+
echo -e "${C_TITLE}COMMANDS${RESET}"
|
|
77
|
+
_help_row "list" "List all themes with status"
|
|
78
|
+
_help_row "info <name>" "Show full details for a theme"
|
|
79
|
+
_help_row "get <name>" "Download & cache a theme"
|
|
80
|
+
_help_row "get --all" "Download every theme"
|
|
81
|
+
_help_row "use <name>" "Apply theme to GRUB ${C_WARNING}[sudo]${RESET}"
|
|
82
|
+
_help_row "remove <name>" "Remove theme from local cache"
|
|
83
|
+
_help_row "add <github-url>" "Add a new theme to the registry"
|
|
84
|
+
_help_row "del <name>" "Delete theme from registry"
|
|
85
|
+
_help_row "update" "Re-download all cached themes"
|
|
86
|
+
_help_row "update <name>" "Re-download one theme"
|
|
87
|
+
_help_row "status" "Show GRUB & system status"
|
|
88
|
+
_help_row "open <name>" "Open theme source page in browser"
|
|
89
|
+
_help_row "clean" "Clear the repo clone cache"
|
|
90
|
+
_help_row "help" "Show this help screen"
|
|
91
|
+
_help_row "version" "Print version"
|
|
92
|
+
|
|
93
|
+
echo -e "\n${C_TITLE}OPTIONS${RESET}"
|
|
94
|
+
_help_row "-y, --yes" "Auto-confirm all prompts"
|
|
95
|
+
_help_row "-q, --quiet" "Suppress non-essential output"
|
|
96
|
+
_help_row "-v, --verbose" "Verbose output"
|
|
97
|
+
_help_row "--no-color" "Disable ANSI colors"
|
|
98
|
+
|
|
99
|
+
echo -e "\n${C_DIM} (no command) -> launches the interactive TUI menu${RESET}\n"
|
|
100
|
+
}
|
|
101
|
+
_help_row() { printf " ${C_HIGHLIGHT}%-22s${RESET} ${C_DIM}%b${RESET}\n" "${1}" "${2}"; }
|
|
102
|
+
|
|
103
|
+
# =============================================================================
|
|
104
|
+
# COMMAND: list
|
|
105
|
+
# =============================================================================
|
|
106
|
+
cmd_list() {
|
|
107
|
+
local active
|
|
108
|
+
active="$(grub_get_active_theme)"
|
|
109
|
+
local total=0 cached=0
|
|
110
|
+
|
|
111
|
+
print_banner
|
|
112
|
+
echo -e "${C_TITLE}${BOLD}THEME REGISTRY${RESET}"
|
|
113
|
+
print_rule "-"
|
|
114
|
+
echo
|
|
115
|
+
|
|
116
|
+
local idx=0
|
|
117
|
+
while IFS='|' read -r name _ _ desc source tags; do
|
|
118
|
+
[[ "${name}" =~ ^[[:space:]]*$ || "${name}" =~ ^# ]] && continue
|
|
119
|
+
(( ++idx )); (( ++total ))
|
|
120
|
+
|
|
121
|
+
local status="remote"
|
|
122
|
+
[[ -d "${THEMES_CACHE_DIR}/${name}" ]] && status="cached" && (( ++cached ))
|
|
123
|
+
[[ "${name}" == "${active}" ]] && status="active"
|
|
124
|
+
|
|
125
|
+
local tag_list
|
|
126
|
+
tag_list="$(echo "${tags}" | tr ',' ' ')"
|
|
127
|
+
|
|
128
|
+
echo -e " ${C_NUM}${idx}.${RESET} ${C_HIGHLIGHT}${name}${RESET} $(print_status "${status}")"
|
|
129
|
+
echo -e " ${C_DIM}${desc}${RESET}"
|
|
130
|
+
echo -e " ${C_DIM}tags:${RESET} ${C_TAG}${tag_list}${RESET}"
|
|
131
|
+
echo
|
|
132
|
+
done < <(parse_conf)
|
|
133
|
+
|
|
134
|
+
print_rule "-"
|
|
135
|
+
echo -e " ${C_DIM}Registry:${RESET} ${C_NUM}${total}${RESET} ${C_DIM}themes Cached:${RESET} ${C_ACTIVE}${cached}${RESET} ${C_DIM}Active:${RESET} ${C_ACTIVE}${active:-none}${RESET}"
|
|
136
|
+
echo -e " ${C_DIM}Run${RESET} ${C_CMD}${TOOL} info <name>${RESET} ${C_DIM}for details,${RESET} ${C_CMD}sudo ${TOOL} use <name>${RESET} ${C_DIM}to apply${RESET}"
|
|
137
|
+
echo
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
# =============================================================================
|
|
141
|
+
# COMMAND: info
|
|
142
|
+
# =============================================================================
|
|
143
|
+
cmd_info() {
|
|
144
|
+
local name="${1:-}"
|
|
145
|
+
[[ -z "${name}" ]] && { print_error "Usage: ${TOOL} info <name>"; exit 1; }
|
|
146
|
+
|
|
147
|
+
local line
|
|
148
|
+
line="$(theme_get_entry "${name}")" || {
|
|
149
|
+
print_error "Theme '${name}' not found in registry."
|
|
150
|
+
print_info "Run '${TOOL} list' to see all themes."
|
|
151
|
+
exit 1
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
IFS='|' read -r t_name t_url t_sub t_desc t_source t_tags <<< "${line}"
|
|
155
|
+
|
|
156
|
+
local active; active="$(grub_get_active_theme)"
|
|
157
|
+
local cached="${THEMES_CACHE_DIR}/${t_name}"
|
|
158
|
+
local status="remote"
|
|
159
|
+
[[ -d "${cached}" ]] && status="cached"
|
|
160
|
+
[[ "${t_name}" == "${active}" ]] && status="active"
|
|
161
|
+
|
|
162
|
+
echo
|
|
163
|
+
print_box_title " ${t_name} "
|
|
164
|
+
echo
|
|
165
|
+
|
|
166
|
+
print_kv "Name" "${BOLD_WHITE}${t_name}${RESET}"
|
|
167
|
+
print_kv "Status" "$(print_status "${status}")"
|
|
168
|
+
print_kv "Description" "${t_desc}"
|
|
169
|
+
print_kv "Tags" "${C_TAG}${t_tags//,/, }${RESET}"
|
|
170
|
+
print_kv "Repository" "${C_LINK}${t_url}${RESET}"
|
|
171
|
+
print_kv "Source Page" "${C_LINK}${t_source}${RESET}"
|
|
172
|
+
[[ "${t_sub}" != "." ]] && print_kv "Subdir" "${C_DIM}${t_sub}${RESET}"
|
|
173
|
+
|
|
174
|
+
if [[ -d "${cached}" ]]; then
|
|
175
|
+
print_kv "Local Cache" "${C_DIM}${cached}${RESET}"
|
|
176
|
+
local txt
|
|
177
|
+
txt="$(find_theme_txt "${cached}")" && print_kv "theme.txt" "${C_DIM}${txt}${RESET}" || true
|
|
178
|
+
# Preview via chafa
|
|
179
|
+
if command -v chafa &>/dev/null; then
|
|
180
|
+
local img
|
|
181
|
+
img="$(find "${cached}" -maxdepth 3 \( -name "*.png" -o -name "*.jpg" \) \
|
|
182
|
+
-not -path "*/.git/*" 2>/dev/null | sort | head -1 || true)"
|
|
183
|
+
if [[ -n "${img}" ]]; then
|
|
184
|
+
echo -e "\n${C_SECTION} Preview:${RESET}"
|
|
185
|
+
chafa --size 60x18 "${img}" 2>/dev/null || true
|
|
186
|
+
fi
|
|
187
|
+
fi
|
|
188
|
+
fi
|
|
189
|
+
|
|
190
|
+
echo
|
|
191
|
+
echo -e " ${C_DIM}Quick actions:${RESET}"
|
|
192
|
+
if [[ "${status}" == "remote" ]]; then
|
|
193
|
+
echo -e " ${C_CMD}${TOOL} get ${t_name}${RESET} - download"
|
|
194
|
+
else
|
|
195
|
+
echo -e " ${C_CMD}sudo ${TOOL} use ${t_name}${RESET} - apply to GRUB"
|
|
196
|
+
echo -e " ${C_CMD}${TOOL} remove ${t_name}${RESET} - clear cache"
|
|
197
|
+
echo -e " ${C_CMD}${TOOL} update ${t_name}${RESET} - re-download"
|
|
198
|
+
fi
|
|
199
|
+
echo -e " ${C_CMD}${TOOL} open ${t_name}${RESET} - open in browser"
|
|
200
|
+
echo
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
# =============================================================================
|
|
204
|
+
# COMMAND: get
|
|
205
|
+
# =============================================================================
|
|
206
|
+
cmd_get() {
|
|
207
|
+
local target="${1:-}"
|
|
208
|
+
[[ -z "${target}" ]] && { print_error "Usage: ${TOOL} get <name>|--all"; exit 1; }
|
|
209
|
+
|
|
210
|
+
if [[ "${target}" == "--all" ]]; then
|
|
211
|
+
print_section "Downloading All Themes"
|
|
212
|
+
local total=0 ok=0
|
|
213
|
+
while IFS='|' read -r t_name _; do
|
|
214
|
+
(( ++total ))
|
|
215
|
+
echo; theme_download "${t_name}" && (( ++ok )) || true
|
|
216
|
+
done < <(parse_conf)
|
|
217
|
+
echo
|
|
218
|
+
print_success "Downloaded ${ok}/${total} themes."
|
|
219
|
+
return
|
|
220
|
+
fi
|
|
221
|
+
|
|
222
|
+
theme_download "${target}"
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
# =============================================================================
|
|
226
|
+
# COMMAND: use (needs root)
|
|
227
|
+
# =============================================================================
|
|
228
|
+
cmd_use() {
|
|
229
|
+
local name="${1:-}"
|
|
230
|
+
[[ -z "${name}" ]] && { print_error "Usage: sudo ${TOOL} use <name>"; exit 1; }
|
|
231
|
+
|
|
232
|
+
require_root "${TOOL} use"
|
|
233
|
+
theme_get_entry "${name}" &>/dev/null || {
|
|
234
|
+
print_error "Theme '${name}' not found in registry."
|
|
235
|
+
print_info "Run '${TOOL} list' to see available themes."
|
|
236
|
+
exit 1
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
# Auto-download if not cached
|
|
240
|
+
if [[ ! -d "${THEMES_CACHE_DIR}/${name}" ]]; then
|
|
241
|
+
print_warning "Theme '${name}' is not cached. Downloading now..."
|
|
242
|
+
echo
|
|
243
|
+
theme_download "${name}"
|
|
244
|
+
fi
|
|
245
|
+
|
|
246
|
+
grub_apply_theme "${name}"
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
# =============================================================================
|
|
250
|
+
# COMMAND: remove
|
|
251
|
+
# =============================================================================
|
|
252
|
+
cmd_remove() {
|
|
253
|
+
local name="${1:-}"
|
|
254
|
+
[[ -z "${name}" ]] && { print_error "Usage: ${TOOL} remove <name>"; exit 1; }
|
|
255
|
+
theme_remove_cache "${name}"
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
# =============================================================================
|
|
259
|
+
# COMMAND: add
|
|
260
|
+
# =============================================================================
|
|
261
|
+
cmd_add() {
|
|
262
|
+
local url="${1:-}"
|
|
263
|
+
[[ -z "${url}" ]] && { print_error "Usage: ${TOOL} add <github-url>"; exit 1; }
|
|
264
|
+
theme_add_to_registry "${url}"
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
# =============================================================================
|
|
268
|
+
# COMMAND: del
|
|
269
|
+
# =============================================================================
|
|
270
|
+
cmd_del() {
|
|
271
|
+
local name="${1:-}"
|
|
272
|
+
[[ -z "${name}" ]] && { print_error "Usage: ${TOOL} del <name>"; exit 1; }
|
|
273
|
+
theme_delete_from_registry "${name}"
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
# =============================================================================
|
|
277
|
+
# COMMAND: update
|
|
278
|
+
# =============================================================================
|
|
279
|
+
cmd_update() {
|
|
280
|
+
local name="${1:-}"
|
|
281
|
+
|
|
282
|
+
if [[ -z "${name}" ]]; then
|
|
283
|
+
print_section "Updating All Cached Themes"
|
|
284
|
+
local updated=0
|
|
285
|
+
while IFS='|' read -r t_name _; do
|
|
286
|
+
[[ -d "${THEMES_CACHE_DIR}/${t_name}" ]] || continue
|
|
287
|
+
echo; theme_download "${t_name}" --force && (( ++updated )) || true
|
|
288
|
+
done < <(parse_conf)
|
|
289
|
+
echo
|
|
290
|
+
if (( updated == 0 )); then
|
|
291
|
+
print_info "No cached themes found. Run '${TOOL} get --all' first."
|
|
292
|
+
else
|
|
293
|
+
print_success "Updated ${updated} theme(s)."
|
|
294
|
+
fi
|
|
295
|
+
else
|
|
296
|
+
theme_download "${name}" --force
|
|
297
|
+
fi
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
# =============================================================================
|
|
301
|
+
# COMMAND: status
|
|
302
|
+
# =============================================================================
|
|
303
|
+
cmd_status() {
|
|
304
|
+
echo
|
|
305
|
+
print_box_title " SYSTEM STATUS "
|
|
306
|
+
echo
|
|
307
|
+
|
|
308
|
+
print_section "GRUB"
|
|
309
|
+
local grub_dir; grub_dir="$(grub_detect_dir)"
|
|
310
|
+
local active; active="$(grub_get_active_theme)"
|
|
311
|
+
print_kv "Themes dir" "${C_DIM}${grub_dir}${RESET}"
|
|
312
|
+
print_kv "Active theme" "${C_ACTIVE}${active:-none}${RESET}"
|
|
313
|
+
local timeout
|
|
314
|
+
timeout="$(grep -E '^GRUB_TIMEOUT=' "${GRUB_CFG}" 2>/dev/null | cut -d= -f2 | tr -d '"' || echo 'not set')"
|
|
315
|
+
print_kv "Timeout" "${timeout}s"
|
|
316
|
+
|
|
317
|
+
print_section "Dependencies"
|
|
318
|
+
local required=("git")
|
|
319
|
+
local optional=("wget" "curl" "chafa" "xdg-open")
|
|
320
|
+
local grub_cmds=("update-grub" "grub-mkconfig" "grub2-mkconfig")
|
|
321
|
+
for dep in "${required[@]}"; do
|
|
322
|
+
_dep_row "${dep}" "required"
|
|
323
|
+
done
|
|
324
|
+
for dep in "${optional[@]}"; do
|
|
325
|
+
_dep_row "${dep}" "optional"
|
|
326
|
+
done
|
|
327
|
+
for dep in "${grub_cmds[@]}"; do
|
|
328
|
+
_dep_row "${dep}" "grub"
|
|
329
|
+
done
|
|
330
|
+
|
|
331
|
+
print_section "Theme Cache"
|
|
332
|
+
local total=0 cached=0
|
|
333
|
+
while IFS='|' read -r t_name _; do
|
|
334
|
+
(( ++total ))
|
|
335
|
+
[[ -d "${THEMES_CACHE_DIR}/${t_name}" ]] && (( ++cached ))
|
|
336
|
+
done < <(parse_conf)
|
|
337
|
+
print_kv "Registry" "${total} themes"
|
|
338
|
+
print_kv "Cached" "${C_ACTIVE}${cached}${RESET} / ${total}"
|
|
339
|
+
print_kv "Cache dir" "${C_DIM}${THEMES_CACHE_DIR}${RESET}"
|
|
340
|
+
print_kv "Repo cache" "${C_DIM}${REPO_CACHE_DIR}${RESET}"
|
|
341
|
+
echo
|
|
342
|
+
}
|
|
343
|
+
_dep_row() {
|
|
344
|
+
local dep="${1}" kind="${2}" tag tag_color note
|
|
345
|
+
if command -v "${dep}" &>/dev/null; then
|
|
346
|
+
printf " %s%-9s%s %-22s %s%s%s\n" \
|
|
347
|
+
"${C_SUCCESS}" "[OK]" "${RESET}" "${dep}" "${C_DIM}" "$(command -v "${dep}")" "${RESET}"
|
|
348
|
+
return
|
|
349
|
+
fi
|
|
350
|
+
case "${kind}" in
|
|
351
|
+
required) tag="[MISSING]"; tag_color="${C_ERROR}"; note="required" ;;
|
|
352
|
+
optional) tag="[ -- ]"; tag_color="${C_DIM}"; note="not found (optional)" ;;
|
|
353
|
+
grub) tag="[ -- ]"; tag_color="${C_DIM}"; note="not found" ;;
|
|
354
|
+
esac
|
|
355
|
+
printf " %s%-9s%s %-22s %s%s%s\n" "${tag_color}" "${tag}" "${RESET}" "${dep}" "${C_DIM}" "${note}" "${RESET}"
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
# =============================================================================
|
|
359
|
+
# COMMAND: open
|
|
360
|
+
# =============================================================================
|
|
361
|
+
cmd_open() {
|
|
362
|
+
local name="${1:-}"
|
|
363
|
+
[[ -z "${name}" ]] && { print_error "Usage: ${TOOL} open <name>"; exit 1; }
|
|
364
|
+
|
|
365
|
+
local line
|
|
366
|
+
line="$(theme_get_entry "${name}")" || {
|
|
367
|
+
print_error "Theme '${name}' not found."
|
|
368
|
+
exit 1
|
|
369
|
+
}
|
|
370
|
+
local t_source
|
|
371
|
+
t_source="$(echo "${line}" | cut -d'|' -f5)"
|
|
372
|
+
|
|
373
|
+
if [[ -z "${t_source}" || "${t_source}" == "none" ]]; then
|
|
374
|
+
print_warning "No source URL for theme '${name}'."
|
|
375
|
+
return
|
|
376
|
+
fi
|
|
377
|
+
|
|
378
|
+
open_url "${t_source}"
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
# =============================================================================
|
|
382
|
+
# COMMAND: clean
|
|
383
|
+
# =============================================================================
|
|
384
|
+
cmd_clean() {
|
|
385
|
+
if [[ -d "${REPO_CACHE_DIR}" ]]; then
|
|
386
|
+
local size; size="$(du -sh "${REPO_CACHE_DIR}" 2>/dev/null | cut -f1)"
|
|
387
|
+
print_warning "This will delete the repo clone cache (${size})."
|
|
388
|
+
if confirm "Clear repo cache?"; then
|
|
389
|
+
rm -rf "${REPO_CACHE_DIR}"
|
|
390
|
+
mkdir -p "${REPO_CACHE_DIR}"
|
|
391
|
+
print_success "Repo cache cleared."
|
|
392
|
+
fi
|
|
393
|
+
else
|
|
394
|
+
print_info "Repo cache is already empty."
|
|
395
|
+
fi
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
# =============================================================================
|
|
399
|
+
# INTERACTIVE MENU (TUI)
|
|
400
|
+
# Layout borrows the grouped, single-column list style used by GitSwitch:
|
|
401
|
+
# short section labels, one option per line, no multi-column alignment to
|
|
402
|
+
# break.
|
|
403
|
+
# =============================================================================
|
|
404
|
+
cmd_interactive() {
|
|
405
|
+
while true; do
|
|
406
|
+
clear
|
|
407
|
+
print_banner
|
|
408
|
+
|
|
409
|
+
local active; active="$(grub_get_active_theme)"
|
|
410
|
+
local total=0 cached=0
|
|
411
|
+
while IFS='|' read -r t _; do
|
|
412
|
+
(( ++total ))
|
|
413
|
+
[[ -d "${THEMES_CACHE_DIR}/${t}" ]] && (( ++cached ))
|
|
414
|
+
done < <(parse_conf)
|
|
415
|
+
|
|
416
|
+
echo -e " ${C_DIM}Active theme :${RESET} ${C_ACTIVE}${active:-none}${RESET}"
|
|
417
|
+
echo -e " ${C_DIM}Themes cached:${RESET} ${C_INFO}${cached}${RESET}${C_DIM}/${total}${RESET}"
|
|
418
|
+
echo
|
|
419
|
+
print_rule "-"
|
|
420
|
+
echo
|
|
421
|
+
echo -e " ${BOLD}Browse${RESET}"
|
|
422
|
+
echo -e " ${C_NUM}1)${RESET} List All Themes"
|
|
423
|
+
echo -e " ${C_NUM}2)${RESET} Browse & Apply Theme"
|
|
424
|
+
echo
|
|
425
|
+
echo -e " ${BOLD}Download & Sync${RESET}"
|
|
426
|
+
echo -e " ${C_NUM}3)${RESET} Download All Themes"
|
|
427
|
+
echo -e " ${C_NUM}4)${RESET} Update Cached Themes"
|
|
428
|
+
echo
|
|
429
|
+
echo -e " ${BOLD}Registry${RESET}"
|
|
430
|
+
echo -e " ${C_NUM}5)${RESET} Add New Theme"
|
|
431
|
+
echo -e " ${C_NUM}6)${RESET} Delete Theme from Registry"
|
|
432
|
+
echo
|
|
433
|
+
echo -e " ${BOLD}System${RESET}"
|
|
434
|
+
echo -e " ${C_NUM}7)${RESET} System Status"
|
|
435
|
+
echo -e " ${C_NUM}8)${RESET} Clean Repo Cache"
|
|
436
|
+
echo
|
|
437
|
+
echo -e " ${C_NUM}q)${RESET} Quit"
|
|
438
|
+
echo
|
|
439
|
+
print_rule "-"
|
|
440
|
+
echo
|
|
441
|
+
echo -ne " ${C_PROMPT}Choice:${RESET} "
|
|
442
|
+
read -r choice
|
|
443
|
+
echo
|
|
444
|
+
|
|
445
|
+
case "${choice}" in
|
|
446
|
+
1) cmd_list; _pause ;;
|
|
447
|
+
2) _interactive_apply ;;
|
|
448
|
+
3) cmd_get "--all"; _pause ;;
|
|
449
|
+
4) cmd_update; _pause ;;
|
|
450
|
+
5)
|
|
451
|
+
echo -ne " ${C_PROMPT}GitHub URL:${RESET} "; read -r url
|
|
452
|
+
cmd_add "${url}"; _pause
|
|
453
|
+
;;
|
|
454
|
+
6)
|
|
455
|
+
echo -ne " ${C_PROMPT}Theme name to delete:${RESET} "; read -r nm
|
|
456
|
+
cmd_del "${nm}"; _pause
|
|
457
|
+
;;
|
|
458
|
+
7) cmd_status; _pause ;;
|
|
459
|
+
8) cmd_clean; _pause ;;
|
|
460
|
+
q|Q|quit|exit)
|
|
461
|
+
echo -e "\n${C_DIM} Goodbye!${RESET}\n"
|
|
462
|
+
exit 0 ;;
|
|
463
|
+
*)
|
|
464
|
+
print_warning "Invalid choice: '${choice}'"
|
|
465
|
+
sleep 1 ;;
|
|
466
|
+
esac
|
|
467
|
+
done
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
_interactive_apply() {
|
|
471
|
+
clear
|
|
472
|
+
echo -e "${C_TITLE}${BOLD}BROWSE & APPLY THEME${RESET}"
|
|
473
|
+
print_rule "-"
|
|
474
|
+
echo
|
|
475
|
+
|
|
476
|
+
local active; active="$(grub_get_active_theme)"
|
|
477
|
+
local -a names=()
|
|
478
|
+
local idx=0
|
|
479
|
+
|
|
480
|
+
while IFS='|' read -r t_name _ _ t_desc _ t_tags; do
|
|
481
|
+
names+=("${t_name}")
|
|
482
|
+
(( ++idx ))
|
|
483
|
+
local status="remote"
|
|
484
|
+
[[ -d "${THEMES_CACHE_DIR}/${t_name}" ]] && status="cached"
|
|
485
|
+
[[ "${t_name}" == "${active}" ]] && status="active"
|
|
486
|
+
|
|
487
|
+
echo -e " ${C_NUM}${idx})${RESET} ${C_HIGHLIGHT}${t_name}${RESET} $(print_status "${status}")"
|
|
488
|
+
echo -e " ${C_DIM}${t_desc}${RESET}"
|
|
489
|
+
done < <(parse_conf)
|
|
490
|
+
|
|
491
|
+
echo
|
|
492
|
+
echo -ne " ${C_PROMPT}Enter number (or 'q' to cancel):${RESET} "
|
|
493
|
+
read -r choice
|
|
494
|
+
|
|
495
|
+
[[ "${choice}" =~ ^[qQ]$ ]] && return
|
|
496
|
+
|
|
497
|
+
if ! [[ "${choice}" =~ ^[0-9]+$ ]] || \
|
|
498
|
+
(( choice < 1 || choice > ${#names[@]} )); then
|
|
499
|
+
print_error "Invalid selection."
|
|
500
|
+
_pause; return
|
|
501
|
+
fi
|
|
502
|
+
|
|
503
|
+
local selected="${names[$((choice-1))]}"
|
|
504
|
+
echo
|
|
505
|
+
print_info "Selected: ${BOLD_WHITE}${selected}${RESET}"
|
|
506
|
+
confirm "Apply theme '${selected}' to GRUB?" || { print_info "Cancelled."; _pause; return; }
|
|
507
|
+
|
|
508
|
+
if [[ "${EUID}" -ne 0 ]]; then
|
|
509
|
+
print_warning "Root is required. Re-running with sudo..."
|
|
510
|
+
sudo "${BASH_SOURCE[0]}" use "${selected}"
|
|
511
|
+
else
|
|
512
|
+
cmd_use "${selected}"
|
|
513
|
+
fi
|
|
514
|
+
_pause
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
_pause() {
|
|
518
|
+
echo
|
|
519
|
+
echo -ne "${C_DIM} Press [Enter] to continue...${RESET}"
|
|
520
|
+
read -r
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
# =============================================================================
|
|
524
|
+
# MAIN - argument router
|
|
525
|
+
# =============================================================================
|
|
526
|
+
main() {
|
|
527
|
+
# -- strip global flags --------------------------------------------------
|
|
528
|
+
local args=()
|
|
529
|
+
for arg in "$@"; do
|
|
530
|
+
case "${arg}" in
|
|
531
|
+
-y|--yes) OPT_YES=true ;;
|
|
532
|
+
-q|--quiet) OPT_QUIET=true ;;
|
|
533
|
+
-v|--verbose) OPT_VERBOSE=true ;;
|
|
534
|
+
--no-color) export NO_COLOR=1 ;;
|
|
535
|
+
*) args+=("${arg}") ;;
|
|
536
|
+
esac
|
|
537
|
+
done
|
|
538
|
+
set -- "${args[@]+"${args[@]}"}"
|
|
539
|
+
|
|
540
|
+
local cmd="${1:-}"
|
|
541
|
+
(( $# > 0 )) && shift || true
|
|
542
|
+
|
|
543
|
+
case "${cmd}" in
|
|
544
|
+
"") cmd_interactive ;;
|
|
545
|
+
list|ls) cmd_list ;;
|
|
546
|
+
info|show) cmd_info "${1:-}" ;;
|
|
547
|
+
get|fetch|download) cmd_get "${1:-}" ;;
|
|
548
|
+
use|apply|set) cmd_use "${1:-}" ;;
|
|
549
|
+
remove|rm|uncache) cmd_remove "${1:-}" ;;
|
|
550
|
+
add) cmd_add "${1:-}" ;;
|
|
551
|
+
del|delete) cmd_del "${1:-}" ;;
|
|
552
|
+
update) cmd_update "${1:-}" ;;
|
|
553
|
+
status|check) cmd_status ;;
|
|
554
|
+
open|browse) cmd_open "${1:-}" ;;
|
|
555
|
+
clean|purge-cache) cmd_clean ;;
|
|
556
|
+
help|-h|--help) cmd_help ;;
|
|
557
|
+
version|-V|--version) echo "${TOOL} v${VERSION}" ;;
|
|
558
|
+
*)
|
|
559
|
+
print_error "Unknown command: '${cmd}'"
|
|
560
|
+
echo -e " ${C_DIM}Run ${C_CMD}${TOOL} help${RESET}${C_DIM} to see all commands.${RESET}\n"
|
|
561
|
+
exit 1 ;;
|
|
562
|
+
esac
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
main "$@"
|