bes-config/dist/bes-config
2018-12-22 11:38:53 +01:00

612 lines
16 KiB
Bash
Executable File

#!/bin/bash
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# @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
# by convention all colors begins with 'C' uppercase
# followed by a name in lowercase
# background foreground
# R G B R G B
color.set "Chead" 53 114 160 195 223 255
color.set "Cheadsep" 53 114 160 252 212 102
# background
# R G B
color.bg "Cdone" 63 172 138
color.bg "Cfail" 172 63 85
# foreground
# R G B
color.fg "Ctitle" 133 92 181
color.fg "Cheadline" 22 74 133
color.fg "Csep" 80 80 80
color.fg "Cerr" 194 48 64
color.fg "Cval" 255 175 95
color.fg "Ckey" 40 168 134
color.fg "Caction" 106 183 241
color.fg "Csymbol" 255 175 95
color.fg "Citem" 92 147 181
color.fg "Cusa" 255 172 0
color.fg "Cspe" 255 214 166
color.fg "Copt" 94 215 255
color.fg "Ccom" 175 135 175
color.fg "Ctext" 0 132 101
color.fg "Cmeta" 39 100 170
Coff="\\033[m"
fi
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function color.fg()
{
local -n var=$1
var="\033[1;38;2;$2;$3;$4m"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function color.bg()
{
local -n var=$1
var="\033[1;48;2;$2;$3;$4m"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function color.set()
{
local -n var=$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}
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bes.color.boot
#
# @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=${3:-'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
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bes.echo.boot
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# @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 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
else
echo.error "can not download latest version of app $app. please check url : $url"
fi
echo.rs $done
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function bes.config ()
{
echo.title "Reading Configuration Project" $APP_NAME
if [ -f ./bes.ini ]; then
bes.ini ./bes.ini -p bes -b 1
local keys="vendor name version license author type homepage description keywords"
local value=""
local hasconf=0
for key in $keys; do
value="bes_project_$key"
if [ ! -z "${!value}" ]; then
hasconf=1
echo.keyval $key "${!value}"
fi
done
if [ "$hasconf" = "0" ]; then
echo.msg " -"
fi
echo.title "Dependencies"
bes.ini ./bes.ini require -p bes -b 1
local prefix="bes_require"
local key=""
for name in ${bes_ALL_VARS}; do
key=${name:${#prefix}+1}
local tmp=${key//_/.}
echo.keyval "$tmp" "${!name}"
done
else
echo " $project does not have bes.ini file"
fi
echo
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function bes.usage ()
{
echo -e " ${Cusa}Usage :${Coff}\n
${Ccom}\tRead current project bes.ini configuration file
${Cspe}\t$APP_NAME
${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}"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# @author a-Sansara - https://git.pluie.org/meta-tech/bes-config
# @app bes-config
# @license GNU GPL v3
# @date 2017-06-16 04:38:52 CET
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BES_VERSION=1.1
BES_NAME="bes-config"
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"
elif [ "$1" = "help" ] || [ "$1" = "-h" ]; then
bes.usage
else
bes.config
fi
echo
fi
}
bes.main $*