feat(legacy): helpers: update log, unefficient but works

This commit is contained in:
2025-11-16 15:50:54 +00:00
parent 33cdebb64a
commit bb99ef9a8a
6 changed files with 243 additions and 29 deletions

View File

@@ -1,7 +1,123 @@
#!/bin/dash
# Hectic shell logger
#
# Usage:
# # Including
# . <this file>
#
# # Required
# colors.sh
#
# # In your script (recommended: do NOT export HECTIC_NAMESPACE)
# HECTIC_NAMESPACE="my-script" # optional, defaults to basename "$0"
# # # Then use:
# log info 'starting up'
# log debug "value=${val}"
# log error "failed: ${WHITE}${reason}${NC} red text again"
#
# # Note:
# When you use NC to reset terminal colors inside log output,
# it resets back to the log levels color instead of the terminal default.
: "${HLOG_NAMESPACE:="$(basename "$0")"}"
: "${HLOG_LEVEL:=trace}" # e.g. "info;ns1=debug;ns2=trace"
validate_log_level_spec() {
spec=$HLOG_LEVEL
levels="trace debug info notice warn error"
ok_level() {
for l in $levels; do
[ "$l" = "$1" ] && return 0
done
return 1
}
oldIFS=$IFS
IFS=';'
# shellcheck disable=SC2086
set -- $spec
IFS=$oldIFS
for tok; do
case $tok in
*=*)
ns=${tok%%=*}
lvl=${tok#*=}
[ -n "$ns" ] || return 1
ok_level "$lvl" || return 1
;;
*)
ok_level "$tok" || return 1
;;
esac
done
return 0
}
validate_log_level_spec || { printf "%b%b\n" "${BBLACK}${HLOG_NAMESPACE}> " "${color}invalid HLOG_LEVEL syntax${NC}" "$@" >&2; exit 1; }
log_level_num() {
case $1 in
trace) printf %s 0 ;;
debug) printf %s 1 ;;
info) printf %s 2 ;;
notice) printf %s 3 ;;
warn) printf %s 4 ;;
error) printf %s 5 ;;
*) printf %s 2 ;; # default info
esac
}
log_effective_level() {
spec=$HLOG_LEVEL
ns=$HLOG_NAMESPACE
default_level=
ns_level=
oldIFS=$IFS
IFS=';'
# shellcheck disable=SC2086
set -- $spec
IFS=$oldIFS
for tok; do
case $tok in
*=*)
name=${tok%%=*}
lvl=${tok#*=}
[ "$name" = "$ns" ] && ns_level=$lvl
;;
*)
[ -z "$default_level" ] && default_level=$tok
;;
esac
done
printf '%s\n' "${ns_level:-${default_level:-info}}"
}
log_allowed() {
msg_level="${1:?}"
eff_level="$(log_effective_level)"
msg_n="$(log_level_num "$msg_level")"
eff_n="$(log_level_num "$eff_level")"
[ "$msg_n" -ge "$eff_n" ]
}
# log(level, text...)
log() {
delimetr=${DELIMETR:-' '};
level="${1:?}"; shift
log_allowed "$level" || return 0
case "$level" in
trace) color="$MAGENTA" ;;
debug) color="$BLUE" ;;
@@ -15,7 +131,7 @@ log() {
# shellcheck disable=SC1003
fmt="$(printf "%s" "${1:?}" | sed 's/\\033\[0m/''\'"$color"'/g')"
fmt="$(printf "%s$delimetr" "$@" | sed 's/\\033\[0m/''\'"$color"'/g')"
shift
printf "%b\n" "$color$fmt$NC" "$@" >&2
printf "%b%b\n" "${BBLACK}${HLOG_NAMESPACE}> " "$color$fmt$NC" >&2
}

View File

