Files
Modular-Bashrc-Manager/installer/scripts-needed/brc-script.sh
T

788 lines
26 KiB
Bash
Executable File

#!/bin/bash
###############
### OPTIONS ###
###############
editor="${EDITOR:-vim}"
#################
### VARIABLES ###
#################
home_folder="$HOME/"
main_folder="${home_folder}.bashrc.d"
available_scripts="${main_folder}/scripts-available/"
enabled_scripts="${main_folder}/scripts-enabled/"
needed_scripts="${main_folder}/scripts-needed/"
bin_folder="${main_folder}/scripts-removed/"
bashrc="${home_folder}.bashrc"
version_file="${main_folder}/.version"
update_cache="${main_folder}/.update_cache"
# Gitea Repository Config
GITEA_REPO_URL="https://gitea.sld-server.org/sld-admin/Modular-Bashrc-Manager"
GITEA_API_URL="https://gitea.sld-server.org/api/v1/repos/sld-admin/Modular-Bashrc-Manager"
GITEA_RAW_URL="https://gitea.sld-server.org/sld-admin/Modular-Bashrc-Manager/raw/branch/master"
#################
### FUNCTIONS ###
#################
# Load ccecho if not available
if ! command -v ccecho >/dev/null 2>&1; then
if [ -f "${needed_scripts}ccecho.sh" ]; then
# shellcheck disable=SC1090
source "${needed_scripts}ccecho.sh"
else
# Fallback simple echo if ccecho is missing
ccecho() {
local msg=""
while [[ $# -gt 0 ]]; do
case "$1" in
-t|--text|-b|--bg|-s|--style) shift 2 2>/dev/null || true ;;
*) msg+="$1 "; shift 2>/dev/null || true ;;
esac
done
echo -e "$msg"
}
fi
fi
# Refresh Bash #
refresh-brc(){
if [ "$1" == "-dis" ]; then
echo "------------------------------------"
ccecho -t bblue "[ Bashrc Refreshed ]"
echo "Disabled scripts have been unloaded from current session config."
echo "------------------------------------"
elif [ "$1" == "-en" ]; then
echo "------------------------------------"
ccecho -t bblue "[ Bashrc Refreshed ]"
echo "------------------------------------"
ccecho -t bgreen -s bold "You can use the new commands from now!"
echo "------------------------------------"
else
ccecho -t bblue "[ Bashrc Refreshed ]"
fi
# shellcheck disable=SC1090
[ -f "$bashrc" ] && source "$bashrc"
}
# Resolve script token (ID number or name) to actual filename in available_scripts
resolve_script_name() {
local token="$1"
[ -z "$token" ] && return 1
# Check if numeric ID
if [[ "$token" =~ ^[0-9]+$ ]]; then
local idx=0
for f in "$available_scripts"*.sh; do
[ -f "$f" ] || continue
idx=$((idx + 1))
if [ "$idx" -eq "$token" ]; then
basename "$f"
return 0
fi
done
return 1
fi
# Check direct filename match
local clean_token="${token%.sh}"
if [ -f "${available_scripts}${clean_token}.sh" ]; then
echo "${clean_token}.sh"
return 0
fi
if [ -f "${available_scripts}${token}" ]; then
echo "${token}"
return 0
fi
# Case-insensitive or partial match
for f in "$available_scripts"*.sh; do
[ -f "$f" ] || continue
local fname
fname=$(basename "$f")
local base="${fname%.sh}"
if [[ "${fname,,}" == "${token,,}" || "${base,,}" == "${clean_token,,}" ]]; then
echo "$fname"
return 0
fi
done
return 1
}
# List all available scripts with index and enabled indicator
listitem() {
local index=0
local has_scripts=0
for f in "$available_scripts"*.sh; do
[ -f "$f" ] || continue
has_scripts=1
local filename
filename=$(basename "$f")
local inotext="${filename%.sh}"
index=$((index + 1))
local enabled=""
if [ -f "${enabled_scripts}${filename}" ] || [ -L "${enabled_scripts}${filename}" ]; then
enabled="-"
fi
if [ "$enabled" == "-" ]; then
printf "%5d | %1s %s\n" "$index" "$(ccecho -t blue -s bold "$enabled")" "$(ccecho -t green "$inotext")"
else
printf "%5d | %1s %s\n" "$index" "$enabled" "$(ccecho -t yellow "$inotext")"
fi
done
if [ "$has_scripts" -eq 0 ]; then
ccecho -t byellow " (No scripts found in ${available_scripts})"
fi
}
# Create a new script
createscript() {
echo "------------------------------------"
echo " Create New Script "
echo "------------------------------------"
read -rp "Name of the script (without .sh): " namenewscript
namenewscript="${namenewscript%.sh}"
if [ -z "$namenewscript" ]; then
ccecho -t bred "Script name cannot be empty!"
return 1
fi
local newscriptav="${available_scripts}${namenewscript}.sh"
if [ -f "$newscriptav" ]; then
ccecho -t byellow "Script already exists!"
else
### INITIALIZATION NEW SCRIPT ###
cat << EOF > "$newscriptav"
#!/bin/bash
### OPTIONS ###
### VARIABLES ###
### FUNCTIONS ###
${namenewscript}() {
# Add your code here!
echo "Executing ${namenewscript}"
}
### EXECUTE ###
EOF
chmod +x "$newscriptav"
if [ "$editor" == "nano" ]; then
nano "$newscriptav"
else
vim "$newscriptav"
fi
if [ $? -ne 0 ]; then
echo "------------------------------------"
echo " Editor aborted!"
echo " Continue or remove $namenewscript?"
echo "------------------------------------"
echo " 1 | Continue "
echo " 2 | Abort and delete "
echo " Def | Continue "
echo "------------------------------------"
read -rp "Choice: " answer
if [ "${answer}x" = "2x" ]; then
rm -f "$newscriptav"
return
fi
fi
echo "------------------------------------"
echo " Script $namenewscript created!"
echo " Do you want to enable it?"
echo "------------------------------------"
echo " 1 | yes "
echo " 2 | no "
echo " Def | no "
echo "------------------------------------"
read -rp "Choice: " answer
if [ "$answer" == "1" ]; then
ln -sf "$newscriptav" "${enabled_scripts}${namenewscript}.sh"
refresh-brc -en
else
ccecho -t byellow "Script saved in available scripts, but not enabled."
fi
fi
}
# Display helper for cat and preview
_display_script() {
local numbered="$1"
shift
local targets=("$@")
local action_title="View / Cat Script"
local prompt_msg="Select script number(s) or name(s) to view: "
if [ "$numbered" -eq 1 ]; then
action_title="Preview Script (Numbered)"
prompt_msg="Select script number(s) or name(s) to preview: "
fi
if [ ${#targets[@]} -eq 0 ]; then
echo "------------------------------------"
echo " $action_title"
echo "------------------------------------"
listitem
echo "------------------------------------"
read -rp "$prompt_msg" input_str
# shellcheck disable=SC2206
targets=($input_str)
fi
if [ ${#targets[@]} -eq 0 ]; then
ccecho -t byellow "No script selected."
return
fi
for target in "${targets[@]}"; do
local resolved
resolved=$(resolve_script_name "$target")
if [ -n "$resolved" ] && [ -f "${available_scripts}${resolved}" ]; then
local full_path="${available_scripts}${resolved}"
local is_enabled="DISABLED"
if [ -f "${enabled_scripts}${resolved}" ] || [ -L "${enabled_scripts}${resolved}" ]; then
is_enabled="ENABLED"
fi
local total_lines
total_lines=$(wc -l < "$full_path")
echo ""
echo "================================================================================"
ccecho -t bcyan -s bold " 📄 SCRIPT: ${resolved} "
ccecho -t white " 📁 Path: ${full_path}"
if [ "$is_enabled" == "ENABLED" ]; then
ccecho -t bgreen " ⚡ Status: ENABLED"
else
ccecho -t byellow " 💤 Status: DISABLED"
fi
ccecho -t white " 📊 Lines: ${total_lines}"
echo "================================================================================"
if [ "$numbered" -eq 1 ]; then
if command -v nl >/dev/null 2>&1; then
nl -ba -w4 -s': ' "$full_path"
else
cat -n "$full_path"
fi
else
cat "$full_path"
fi
echo "================================================================================"
echo ""
else
ccecho -t bred "[ Error: Script '$target' not found in available scripts! ]"
fi
done
}
# Plain Cat of script(s)
catscript() {
_display_script 0 "$@"
}
# Numbered Preview of script(s)
previewscript() {
_display_script 1 "$@"
}
# Enable one or more scripts by ID or Name
enablescript() {
local targets=("$@")
if [ ${#targets[@]} -eq 0 ]; then
echo "------------------------------------"
echo " Enable Scripts "
echo "------------------------------------"
listitem
echo "------------------------------------"
read -rp "Select script number(s) or name(s) to enable (space separated): " input_str
# shellcheck disable=SC2206
targets=($input_str)
fi
if [ ${#targets[@]} -eq 0 ]; then
ccecho -t byellow "No script selected."
return
fi
local changed=0
for target in "${targets[@]}"; do
local resolved
resolved=$(resolve_script_name "$target")
if [ -n "$resolved" ] && [ -f "${available_scripts}${resolved}" ]; then
local script_name="${resolved%.sh}"
if [ -f "${enabled_scripts}${resolved}" ] || [ -L "${enabled_scripts}${resolved}" ]; then
ccecho -t bblue "[ Script $script_name already enabled ]"
else
ln -sf "${available_scripts}${resolved}" "${enabled_scripts}${resolved}"
ccecho -t bgreen -s bold "[ Script $script_name Enabled ]"
changed=1
fi
else
ccecho -t bred "[ Error: Script '$target' not found! ]"
fi
done
if [ $changed -eq 1 ]; then
refresh-brc -en
fi
}
# Enable all scripts
enableallscript() {
echo "------------------------------------"
echo " Enable All Scripts "
echo "------------------------------------"
local count=0
for f in "$available_scripts"*.sh; do
[ -f "$f" ] || continue
local fname
fname=$(basename "$f")
ln -sf "$f" "${enabled_scripts}${fname}"
local inoext="${fname%.sh}"
echo -n "enabled " && ccecho -t green -s underline "$inoext"
count=$((count + 1))
done
echo "------------------------------------"
ccecho -t bgreen -s bold "[ All $count available scripts enabled ]"
refresh-brc -en
}
# Disable one or more scripts by ID or Name
disablescript() {
local targets=("$@")
if [ ${#targets[@]} -eq 0 ]; then
echo "------------------------------------"
echo " Disable Scripts "
echo "------------------------------------"
listitem
echo "------------------------------------"
read -rp "Select script number(s) or name(s) to disable (space separated): " input_str
# shellcheck disable=SC2206
targets=($input_str)
fi
if [ ${#targets[@]} -eq 0 ]; then
ccecho -t byellow "No script selected."
return
fi
local changed=0
for target in "${targets[@]}"; do
local resolved
resolved=$(resolve_script_name "$target")
if [ -n "$resolved" ] && [ -f "${available_scripts}${resolved}" ]; then
local script_name="${resolved%.sh}"
if [ -f "${enabled_scripts}${resolved}" ] || [ -L "${enabled_scripts}${resolved}" ]; then
rm -f "${enabled_scripts}${resolved}"
ccecho -t bmagenta -s bold "[ Script $script_name Disabled ]"
changed=1
else
ccecho -t byellow "[ Script $script_name is not enabled ]"
fi
else
ccecho -t bred "[ Error: Script '$target' not found! ]"
fi
done
if [ $changed -eq 1 ]; then
refresh-brc -dis
fi
}
# Disable all scripts
disableallscript() {
echo "------------------------------------"
echo " Disable All Enabled Scripts "
echo "------------------------------------"
local count=0
for f in "$enabled_scripts"*.sh; do
[ -f "$f" ] || [ -L "$f" ] || continue
local fname
fname=$(basename "$f")
rm -f "$f"
local inoext="${fname%.sh}"
echo -n "disabled " && ccecho -t red -s underline "$inoext"
count=$((count + 1))
done
echo "------------------------------------"
ccecho -t bmagenta -s bold "[ All $count scripts disabled ]"
refresh-brc -dis
}
# Modify a script
managescript_modify() {
local target="$1"
if [ -z "$target" ]; then
echo "###### MODIFY SCRIPT #######"
listitem
echo "------------------------------------"
read -rp "Select index or name to modify: " target
fi
[ -z "$target" ] && return
local resolved
resolved=$(resolve_script_name "$target")
if [ -z "$resolved" ] || [ ! -f "${available_scripts}${resolved}" ]; then
ccecho -t bred "[ Error: Script '$target' not found! ]"
return 1
fi
local target_path="${available_scripts}${resolved}"
if [ "$editor" == "nano" ]; then
nano "$target_path"
elif [ "$editor" == "vim" ]; then
vim "$target_path"
else
echo "------------"
echo " 1 - nano "
echo " 2 - vim "
echo " def - vim "
echo "------------"
read -rp "Choice: " ched
if [ "$ched" == "1" ]; then
nano "$target_path"
else
vim "$target_path"
fi
fi
echo "------------------------------------"
echo "Would you like to rename the script?"
echo "------------------------------------"
echo " 1 | yes "
echo " 2 | no "
echo " default | no "
echo "------------------------------------"
read -rp "Choice: " renscr
if [ "$renscr" == "1" ]; then
read -rp "Insert new name (without .sh): " renamenow
renamenow="${renamenow%.sh}"
if [ -n "$renamenow" ]; then
local wasenabled=0
if [ -f "${enabled_scripts}${resolved}" ] || [ -L "${enabled_scripts}${resolved}" ]; then
rm -f "${enabled_scripts}${resolved}"
wasenabled=1
fi
mv "$target_path" "${available_scripts}${renamenow}.sh"
ccecho -t blue "[ Script $resolved renamed to ${renamenow}.sh ]"
if [ "$wasenabled" -eq 1 ]; then
ln -sf "${available_scripts}${renamenow}.sh" "${enabled_scripts}${renamenow}.sh"
ccecho -t bgreen "[ Script Enabled Again ]"
fi
fi
fi
refresh-brc -en
}
# Remove one or more scripts
removescript() {
local targets=("$@")
if [ ${#targets[@]} -eq 0 ]; then
echo "------------------------------------"
echo " Remove Script "
echo "------------------------------------"
listitem
echo "------------------------------------"
read -rp "Select script number(s) or name(s) to remove (space separated): " input_str
# shellcheck disable=SC2206
targets=($input_str)
fi
if [ ${#targets[@]} -eq 0 ]; then
ccecho -t byellow "No script selected."
return
fi
mkdir -p "$bin_folder"
for target in "${targets[@]}"; do
local resolved
resolved=$(resolve_script_name "$target")
if [ -n "$resolved" ] && [ -f "${available_scripts}${resolved}" ]; then
read -rp "Are you sure you want to remove '$resolved'? (y/N): " confirm_rm
if [[ "$confirm_rm" == "y" || "$confirm_rm" == "Y" ]]; then
if [ -f "${enabled_scripts}${resolved}" ] || [ -L "${enabled_scripts}${resolved}" ]; then
rm -f "${enabled_scripts}${resolved}"
ccecho -t yellow "[ Script $resolved unlinked from enabled ]"
fi
local removed_data="${resolved}-$(date +%F_%H-%M-%S)"
mv "${available_scripts}${resolved}" "${bin_folder}${removed_data}"
ccecho -t bmagenta "[ Script $resolved moved to bin: ${bin_folder}${removed_data} ]"
else
ccecho -t byellow "Removal of $resolved aborted."
fi
else
ccecho -t bred "[ Error: Script '$target' not found! ]"
fi
done
refresh-brc
}
# Check for updates on Gitea
check_updates() {
echo "============================================="
ccecho -t bblue -s bold "[ Checking updates on Gitea... ]"
echo " Repository: $GITEA_REPO_URL"
echo "============================================="
local local_ver="unknown"
if [ -f "$version_file" ]; then
local_ver=$(cat "$version_file" | tr -d '[:space:]')
fi
local remote_commit=""
local commit_msg=""
local commit_author=""
local commit_date=""
# Attempt API check using curl and jq
if command -v curl >/dev/null 2>&1; then
local api_res
api_res=$(curl -s -m 5 "${GITEA_API_URL}/branches/master" 2>/dev/null || true)
if [ -n "$api_res" ] && command -v jq >/dev/null 2>&1; then
remote_commit=$(echo "$api_res" | jq -r '.commit.id // empty' 2>/dev/null || true)
commit_msg=$(echo "$api_res" | jq -r '.commit.message // empty' 2>/dev/null || true)
commit_author=$(echo "$api_res" | jq -r '.commit.author.name // empty' 2>/dev/null || true)
commit_date=$(echo "$api_res" | jq -r '.commit.timestamp // empty' 2>/dev/null || true)
fi
fi
# Fallback to git ls-remote if API is unavailable
if [ -z "$remote_commit" ] && command -v git >/dev/null 2>&1; then
remote_commit=$(git ls-remote "${GITEA_REPO_URL}.git" HEAD 2>/dev/null | awk '{print $1}' || true)
fi
if [ -z "$remote_commit" ]; then
ccecho -t bred "[ WARNING: Unable to connect to Gitea or fetch remote version. Check internet connection. ]"
return 1
fi
local short_local="${local_ver:0:8}"
local short_remote="${remote_commit:0:8}"
echo " Local Version: $short_local"
echo " Remote Version: $short_remote"
echo "---------------------------------------------"
if [ "$local_ver" == "$remote_commit" ]; then
ccecho -t bgreen -s bold "✔ Modular Bashrc Manager is up to date!"
rm -f "$update_cache" 2>/dev/null || true
else
ccecho -t byellow -s bold "★ Update Available!"
if [ -n "$commit_author" ]; then
echo " Author: $commit_author"
echo " Date: $commit_date"
echo " Message: $commit_msg"
fi
echo "---------------------------------------------"
ccecho -t bgreen "Run 'brc-script --upgrade' to install the latest version."
echo "1" > "$update_cache"
fi
return 0
}
# Perform upgrade from Gitea
upgrade_system() {
echo "============================================="
ccecho -t bblue -s bold "[ Upgrading Modular Bashrc Manager... ]"
echo " Repository: $GITEA_REPO_URL"
echo "============================================="
read -rp "Are you sure you want to upgrade scripts from Gitea? (y/N): " confirm_up
if [[ "$confirm_up" != "y" && "$confirm_up" != "Y" ]]; then
echo "Upgrade aborted."
return 0
fi
if ! command -v curl >/dev/null 2>&1; then
ccecho -t bred "[ Error: curl is required to download updates! ]"
return 1
fi
local tmp_dir
tmp_dir=$(mktemp -d 2>/dev/null || mktemp -d -t 'brc_upgrade')
echo " -> Downloading latest core files..."
# Core scripts to upgrade in scripts-needed
local core_files=("brc-script.sh" "ccecho.sh")
for f in "${core_files[@]}"; do
curl -s -f -m 10 "${GITEA_RAW_URL}/installer/scripts-needed/${f}" -o "${tmp_dir}/${f}" || true
if [ -s "${tmp_dir}/${f}" ]; then
cp "${tmp_dir}/${f}" "${needed_scripts}${f}"
chmod 750 "${needed_scripts}${f}"
echo " [OK] Updated needed script: ${f}"
else
ccecho -t byellow " [WARN] Could not update ${f}"
fi
done
# Default available scripts to update (excluding 00_default.sh so user config is never overwritten!)
local default_available=("01_git-cli-highlitgh.sh" "02_git-cli-highlitgh-root.sh" "03_bashboard.sh" "04_aliases.sh")
echo " -> Updating standard available scripts..."
for f in "${default_available[@]}"; do
curl -s -f -m 10 "${GITEA_RAW_URL}/installer/${f}" -o "${tmp_dir}/${f}" || true
if [ -s "${tmp_dir}/${f}" ]; then
cp "${tmp_dir}/${f}" "${available_scripts}${f}"
chmod 644 "${available_scripts}${f}"
echo " [OK] Updated available script: ${f}"
fi
done
# Fetch and record latest commit hash
local new_commit=""
if command -v jq >/dev/null 2>&1; then
local api_res
api_res=$(curl -s -m 5 "${GITEA_API_URL}/branches/master" 2>/dev/null || true)
new_commit=$(echo "$api_res" | jq -r '.commit.id // empty' 2>/dev/null || true)
fi
if [ -z "$new_commit" ] && command -v git >/dev/null 2>&1; then
new_commit=$(git ls-remote "${GITEA_REPO_URL}.git" HEAD 2>/dev/null | awk '{print $1}' || true)
fi
if [ -n "$new_commit" ]; then
echo "$new_commit" > "$version_file"
else
date +%s > "$version_file"
fi
rm -rf "$tmp_dir" "$update_cache" 2>/dev/null || true
echo "---------------------------------------------"
ccecho -t bgreen -s bold "[ Upgrade completed successfully! ]"
echo "---------------------------------------------"
refresh-brc
}
# Passive check notification
passive_check_notice() {
if [ -f "$update_cache" ]; then
ccecho -t byellow "★ [Notice] An update is available on Gitea! Run 'brc-script --upgrade'"
echo ""
fi
return 0
}
#################
### EXECUTION ###
#################
# Main Script #
brc-script() {
local cmd=""
if [ $# -gt 0 ]; then
cmd="$1"
shift
fi
case "$cmd" in
### PREVIEW SCRIPT (WITH LINE NUMBERS) ###
-p|--preview|preview)
previewscript "$@"
;;
### VIEW / CAT SCRIPT (PLAIN CODE) ###
-v|--cat|--view|--show|cat|show|view)
catscript "$@"
;;
### ENABLE SCRIPTS ###
-e|--enable|enable)
enablescript "$@"
;;
### ENABLE ALL SCRIPTS ###
-ea|--enable-all|enable-all)
enableallscript
;;
### DISABLE SCRIPT ###
-d|--disable|disable)
disablescript "$@"
;;
### DISABLE ALL SCRIPTS ###
-da|--disable-all|disable-all)
disableallscript
;;
### SCRIPTS LIST ###
-l|--list|list)
passive_check_notice
echo "------------------------------------"
echo " Scripts List "
echo "------------------------------------"
listitem
echo "------------------------------------"
echo " '-' (blue) = Active / Enabled "
echo "------------------------------------"
;;
### MODIFY SCRIPTS ###
-m|--modify|modify)
managescript_modify "$1"
;;
### CREATE NEW SCRIPT ###
-c|--create|create)
createscript
;;
### REMOVE SCRIPT ###
-r|--remove|remove)
removescript "$@"
;;
### CHECK UPDATES ###
-u|--update|update)
check_updates
;;
### UPGRADE SCRIPTS ###
--upgrade|upgrade)
upgrade_system
;;
### COMMAND LIST / HELP ###
*)
passive_check_notice
echo "--------------------------------------------------------"
echo " List of brc-script commands "
echo "--------------------------------------------------------"
echo " -l, --list | List all scripts "
echo " -p, --preview <id|name ...> | Preview (with numbers) "
echo " -v, --cat <id|name ...> | Cat / view (plain code) "
echo " -e, --enable <id|name ...> | Enable script(s) "
echo " -d, --disable <id|name ...> | Disable script(s) "
echo " -ea, --enable-all | Enable all scripts "
echo " -da, --disable-all | Disable all scripts "
echo " -c, --create | Create new script "
echo " -m, --modify <id|name> | Edit / rename script "
echo " -r, --remove <id|name ...> | Remove script(s) to bin "
echo " -u, --update | Check updates on Gitea "
echo " --upgrade | Upgrade scripts & core "
echo "--------------------------------------------------------"
echo " Example: brc-script -d 1 5 12 03_bashboard "
echo " Example: brc-script -e 2 4 01_git-cli-highlitgh "
echo " Example: brc-script -p 03_bashboard "
echo " Example: brc-script -v 03_bashboard "
echo "--------------------------------------------------------"
;;
esac
}