pythonify man script

This commit is contained in:
Didier Slof 2022-12-09 11:01:36 +01:00
parent ddb7a69f7e
commit 56d1705abd
Signed by: didier
GPG key ID: 01E71F18AA4398E5
4 changed files with 129 additions and 219 deletions

2
.gitignore vendored Normal file → Executable file
View file

@ -1,3 +1,5 @@
*.tar
*.tar.gz
.idea
.vscode
__pycharm__

219
man
View file

@ -1,220 +1,3 @@
#!/bin/sh
PROJECT_NAME=${PROJECT_NAME:-neo}
LIST=docker-compose.*.yml
SAVEFILE=$HOME/.local/faulty/$PROJECT_NAME.save
PROFILES=""
alias dc="docker-compose -p $PROJECT_NAME"
# alias dc="echo docker-compose -p $PROJECT_NAME"
alias _p="printf \"%s\""
default() {
fopts=""
for f in $LIST; do
fopts="$fopts -f $f"
done
profopts=""
for p in $PROFILES; do
profopts="$profopts --profile $p"
done
dc $fopts $profopts $*
}
safe_env_load() {
# $1 = file
# $2 = var
# get env var from regex instead of inclusion
[ ! -f $1 ] && fatal "file doesn't exist"
[ ! -r $1 ] && fatal "file not readable"
res=$(grep -E "^$2=" $1 | sed -E "s/^$2=\"(.*)\"/\1/")
[ -z "$res" ] && fatal "var not found"
_p $res
}
write_savefile() {
[ -d $(dirname $1) ] || mkdir -p $(dirname $1})
echo -n "LIST=\"" > $1
for li in $LIST; do
echo -n " $li" >> $1
done
echo "\"" >> $1
echo -n "PROFILES=\"" >> $1
for p in $PROFILES; do
echo -n " $p" >> $1
done
echo "\"" >> $1
}
load_savefile() {
[ "$1" == "/dev/null" ] && return
[ ! -f $1 ] && return
LIST=$(safe_env_load $1 LIST)
PROFILES=$(save_env_load $1 PROFILES)
}
fatal() {
echo "FATAL: $@"
exit 1
}
includechain=0
handleFallthrough() {
cmd=${1:-}; shift
case $cmd in
delete-project-files|dpf)
[ -n "$1" ] || fatal "no directory specified"
[ -d /srv/$1 ] || fatal "directory doesn't exist"
ls /srv/$1
printf "Are you sure? (y/n) [n]: "
read answer
[ "$answer" = "y" ] && sudo rm -rf /srv/$1 || fatal "cancelled"
;;
-p) # add profile
PROFILES="$PROFILES $1"; shift
handleFallthrough $@
;;
-i) #include
if [ $includechain -eq 0 ]; then
LIST="docker-compose.$1.yml"
includechain=1
else
LIST="$LIST docker-compose.$1.yml"
fi
shift
handleFallthrough $@
;;
-x) #exclude
LIST=$(echo $LIST | sed "s/docker-compose.$1.yml/ /")
shift
handleFallthrough $@
;;
make:*)
WHAT=`echo $cmd | cut -c6-`
case $WHAT in
dc|docker-compose)
[ -n "$1" ] || fatal "no name specified"
FILE="docker-compose.$1.yml"
[ -f $FILE ] && fatal "file exists"
echo -e "version: '2.2'\n" > $FILE
echo -e "services: \n" >> $FILE
;;
backup)
[ -n "$1" ] || fatal "no name specified"
FILE="$1.tar.gz"
[ -f $FILE ] && fatal "file exists"
tar cvf $FILE /srv .
;;
*) fatal "not supported" ;;
esac
;;
setup:*|s:*)
WHAT=`echo $cmd | cut -c8-`
case $WHAT in
ports) sudo ./utils/setup-ports.sh up ./utils/rulelist.rules ;;
def) sudo ./utils/setup.sh ;;
all|a)
sudo ./utils/setup.sh
sudo ./utils/setup-ports.sh up ./utils/rulelist.rules
;;
*) fatal "not supported" ;;
esac
;;
--save) # save behaviour
handleFallthrough $@
write_savefile $SAVEFILE
;;
# preference
logs) default logs --tail=20 -f $@ ;;
up) default up -d $@ ;;
upr) default up -d --remove-orphans $@ ;;
--help|-h)
__() {
colsep="$1"
cmd="$2"
desc="$3"
aliases="$4"
printf "%s %-20s %s %-64s %s %-40s %s \n" "$colsep" "$cmd" "$colsep" "$desc" "$colsep" "$aliases" "$colsep"
}
_hr() {
repchar() {
printf "%$1s" | tr " " "$2"
}
__ "*" ${1:-$(repchar 20 -)} ${2:-$(repchar 64 -)} ${3:-$(repchar 40 -)}
}
_r() {
__ "|" "$1" "$2" "$3"
}
_hr
_r $0 Description Aliases
_hr
_hr "Flags" " " " "
_hr
_r "-x" "Excludes a docker-compose file from the list." " "
_r "-i" "Includes a docker-compose file from the list." " "
_hr
_hr "Commands" " " " "
_hr
_r "dpf" "Delete project files." "delete-project-files <name>"
_r "setup:ports" "Setup ports." "setup:ports"
_r "setup:def" "Setup default." "setup:def"
_r "setup:all" "Setup all." "setup:all"
_r "make:dc <name>" "Make docker-compose file." "make:docker-compose <name>"
_r "make:backup <name>" "Make backup file." "tar cvf <name>.tar.gz /srv"
_hr
_hr "Commands/aliases" "(shortcuts)" " "
_hr
_r "up" "Bring up services. (-d)" "$0 default up -d"
_r "upr" "Bring up services and remove orphans." "$0 default up -d --remove-orphans"
_r "logs" "View logs and follow with a tail of 20." "$0 default logs --tail=20 -f"
_hr
_r "default" "fallback to the main docker-compose command with fileopts." "docker-compose"
_hr
;;
debug)
load_savefile $SAVEFILE
_() {
eval "echo -n \"$1=\"; echo \$$1"
}
_ SAVEFILE
_ LIST
for i in $LIST; do
echo $i
done
return
;;
default) default $@ ;;
*|'') default $cmd $@ ;;
esac
}
main() {
case $1 in
--ignore-save)
SAVEFILE=/dev/null
shift 1
;;
--set-save)
SAVEFILE=$2
shift 2
main $@; exit 0
;;
--del-save)
rm $SAVEFILE
shift
;;
esac
load_savefile $SAVEFILE
handleFallthrough $@
}
main $@
python utils/manager/main.py $@

