#!/usr/bin/env bash # This file is part of The RetroPie Project # # The RetroPie Project is the legal property of its developers, whose names are # too numerous to list here. Please refer to the COPYRIGHT.md file distributed with this source. # # See the LICENSE.md file at the top-level directory of this distribution and # at https://raw.githubusercontent.com/RetroPie/RetroPie-Setup/master/LICENSE.md # declare -A __mod_id_to_idx __mod_idx=() __mod_id=() __mod_type=() __mod_desc=() __mod_help=() __mod_section=() __mod_flags=() declare -A __sections __sections[core]="core" __sections[main]="main" __sections[opt]="optional" __sections[exp]="experimental" __sections[driver]="driver" __sections[config]="configuration" function rp_listFunctions() { local idx local mod_id local desc local mode local func echo -e "Index/ID: Description: List of available actions" echo "-----------------------------------------------------------------------------------------------------------------------------------" for idx in ${__mod_idx[@]}; do mod_id=${__mod_id[$idx]}; printf "%d/%-20s: %-42s :" "$idx" "$mod_id" "${__mod_desc[$idx]}" while read mode; do # skip private module functions (start with an underscore) [[ "$mode" = _* ]] && continue mode=${mode//_$mod_id/} echo -n " $mode" done < <(compgen -A function -X \!*_$mod_id) fnExists "install_${mod_id}" || fnExists "install_bin_${mod_id}" && ! fnExists "remove_${mod_id}" && echo -n " remove" echo -n " help" echo "" done echo "===================================================================================================================================" } function rp_printUsageinfo() { echo -e "Usage:\n$0 \nThis will run the actions depends, sources, build, install, configure and clean automatically.\n" echo -e "Alternatively, $0 can be called as\n$0 /dev/null pushed=$? ;; install) action="Installing" mkdir -p "$md_inst" pushd "$md_build" 2>/dev/null pushed=$? ;; install_bin) action="Installing" mkdir -p "$md_inst" ;; configure) action="Configuring" pushd "$md_inst" 2>/dev/null pushed=$? ;; remove) action="Removing" ;; *) action="Running action '$mode' for" ;; esac # print an action and a description printHeading "$action '$md_id' : $md_desc" case "$mode" in remove) fnExists "$function" && "$function" "$@" md_mode="remove" if fnExists "configure_${md_id}"; then pushd "$md_inst" 2>/dev/null pushed=$? "configure_${md_id}" remove fi rm -rvf "$md_inst" ;; install) if fnExists "$function"; then "$function" "$@" elif fnExists "install_bin_${md_id}"; then "install_bin_${md_id}" "$@" fi ;; install_bin) if fnExists "install_bin_${md_id}"; then if ! "$function" "$@"; then # if it failed to install remove the install folder if it exists rm -rf "$md_inst" fi else if rp_hasBinary "$md_idx"; then rp_installBin else md_ret_errors+=("Could not find a binary for $md_id") fi fi ;; *) # call the function with parameters fnExists "$function" && "$function" "$@" ;; esac local file # some errors were returned. append to global errors and return if [[ "${#md_ret_errors}" -eq 0 ]]; then # check if any required files are found if [[ -n "$md_ret_require" ]]; then for file in "${md_ret_require[@]}"; do if [[ ! -e "$file" ]]; then md_ret_errors+=("Could not successfully $mode $md_desc ($file not found).") break fi done else # check for existance and copy any files/directories returned if [[ -n "$md_ret_files" ]]; then for file in "${md_ret_files[@]}"; do if [[ ! -e "$md_build/$file" ]]; then md_ret_errors+=("Could not successfully install $md_desc ($md_build/$file not found).") break fi cp -Rvf "$md_build/$file" "$md_inst" done fi fi fi # remove build folder if empty [[ -d "$md_build" ]] && find "$md_build" -maxdepth 0 -empty -exec rmdir {} \; [[ "$pushed" -eq 0 ]] && popd if [[ "${#md_ret_errors[@]}" -gt 0 ]]; then # remove install folder if there is an error [[ -d "$md_inst" ]] && find "$md_inst" -maxdepth 0 -empty -exec rmdir {} \; printMsgs "console" "${md_ret_errors[@]}" >&2 __ERRMSGS+=("${md_ret_errors[@]}") return 1 fi return 0 } function rp_hasBinaries() { [[ "$__has_binaries" -eq 1 ]] && return 0 return 1 } function rp_hasBinary() { local idx="$1" fnExists "install_bin_${__mod_id[$idx]}" && return 0 if rp_hasBinaries; then wget --spider -q "$__binary_url/${__mod_type[$idx]}/${__mod_id[$idx]}.tar.gz" return $? fi return 1 } function rp_installBin() { rp_hasBinaries || fatalError "There are no binary archives for platform $__platform" local archive="$md_type/$md_id.tar.gz"; local dest="$rootdir/$md_type" mkdir -p "$dest" wget -O- -q "$__binary_url/$archive" | tar -xvz -C "$dest" } function rp_createBin() { printHeading "Creating binary archive for $md_desc" if [[ -d "$rootdir/$md_type/$md_id" ]]; then local archive="$md_id.tar.gz" local dest="$__tmpdir/archives/$__raspbian_name/$__platform/$md_type" rm -f "$dest/$archive" mkdir -p "$dest" tar cvzf "$dest/$archive" -C "$rootdir/$md_type" "$md_id" chown $user:$user "$dest/$archive" else printMsgs "console" "No install directory $rootdir/$md_type/$md_id - no archive created" fi } function rp_installModule() { local idx="$1" local mode if rp_hasBinary "$idx"; then for mode in depends install_bin configure; do rp_callModule "$idx" "$mode" || return 1 done else rp_callModule "$idx" || return 1 fi return 0 } function rp_registerModule() { local module_idx="$1" local module_path="$2" local module_type="$3" local rp_module_id="" local rp_module_desc="" local rp_module_help="" local rp_module_section="" local rp_module_flags="" local var local error=0 source "$module_path" for var in rp_module_id rp_module_desc; do if [[ -z "${!var}" ]]; then echo "Module $module_path is missing valid $var" error=1 fi done [[ $error -eq 1 ]] && exit 1 local flags=($rp_module_flags) local flag local valid=1 for flag in "${flags[@]}"; do if [[ "$flag" =~ ^\!(.+) ]] && isPlatform "${BASH_REMATCH[1]}"; then valid=0 break fi done if [[ "$valid" -eq 1 ]]; then __mod_idx+=("$module_idx") __mod_id["$module_idx"]="$rp_module_id" __mod_type["$module_idx"]="$module_type" __mod_desc["$module_idx"]="$rp_module_desc" __mod_help["$module_idx"]="$rp_module_help" __mod_section["$module_idx"]="$rp_module_section" __mod_flags["$module_idx"]="$rp_module_flags" # id to idx mapping via associative array __mod_id_to_idx["$rp_module_id"]="$module_idx" fi } function rp_registerModuleDir() { local module_idx="$1" local module_dir="$2" for module in $(find "$scriptdir/scriptmodules/$2" -maxdepth 1 -name "*.sh" | sort); do rp_registerModule $module_idx "$module" "$module_dir" ((module_idx++)) done } function rp_registerAllModules() { rp_registerModuleDir 100 "emulators" rp_registerModuleDir 200 "libretrocores" rp_registerModuleDir 300 "ports" rp_registerModuleDir 800 "supplementary" rp_registerModuleDir 900 "admin" } function rp_getIdxFromId() { echo "${__mod_id_to_idx[$1]}" } function rp_getSectionIds() { local section local id local ids=() for id in "${__mod_idx[@]}"; do for section in "$@"; do [[ "${__mod_section[$id]}" == "$section" ]] && ids+=("$id") done done echo "${ids[@]}" } function rp_isInstalled() { local md_idx="$1" local md_inst="$rootdir/${__mod_type[$md_idx]}/${__mod_id[$md_idx]}" [[ -d "$md_inst" ]] && return 0 return 1 } function rp_updateHooks() { local function local mod_idx for function in $(compgen -A function _update_hook_); do mod_idx="$(rp_getIdxFromId "${function/_update_hook_/}")" [[ -n "$mod_idx" ]] && rp_callModule "$mod_idx" _update_hook done }