bes-ps1/dist/bes-ps1
2019-11-16 01:48:07 +01:00

692 lines
19 KiB
Bash
Executable File

#!/bin/bash
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BES_BOOT=
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function bes.exists () {
declare -f $1 > /dev/null
#~ [ x$(type -t $1) = xfunction ];
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function bes.boot ()
{
for fn in $BES_BOOT; do
if bes.exists $fn.boot; then
$fn.boot
fi
done
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function bes.reg ()
{
local sep=" "
if [ -z "$BES_BOOT" ]; then
sep=""
fi
BES_BOOT=$BES_BOOT$sep$1
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# @author a-Sansara - https://git.pluie.org/meta-tech/bes-color
# @app bes-color
# @license GNU GPL v3
# @date 2017-10-23 23:30:54 CET
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function bes.color.boot () {
BES_NOCOLOR=${BES_NOCOLOR:-0}
if [ "$BES_NOCOLOR" -eq 0 ]; then
color.load
if [ $? -eq 1 ]; then
# by convention all colors begins with 'C' uppercase
# followed by a name in lowercase
# but in this calls you dont need to prefix names
#
# background foreground
# R G B R G B
color.set "head" 53 114 160 195 223 255
color.set "headsep" 53 114 160 252 212 102
# background
# R G B
color.bg "done" 63 172 138
color.bg "fail" 172 63 85
# foreground
# R G B
color.fg "title" 133 92 181
color.fg "headline" 22 74 133
color.fg "sep" 80 80 80
color.fg "err" 194 48 64
color.fg "val" 255 175 95
color.fg "key" 40 168 134
color.fg "action" 106 183 241
color.fg "symbol" 255 175 95
color.fg "item" 92 147 181
color.fg "usa" 255 172 0
color.fg "spe" 255 214 166
color.fg "opt" 94 215 255
color.fg "com" 175 135 175
color.fg "text" 0 132 101
color.fg "meta" 39 100 170
echo -e "$Cerr warning ${Coff}cannot load colors config file"
fi
Coff="\\033[m"
fi
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function color.fg()
{
local s=${1}
if [ ${s:0:1} = "C" ]; then s=${s:1}; fi
s=${s,,}
local -n var=C$1
var="\033[1;38;2;$2;$3;$4m"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function color.bg()
{
local s=${1}
if [ ${s:0:1} = "C" ]; then s=${s:1}; fi
s=${s,,}
local -n var=C$1
var="\033[1;48;2;$2;$3;$4m"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function color.set()
{
local s=${1}
if [ ${s:0:1} = "C" ]; then s=${s:1}; fi
s=${s,,}
local -n var=C$1
var="\033[1;48;2;$2;$3;$4;1;38;2;$5;$6;$7m"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function color.rgb ()
{
local c=${3:-0}
local v=$1
local -n r=${2}_r
local -n g=${2}_g
local -n b=${2}_b
if [ -z "$v" ]; then
r=$c
g=$c
b=$c
return
fi
r=${v%%;*}
[ "$v" = "$r" ] && v='' || v="${v#*;}"
if [ -z "$r" ]; then r=$c; fi
g=${v%%;*}
[ "$v" = "$g" ] && v='' || v="${v#*;}"
if [ -z "$g" ]; then g=$c; fi
b=${v%%;*}
if [ -z "$b" ]; then b=$c; fi
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function color.env () {
local -n var=${2:-shenv}
local v=ctx$1
local ctxPROD="174 8 49"
local ctxINT="218 84 0"
local ctxDEV="218 159 0"
local ctxLOCAL="122 122 122"
if [ -z "${!v}" ]; then
v=ctxLOCAL
SHENV_CTX=LOCAL
fi
var=${!v}
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function color.load () {
local file=${1:-/usr/share/bes/colors.ini}
if [ -f "$file" ]; then
local prefix="bes_colors"
bes.ini "$file" -p "$prefix" -b 1
for name in ${bes_colors_ALL_VARS}; do
key="${name:${#prefix}+1}"
if [ "${key:0:2}" = "fg" ]; then
color.fg "${key:3}" ${!name}
elif [ "${key:0:2}" == "bg" ]; then
color.bg "${key:3}" ${!name}
elif [ "${key:0:3}" == "set" ]; then
color.set "${key:4}" ${!name}
fi
done
else
return 1
fi
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
declare -f bes.reg > /dev/null
if [ $? -eq 0 ]; then
bes.reg bes.color
fi
#
# @author a-Sansara - https://git.pluie.org/meta-tech/bes-echo
# @app bes-echo
# @license GNU GPL v3
# @date 2017-05-13 23:50:54 CET
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function bes.echo.boot ()
{
BES_TERM_WIDTH=${COLUMNS:-130}
BES_TERM_WIDTH=$(($BES_TERM_WIDTH - 20))
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function echo.msg ()
{
local c=${2:-}
local m=${1:-}
echo -e " $c$m$Coff"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function echo.state ()
{
local len=14
echo -en " $Csep"
printf "%0.s-" $(seq 1 $(($BES_TERM_WIDTH-${len})))
if [ "$1" = 0 ]; then
echo -e "$Coff $Cdone OK $Coff\n"
else
echo -e "$Coff $Cfail KO $Coff\n"
fi
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function echo.action ()
{
local symbol=${3:-*}
local color=${4:-Citem}
echo -e " $Csymbol$symbol ${Caction}$1 ${!color}$2$Coff"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function echo.title ()
{
echo -e "\n $Csymbol$Ctitle$1 $Coff$Cspe$2$Coff\n"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function echo.keyval ()
{
local len=${3:-20}
local c="$Ckey: ${Cval}"
echo -e " $Ckey $(printf "%-${len}s " "$1") ${c}${2} $Coff"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function echo.rs ()
{
local rs=${1:-0}
if [ "$rs" -eq 0 ]; then
echo -e " ${Cdone} done ${Coff}"
else
echo -e " ${Cfail} failed ${Coff}"
fi
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function echo.error ()
{
local leave=${2:-0}
echo -e "\n${Cerr} error : ${Coff}\n\t$1 ${Coff}\n"
if [ "$leave" = "1" ]; then
exit 1;
fi
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function echo.sepline ()
{
local char=${1:-'_'}
local width=${2:-$BES_TERM_WIDTH}
echo -ne "${Cheadline} "
printf "%0.s$char" $(seq 1 $width)
echo -e "${Coff}"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function echo.app ()
{
local msg=${1:-''}
local version=${2:-''}
local author=${3:-'a-Sansara'}
local license=${4:-'GNU GPL v3'}
if [ ! -z "$2" ]; then
msg="$msg ${Cval}v$version"
fi
local len="$1${version}license : $license author:$author"
echo.sepline
echo -ne "\n $Chead $msg $Coff"
printf "%0.s " $(seq 1 $(($BES_TERM_WIDTH-${#len}-15)))
echo -e " ${Cmeta}license : ${Coff}$license ${Cmeta}author : ${Cval}$author"
echo.sepline
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
declare -f bes.reg > /dev/null
if [ $? -eq 0 ]; then
bes.reg bes.echo
fi
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# @author a-Sansara - https://git.pluie.org/meta-tech/bes-echo
# @app bes-ini
# @license GNU GPL v3
# @date 2017-05-19 22:52:59 CET
#
# bes alter '__' to '_' , rename read_ini to bes.ini
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# > https://github.com/rudimeier/bash_ini_parser
#
# Copyright (c) 2009 Kevin Porter / Advanced Web Construction Ltd
# (http://coding.tinternet.info, http://webutils.co.uk)
# Copyright (c) 2010-2014 Ruediger Meier <sweet_f_a@gmx.de>
# (https://github.com/rudimeier/)
#
# License: BSD-3-Clause, see LICENSE file
#
# Simple INI file parser.
#
# See README for usage.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function bes.ini ()
{
# Be strict with the prefix, since it's going to be run through eval
function check_prefix()
{
if ! [[ "${VARNAME_PREFIX}" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]] ;then
echo "read_ini: invalid prefix '${VARNAME_PREFIX}'" >&2
return 1
fi
}
function check_ini_file()
{
if [ ! -r "$INI_FILE" ] ;then
echo "read_ini: '${INI_FILE}' doesn't exist or not" \
"readable" >&2
return 1
fi
}
# enable some optional shell behavior (shopt)
function pollute_bash()
{
if ! shopt -q extglob ;then
SWITCH_SHOPT="${SWITCH_SHOPT} extglob"
fi
if ! shopt -q nocasematch ;then
SWITCH_SHOPT="${SWITCH_SHOPT} nocasematch"
fi
shopt -q -s ${SWITCH_SHOPT}
}
# unset all local functions and restore shopt settings before returning
# from read_ini()
function cleanup_bash()
{
shopt -q -u ${SWITCH_SHOPT}
unset -f check_prefix check_ini_file pollute_bash cleanup_bash
}
local INI_FILE=""
local INI_SECTION=""
# {{{ START Deal with command line args
# Set defaults
local BOOLEANS=1
local VARNAME_PREFIX=INI
local CLEAN_ENV=0
# {{{ START Options
# Available options:
# --boolean Whether to recognise special boolean values: ie for 'yes', 'true'
# and 'on' return 1; for 'no', 'false' and 'off' return 0. Quoted
# values will be left as strings
# Default: on
#
# --prefix=STRING String to begin all returned variables with (followed by '_').
# Default: INI
#
# First non-option arg is filename, second is section name
while [ $# -gt 0 ]
do
case $1 in
--clean | -c )
CLEAN_ENV=1
;;
--booleans | -b )
shift
BOOLEANS=$1
;;
--prefix | -p )
shift
VARNAME_PREFIX=$1
;;
* )
if [ -z "$INI_FILE" ]
then
INI_FILE=$1
else
if [ -z "$INI_SECTION" ]
then
INI_SECTION=$1
fi
fi
;;
esac
shift
done
if [ -z "$INI_FILE" ] && [ "${CLEAN_ENV}" = 0 ] ;then
echo -e "Usage: read_ini [-c] [-b 0| -b 1]] [-p PREFIX] FILE"\
"[SECTION]\n or read_ini -c [-p PREFIX]" >&2
cleanup_bash
return 1
fi
if ! check_prefix ;then
cleanup_bash
return 1
fi
local INI_ALL_VARNAME="${VARNAME_PREFIX}_ALL_VARS"
local INI_ALL_SECTION="${VARNAME_PREFIX}_ALL_SECTIONS"
local INI_NUMSECTIONS_VARNAME="${VARNAME_PREFIX}_NUMSECTIONS"
if [ "${CLEAN_ENV}" = 1 ] ;then
eval unset "\$${INI_ALL_VARNAME}"
fi
unset ${INI_ALL_VARNAME}
unset ${INI_ALL_SECTION}
unset ${INI_NUMSECTIONS_VARNAME}
if [ -z "$INI_FILE" ] ;then
cleanup_bash
return 0
fi
if ! check_ini_file ;then
cleanup_bash
return 1
fi
# Sanitise BOOLEANS - interpret "0" as 0, anything else as 1
if [ "$BOOLEANS" != "0" ]
then
BOOLEANS=1
fi
# }}} END Options
# }}} END Deal with command line args
local LINE_NUM=0
local SECTIONS_NUM=0
local SECTION=""
# IFS is used in "read" and we want to switch it within the loop
local IFS=$' \t\n'
local IFS_OLD="${IFS}"
# we need some optional shell behavior (shopt) but want to restore
# current settings before returning
local SWITCH_SHOPT=""
pollute_bash
while read -r line || [ -n "$line" ]
do
#echo line = "$line"
((LINE_NUM++))
# Skip blank lines and comments
if [ -z "$line" -o "${line:0:1}" = ";" -o "${line:0:1}" = "#" ]
then
continue
fi
# Section marker?
if [[ "${line}" =~ ^\[[a-zA-Z0-9_]{1,}\]$ ]]
then
# Set SECTION var to name of section (strip [ and ] from section marker)
SECTION="${line#[}"
SECTION="${SECTION%]}"
eval "${INI_ALL_SECTION}=\"\${${INI_ALL_SECTION}# } $SECTION\""
((SECTIONS_NUM++))
continue
fi
# Are we getting only a specific section? And are we currently in it?
if [ ! -z "$INI_SECTION" ]
then
if [ "$SECTION" != "$INI_SECTION" ]
then
continue
fi
fi
# Valid var/value line? (check for variable name and then '=')
if ! [[ "${line}" =~ ^[a-zA-Z0-9._]{1,}[[:space:]]*= ]]
then
echo "Error: Invalid line:" >&2
echo " ${LINE_NUM}: $line" >&2
cleanup_bash
return 1
fi
# split line at "=" sign
IFS="="
read -r VAR VAL <<< "${line}"
IFS="${IFS_OLD}"
# delete spaces around the equal sign (using extglob)
VAR="${VAR%%+([[:space:]])}"
VAL="${VAL##+([[:space:]])}"
VAR=$(echo $VAR)
# Construct variable name:
# ${VARNAME_PREFIX}_$SECTION_$VAR
# Or if not in a section:
# ${VARNAME_PREFIX}_$VAR
# In both cases, full stops ('.') are replaced with underscores ('_')
if [ -z "$SECTION" ]
then
VARNAME=${VARNAME_PREFIX}_${VAR//./_}
else
VARNAME=${VARNAME_PREFIX}_${SECTION}_${VAR//./_}
fi
eval "${INI_ALL_VARNAME}=\"\${${INI_ALL_VARNAME}# } ${VARNAME}\""
if [[ "${VAL}" =~ ^\".*\"$ ]]
then
# remove existing double quotes
VAL="${VAL##\"}"
VAL="${VAL%%\"}"
elif [[ "${VAL}" =~ ^\'.*\'$ ]]
then
# remove existing single quotes
VAL="${VAL##\'}"
VAL="${VAL%%\'}"
elif [ "$BOOLEANS" = 1 ]
then
# Value is not enclosed in quotes
# Booleans processing is switched on, check for special boolean
# values and convert
# here we compare case insensitive because
# "shopt nocasematch"
case "$VAL" in
yes | true | on )
VAL=1
;;
no | false | off )
VAL=0
;;
esac
fi
# enclose the value in single quotes and escape any
# single quotes and backslashes that may be in the value
VAL="${VAL//\\/\\\\}"
VAL="\$'${VAL//\'/\'}'"
eval "$VARNAME=$VAL"
done <"${INI_FILE}"
# return also the number of parsed sections
eval "$INI_NUMSECTIONS_VARNAME=$SECTIONS_NUM"
cleanup_bash
}
# < https://github.com/rudimeier/bash_ini_parser
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# @author a-Sansara - https://git.pluie.org/meta-tech/bes-install
# @app bes-install
# @license GNU GPL v3
# @date 2017-07-07 02:21:51 CET
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function bes.install ()
{
local app=${1}
local url=${2}
local path=${3:-/usr/local/bin}
local inst=${4:-}
local done=1
echo.title "Installing $app ${Coff}in" "$path"
if [ -z "$app" ] || [ -s "$url" ]; then
echo.error "in bes.install : \$app '$app' & \$url '$url' are required" 1
fi
if [ -f "./$app" ]; then
rm ./$app
fi
wget -q $url
if [ $? -eq 0 ]; then
chmod +x ./$app
if [ -d $path ]; then
sudo mv ./$app $path/$app
local done=$?
echo.state $done
else
echo.error "install directory do not exists : ${Cspe}$path"
fi
if [ ! -z "$inst" ]; then
if bes.exists "$inst"; then
$inst
fi
fi
else
echo.error "can not download latest version of app $app. please check url : $url"
fi
echo.rs $done
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function bes.usage ()
{
echo -e " ${Cusa}Usage :${Coff}\n
${Ccom}\tInstall or update $APP_NAME on specified BINDIR directory or in /etc/local/bin directory
${Cspe}\t$APP_NAME ${Copt}-i${Ctext}, ${Copt}install ${Copt}[ ${Ctext}BINDIR${Copt} ]
${Ccom}\tDisplay program version
${Cspe}\t$APP_NAME ${Copt}-v${Ctext}, ${Copt}version
${Ccom}\tDisplay this help
${Cspe}\t$APP_NAME ${Copt}-h${Ctext}, ${Copt}help"
echo -e "${Coff}"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bes.boot
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# @author a-Sansara - https://git.pluie.org/meta-tech/bes-build
# @app bes-build
# @license GNU GPL v3
# @date 2017-06-16 04:38:52 CET
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BES_VERSION=2.1
BES_NAME="bes-ps1"
BES_URL="https://git.pluie.org/meta-tech/$BES_NAME/raw/latest/dist/$BES_NAME"
APP_DIR=$(pwd)
APP_NAME=$(basename $(pwd))
APP_BIN=$APP_DIR/dist/$APP_NAME
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function bes.main ()
{
if [ "$1" = "version" ] || [ "$1" = "-v" ]; then
echo $BES_VERSION
else
echo.app "$BES_NAME" "$BES_VERSION"
echo
if [ "$1" = "install" ] || [ "$1" = "-i" ]; then
bes.install "$BES_NAME" "$BES_URL" "$2" "bes.ps1.install"
elif [ "$1" = "help" ] || [ "$1" = "-h" ]; then
bes.usage
fi
echo
fi
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function bes.ps1.install ()
{
local path="/usr/share/bes/ps1"
local dir=$(dirname "$path")
if [ ! -d "$dir" ]; then
echo.action "Creating default bes share dir" "$Cspe$dir$Coff"
sudo mkdir -p "$dir"
echo.state $?
fi
echo.action "Downloading ps1 file"
wget -q https://raw.githubusercontent.com/meta-tech/bes-ps1/latest/src/ps1
echo.state $?
echo.action "Moving ps1 file to" "$Cspe$path$Coff"
sudo mv ps1 "$path"
echo.state $?
if [ ! -f "/home/$USER/.bash_ps1" ]; then
echo.action "Downloading .user_ps1 file"
wget -q https://raw.githubusercontent.com/meta-tech/bes-ps1/latest/src/.user_ps1
echo.action "Moving .user_ps1 file to" "${Cspe}~/.bash_ps1${Coff}"
mv .user_ps1 ~/.bash_ps1
echo.state $?
fi
echo.action "Updating $USER .bashrc file"
if [ ! -f "~/.bashrc" ]; then
touch ~/.bashrc
fi
local line=$(cat ~/.bashrc | grep -n '# > BES_PS1' | cut -d':' -f1)
if [ -z "$line" ]; then
echo "
# > BES_PS1
if [ -f ~/.bash_ps1 ]; then
. ~/.bash_ps1
fi
# < BES_PS1
" >> ~/.bashrc
else
echo.msg "already updated"
fi
echo.state $?
echo.action "You can now edit ~/.bash_ps1 to customize ps1"
cat ~/.bash_ps1
echo.action "To view effects immediatly run :"
echo.msg "source ~/.bashrc"
source ~/.bash_ps1
}
bes.main $*