#!/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 | Preview (with numbers) " echo " -v, --cat | Cat / view (plain code) " echo " -e, --enable | Enable script(s) " echo " -d, --disable | 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 | Edit / rename script " echo " -r, --remove | 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 }