Files
MiniServer/configure
T

157 lines
3.7 KiB
Bash
Executable File

#!/bin/bash
#
# Purpose : Set up the things MiniServer installs that need your input:
# mounting your Nextcloud files and signing in to the AI agents.
#
# Each file in configure.d/ is one item. It sets TITLE and DESCRIPTION and
# defines is_configured and run_configure. It can also define is_installed;
# the item is left out when that fails. To add an item, add a file there.
# Wrapped in { ...; exit; } so bash reads the whole script up front; update
# replaces this file while it runs.
{
MINISERVER="$HOME/.local/share/MiniServer"
PATH="$HOME/.local/bin:$PATH"
# Run an agent's real command rather than its sandboxed one in sandbox/bin:
# setting an agent up writes outside its sandbox
unsandboxed() {
"$MINISERVER/sandbox/bin/unsandboxed" "$@"
}
# Ask a yes/no question; the default is no
confirm() {
local answer
read -rp "$1 [y/N] " answer
[[ "$answer" == [yY]* ]]
}
# Ask a yes/no question; the default is yes
confirm_yes() {
local answer
read -rp "$1 [Y/n] " answer
[[ "$answer" != [nN]* ]]
}
usage() {
cat << EOF
Usage: configure [item]
configure Show what's set up and choose what to set up
configure <item> Set up one item
configure --list Show what's set up, and the item names
EOF
}
# configure.d/30-claude.sh -> claude
item_name() {
local name
name="$(basename "$1" .sh)"
echo "${name#[0-9][0-9]-}"
}
# Prints "<state>|<title>|<description>"; state is done, todo or absent
item_info() {
(
source "$1"
if declare -f is_installed > /dev/null && ! is_installed &> /dev/null; then
echo "absent||"
elif is_configured &> /dev/null; then
echo "done|$TITLE|$DESCRIPTION"
else
echo "todo|$TITLE|$DESCRIPTION"
fi
)
}
configure_item() {
(
source "$1"
echo
echo -e "\e[1m$TITLE\e[0m"
run_configure
)
local status=$?
if [ $status -ne 0 ]; then
echo -e "\e[31m$(item_name "$1") was not set up.\e[0m"
fi
return $status
}
# Fill ITEMS, STATES, TITLES and DESCRIPTIONS with the installed items
load_items() {
local file state title description
ITEMS=() STATES=() TITLES=() DESCRIPTIONS=()
for file in "$MINISERVER"/configure.d/*.sh; do
[ -f "$file" ] || continue
IFS='|' read -r state title description < <(item_info "$file")
[ "$state" = absent ] && continue
ITEMS+=("$file") STATES+=("$state") TITLES+=("$title") DESCRIPTIONS+=("$description")
done
}
show_items() {
local i mark
for i in "${!ITEMS[@]}"; do
if [ "${STATES[$i]}" = done ]; then
mark="\e[32mdone\e[0m "
else
mark="\e[33mto do\e[0m"
fi
printf " %2d) $mark %-22s %s\n" $((i + 1)) "${TITLES[$i]}" "${DESCRIPTIONS[$i]}"
done
}
case "$1" in
"") ;;
-h|--help)
usage
exit 0 ;;
-l|--list)
load_items
for i in "${!ITEMS[@]}"; do
printf '%-6s %-14s %s\n' "${STATES[$i]/todo/to do}" "$(item_name "${ITEMS[$i]}")" "${TITLES[$i]}"
done
exit 0 ;;
*)
for file in "$MINISERVER"/configure.d/*.sh; do
if [ "$(item_name "$file")" = "$1" ]; then
configure_item "$file"
exit
fi
done
echo "No item named $1. These are: configure --list"
exit 2 ;;
esac
while true; do
load_items
echo
echo "MiniServer configuration"
echo
show_items
echo
echo " a) Set up everything still to do"
echo " q) Quit"
echo
read -rp "Choose: " choice || exit 0
case "$choice" in
q|Q|"")
exit 0 ;;
a|A)
for i in "${!ITEMS[@]}"; do
[ "${STATES[$i]}" = todo ] && configure_item "${ITEMS[$i]}"
done ;;
*)
if [[ "$choice" =~ ^[0-9]+$ ]] && (( choice >= 1 && choice <= ${#ITEMS[@]} )); then
configure_item "${ITEMS[$((choice - 1))]}"
else
echo "Choose a number from the list, a or q."
fi ;;
esac
done
}