97
utils/manager/main.py Normal file
View file

@ -0,0 +1,97 @@
import glob
import os
import argparse
from savefile import SaveFile
# Spaghetti code to replace the shell script
PROJECT_NAME = os.environ.get("PROJECT_NAME", "neo")
files = glob.glob("docker-compose.*.yml")
def setup_handler(what: str):
types = {
"def": lambda: os.system("sh ./utils/setup.sh"),
"ports": lambda: os.system("sh ./utils/setup-ports.sh ./utils/rulelist.rules")
}.get(what, lambda: print("Invalid setup type"))
def dc(cmd: str):
fopts = ""
for f in files:
fopts += f"-f {f} "
# print(f"docker-compose {fopts}{cmd}")
os.system(f"docker-compose -p {PROJECT_NAME} {fopts} {cmd}")
def main():
global files
ap = argparse.ArgumentParser()
ap.add_argument("--savefile", help="The savefile to use",
default=os.path.expanduser("~/.local/faulty/neo.save"))
ap.add_argument("--del-savefile", help="Delete the savefile",
action="store_true")
ap.add_argument("--ignore-savefile", help="Ignore the savefile",
action="store_true")
# -x, --exclude: e.g. -x this -x that
ap.add_argument("-x", "--exclude", help="Exclude a file from the list",
action="append", default=[])
# -i, --include: e.g. -i this -i that
ap.add_argument("-i", "--include", help="Include a file from the list",
action="append", default=[])
ap.add_argument('--save', help="Save the list of files to the savefile", action="store_true")
ap.add_argument('action', help="The action to perform on the files",
nargs="?", default="up")
ap.add_argument('args', help="Extra arguments for the action",
nargs=argparse.REMAINDER)
args = ap.parse_args()
if args.del_savefile:
os.remove(args.savefile)
return
if not args.ignore_savefile:
savefile = SaveFile(args.savefile)
else:
savefile = SaveFile(os.path.expanduser("~/.local/faulty/neo.save"))
# load the savefile
if not args.ignore_savefile:
files = savefile.get("files", files)
if len(args.include) > 0:
files = []
for i in args.include:
files.append(f"docker-compose.{i}.yml")
if len(args.exclude) > 0:
for i in args.exclude:
files.remove(f"docker-compose.{i}.yml")
if args.save:
savefile["files"] = files
return
def handle_aliases(fnlist: dict, name: str):
return fnlist.get(name, lambda: print("does not exist"))
fnlist = {
"up": lambda: dc(f"up -d {' '.join(args.args)}"),
"upr": lambda: dc(f"up -d --build {' '.join(args.args)}"),
"logs": lambda: dc(f"logs --tail=20 -f {' '.join(args.args)}"),
"setup": lambda: setup_handler(args.args[0]),
"delete-project-files": lambda: os.system(f"sudo rm -rf /srv/{args.args[0]}"),
"dpf": lambda: handle_aliases(fnlist, "delete-project-files")()
}
fnlist.get(args.action, lambda: dc(f"{args.action} {' '.join(args.args)}"))()
if __name__ == "__main__":
main()

28
utils/manager/savefile.py Normal file
View file

@ -0,0 +1,28 @@
import json
import os
class SaveFile(dict):
def __init__(self, file: str) -> None:
super().__init__()
self.path: str = file
_dir = os.path.dirname(self.path)
if not os.path.exists(_dir):
os.makedirs(_dir)
if os.path.exists(self.path):
with open(self.path) as f:
self.update(json.loads(f.read()))
else:
self.save()
def save(self):
with open(self.path, 'a+') as f:
f.write(json.dumps(self, indent=1))
def __getitem__(self, key):
return super().__getitem__(key)
def __setitem__(self, key, value):
super().__setitem__(key, value)
self.save()