@@ -0,0 +1,18 @@
{ symlinkJoin, dash, hectic }: let
shell = "${dash}/bin/dash";
bashOptions = [
"errexit"
"nounset"
];
show-megumin = hectic.writeShellApplication {
inherit shell bashOptions;
name = "show-megumin";
runtimeInputs = [ ];
text = builtins.readFile ./show-megumin.sh;
};
in
symlinkJoin {
name = "sentinèlla";
paths = [ show-megumin ];
}

View File

View File

@@ -9,10 +9,18 @@ MIGRATION_DIR="${MIGRATION_DIR:-migration}"
quote() { printf "'%s'" "$(printf %s "$1" | sed "s/'/'\\\\''/g")"; }
REMAINING_ARS=
# cat filename | sha256sum()
# sha256sum(filename)
sha256sum() {
local file
file="${1:-'-'}"
cksum --algorithm=sha256 --untagged "$file" | awk '{printf $1}'
}
while [ $# -gt 0 ]; do
log debug "$1"
case $1 in
migrate|create|fetch|list)
migrate|create|fetch|list|init)
[ "${SUBCOMMAND+x}" ] && { printf 'ambiguous subcommand, decide %s or %s\n' "$SUBCOMMAND" "$1"; exit 1; }
SUBCOMMAND=$1
shift
@@ -25,10 +33,6 @@ while [ $# -gt 0 ]; do
INHERITS_LIST="${INHERITS_LIST:+$INHERITS_LIST\"}$2"
shift 2
;;
--init-dry-run)
INIT_DRY_RUN=1
shift
;;
--*|-*) REMAINING_ARS="$REMAINING_ARS $(quote "$1")"; shift ;; # unknown global -> pass through
*) REMAINING_ARS="$REMAINING_ARS $(quote "$1")"; shift ;;
esac
@@ -36,22 +40,79 @@ done
INHERITS_LIST="$(printf '%s' "$INHERITS_LIST" | sed -E 's/"/,/g; s/([^,]+)/"\1"/g')"
# shellcheck disable=SC2120
init() {
while [ $# -gt 0 ]; do
case $1 in
--dry-run)
INIT_DRY_RUN=1
shift
;;
--db-url|-u)
DB_URL="$2"
shift 2
;;
--*|-*)
printf 'init argument %s does not exists' "$1"
exit 1
;;
*)
printf 'init command %s does not exists' "$1"
exit 1
;;
esac
done
error_handler_no_db_url
[ "${INIT_DRY_RUN+x}" ] && { printf '%s\n' "$(init_sql)"; exit; }
psql_args="$(form_psql_args)"
# shellcheck disable=SC2086
if ! printf '%s' "$(init_sql)" | psql $psql_args; then
log error "Migration failed: ${WHITE}$fs_migration${NC}"
return 3
fi
}
# error_handler_no_db_url()
error_handler_no_db_url() {
[ "${DB_URL+x}" ] || { log error "no ${WHITE}DB_URL${NC} or ${WHITE}--db-url${NC} specified"; exit 1; }
}
init_sql() {
log debug "inherits: ${WHITE}${INHERITS_LIST}${NC}"
local create_table
create_table="$(printf '%s\n' \
"BEGIN;" \
"CREATE DOMAIN hectic.migration_name AS TEXT CHECK (VALUE ~ '^[0-9]{15}-.*$');" \
'' \
"CREATE DOMAIN hectic.sha256 AS CHAR(64) CHECK (VALUE ~ '^[0-9a-f]{64}$');" \
'' \
'CREATE FUNCTION hectic.sha256_lower() RETURNS trigger AS $$' \
'BEGIN' \
' NEW.hash = lower(NEW.hash);' \
' RETURN NEW;' \
'END;' \
'$$ LANGUAGE plpgsql;' \
'' \
'CREATE TRIGGER hectic.t_sha256_lower' \
'BEFORE INSERT OR UPDATE ON hectic.migration' \
'FOR EACH ROW EXECUTE FUNCTION sha256_lower();' \
'' \
'CREATE SCHEMA IF NOT EXISTS hectic;' \
'CREATE TABLE IF NOT EXISTS hectic.migration (' \
' id SERIAL PRIMARY KEY,' \
' name TEXT UNIQUE NOT NULL,'\
' name hectic.migration_name UNIQUE NOT NULL,'\
' hash hectic.sha256 UNIQUE NOT NULL,'\
' applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()' \
')')"
')' \
'COMMIT;')"
printf '%s INHERITS(%s)' "$create_table" "$INHERITS_LIST"
}
[ "${INIT_DRY_RUN+x}" ] && { printf '%s\n' "$(init)"; exit; }
[ "${SUBCOMMAND+x}" ] || { log error "no subcomand specified"; exit 1; }
help() {
@@ -142,21 +203,20 @@ migrate() {
;;
--*|-*) REMAINING_ARS="$REMAINING_ARS $(quote "$1")"; shift ;; # unknown global -> pass through
*) REMAINING_ARS="$REMAINING_ARS $(quote "$1")"; shift ;;
#--*|-*)
# printf 'migrate argument %s does not exists' "$1"
# exit 1
#;;
#*)
# printf 'migrate subcommand %s does not exists' "$1"
# exit 1
#;;
esac
done
error_handler_no_db_url
[ -n "$FORCE" ] && {
log error "migrate --force not implemented"
exit 1
}
init
fs_migrations=$(
find "$MIGRATION_DIR" -maxdepth 1 -type f -name '*.sql' \
find "$MIGRATION_DIR" -maxdepth 1 -type d -regex '^.*/[0-9]{15}-.*$' \
| sort \
| xargs -n1 basename
)
@@ -186,17 +246,25 @@ migrate() {
eval "set -- $REMAINING_ARS"
#target_migration="$("migrate_$MIGRATE_SUBCOMMAND" "$@")"
}
form_psql_args() {
psql_args="-d $DB_URL -v ON_ERROR_STOP=1"
for var in $VARIABLE_LIST; do
psql_args="$psql_args -v $var"
done
}
migrate_inner() {
printf '%s\n' "$fs_migrations" | while IFS= read -r fs_migration; do
# skip already applied migrations
printf '%s' "$db_migrations" | grep -qxF "$fs_migration" && continue
psql_args="-d $DB_URL"
for var in $VARIABLE_LIST; do
psql_args="$psql_args -v $var"
done
psql_args="$(form_psql_args)"
escaped_name=$(printf "%s" "$fs_migration" | sed "s/'/''/g")
escaped_path=$(printf "%s/%s" "$MIGRATION_DIR" "$fs_migration" | sed "s/'/''/g")
escaped_path=$(printf "%s/%s/up.sql" "$MIGRATION_DIR" "$fs_migration" | sed "s/'/''/g")
# shellcheck disable=SC2086
if ! psql $psql_args <<SQL
@@ -255,6 +323,8 @@ fetch() {
;;
esac
done
error_handler_no_db_url
}
list() {

View File

@@ -1,6 +1,16 @@
if ! migration_table_sql="$(migrator --inherits tablename --inherits 'table name' --init-dry-run)"; then
#!/bin/dash
log info "hectic.migration table inheritance"
if ! migration_table_sql="$(migrator --inherits tablename --inherits 'table name' init --dry-run)"; then
log error "test failed: error on migration table init dry run"
fi
printf '%s' "$migration_table_sql" | grep -Eq 'INHERITS[[:space:]]*\([[:space:]]*"tablename"[[:space:]]*,[[:space:]]*"table name"[[:space:]]*\)' ||
{ log error "not correct migration table inherits"; exit 1; }
log info "init"
if ! migrator --inherits tablename --inherits 'table name' init; then
log error "test failed: error on init sql"
fi
printf 'SELECT * FROM hectic.migration' | psql -v ON_ERROR_STOP=1 "$DATABASE_URL"

View File

@@ -1 +1 @@
migrator list
#migrator list