From 373a3fe3f06b4e00ad739ed3877966c1f65aec9d Mon Sep 17 00:00:00 2001 From: yukkop Date: Sat, 6 Dec 2025 04:47:31 +0000 Subject: [PATCH] fix(package): `migrator`: index_of subshell issue --- package/migrator/migrator.sh | 120 ++++++++++-------- test/package/migrator/default.nix | 4 +- .../migrator/test/function-generate-word.sh | 17 +++ .../migrator/test/function-index-of.sh | 47 +++++++ .../up.sql} | 0 .../test/function-migration-list/run.sh | 17 +++ .../20251104192425-add-info-to-profile/up.sql | 1 + test/package/migrator/util.sh | 12 ++ 8 files changed, 166 insertions(+), 52 deletions(-) create mode 100644 test/package/migrator/test/function-generate-word.sh create mode 100644 test/package/migrator/test/function-index-of.sh rename test/package/migrator/test/{migrate-up/migration/20251104192425-add-info-to-profile.sql => function-migration-list/migration/20251104192425-add-info-to-profile/up.sql} (100%) create mode 100644 test/package/migrator/test/function-migration-list/run.sh create mode 100644 test/package/migrator/test/migrate-up/migration/20251104192425-add-info-to-profile/up.sql diff --git a/package/migrator/migrator.sh b/package/migrator/migrator.sh index da3507a..67e80f9 100644 --- a/package/migrator/migrator.sh +++ b/package/migrator/migrator.sh @@ -14,16 +14,12 @@ set -eu -if ! command -v psql >/dev/null; then - log error "Required tool (psql) are not installed." - exit 127 -fi - VERSION='0.0.1' MIGRATION_DIR="${MIGRATION_DIR:-migration}" -quote() { printf "'%s'" "$(printf %s "$1" | sed "s/'/'\\\\''/g")"; } REMAINING_ARS= +quote() { printf "'%s'" "$(printf %s "$1" | sed "s/'/'\\\\''/g")"; } + # cat filename | sha256sum() # sha256sum(filename) sha256sum() { @@ -32,32 +28,6 @@ sha256sum() { cksum --algorithm=sha256 --untagged "$file" | awk '{printf $1}' } -while [ $# -gt 0 ]; do - log debug "arg: $1" - case $1 in - migrate|create|fetch|list|init) - [ "${SUBCOMMAND+x}" ] && { - log error "ambiguous subcommand, decide ${WHITE}$SUBCOMMAND ${NC}or ${WHITE}$1"; - exit 2; - } - SUBCOMMAND=$1 - shift - ;; - --migration-dir|-d) - MIGRATION_DIR=$2 - shift 2 - ;; - --inherits) - INHERITS_LIST="${INHERITS_LIST+$INHERITS_LIST\"}$2" - shift 2 - ;; - --*|-*) REMAINING_ARS="$REMAINING_ARS $(quote "$1")"; shift ;; # unknown global -> pass through - *) REMAINING_ARS="$REMAINING_ARS $(quote "$1")"; shift ;; - esac -done - -[ ${INHERITS_LIST+x} ] && INHERITS_LIST="$(printf '%s' "$INHERITS_LIST" | sed -E 's/"/,/g; s/([^,]+)/"\1"/g')" - # shellcheck disable=SC2120 init() { while [ $# -gt 0 ]; do @@ -192,8 +162,6 @@ EOF printf '%s' "$sql" } -[ "${SUBCOMMAND+x}" ] || { log error "no subcomand specified"; exit 1; } - help() { # inherits: List one or more tables the migration table must inherit from echo help @@ -269,6 +237,24 @@ migration_list() { find "$MIGRATION_DIR" -maxdepth 1 -type d -regextype posix-extended -regex '^.*/[0-9]{14}-.*$' -printf '%f\n' | sort } +# index_of(array, name) +index_of() { + local list name m i=1 + list=$1 + name=$2 + [ -z "$name" ] && return 1 + + # no subshell, no pipeline + while IFS= read -r m; do + [ "$m" = "$name" ] && { printf '%s\n' "$i"; return 0; } + i=$((i+1)) + done </dev/null; then + log error "Required tool (psql) are not installed." + exit 127 +fi -eval "set -- $REMAINING_ARS" -"$SUBCOMMAND" "$@" +if ! [ "${AS_LIBRARY+x}" ]; then + while [ $# -gt 0 ]; do + log debug "arg: $1" + case $1 in + migrate|create|fetch|list|init) + [ "${SUBCOMMAND+x}" ] && { + log error "ambiguous subcommand, decide ${WHITE}$SUBCOMMAND ${NC}or ${WHITE}$1"; + exit 2; + } + SUBCOMMAND=$1 + shift + ;; + --migration-dir|-d) + MIGRATION_DIR=$2 + shift 2 + ;; + --inherits) + INHERITS_LIST="${INHERITS_LIST+$INHERITS_LIST\"}$2" + shift 2 + ;; + --*|-*) REMAINING_ARS="$REMAINING_ARS $(quote "$1")"; shift ;; # unknown global -> pass through + *) REMAINING_ARS="$REMAINING_ARS $(quote "$1")"; shift ;; + esac + done + + [ ${INHERITS_LIST+x} ] && INHERITS_LIST="$(printf '%s' "$INHERITS_LIST" | sed -E 's/"/,/g; s/([^,]+)/"\1"/g')" + [ "${SUBCOMMAND+x}" ] || { log error "no subcomand specified"; exit 1; } + + + log debug "subcommand: $WHITE$SUBCOMMAND" + log debug "subcommand args: $WHITE$REMAINING_ARS" + + eval "set -- $REMAINING_ARS" + "$SUBCOMMAND" "$@" +fi diff --git a/test/package/migrator/default.nix b/test/package/migrator/default.nix index d9c4f59..8f744b7 100644 --- a/test/package/migrator/default.nix +++ b/test/package/migrator/default.nix @@ -7,7 +7,7 @@ pkgs.runCommand "test-${name}" {} '' if ! [ -f ${./test + "/${name}" + /run.sh} ]; then echo no run.sh in test/${name} - exit 1 + exit 1 fi mkdir -p "$out" @@ -35,7 +35,7 @@ mkPgTest = testName: testDrv: pkgs.runCommand "migrator-test-${testName}" { nativeBuildInputs = [ pkgs.coreutils pkgs.gnugrep pkgs.gnused ]; - buildInputs = [ migrator pkgs.postgresql ]; + buildInputs = [ pkgs.which migrator pkgs.postgresql ]; } '' ${builtins.readFile self.legacyPackages.${system}.helpers.posix-shell.log} test=${testDrv} diff --git a/test/package/migrator/test/function-generate-word.sh b/test/package/migrator/test/function-generate-word.sh new file mode 100644 index 0000000..102addf --- /dev/null +++ b/test/package/migrator/test/function-generate-word.sh @@ -0,0 +1,17 @@ +# shellcheck disable=SC2034 +AS_LIBRARY= +# shellcheck disable=SC1090 +. "$(which migrator)" + +log notice "test case: ${WHITE}generate word" +if ! answer=$(generate_word); then + log error "test failed: ${WHITE}error during generate_word call" + exit 1 +fi + +if [ "$(printf '%s' "$answer" | wc -c)" -ne 6 ]; then + log error "test failed: ${WHITE}word length must be 6 chars" + exit 1 +fi + +log notice "test passed" diff --git a/test/package/migrator/test/function-index-of.sh b/test/package/migrator/test/function-index-of.sh new file mode 100644 index 0000000..f441bdc --- /dev/null +++ b/test/package/migrator/test/function-index-of.sh @@ -0,0 +1,47 @@ +# shellcheck disable=SC2034 +AS_LIBRARY= +# shellcheck disable=SC1090 +. "$(which migrator)" + +array='item1 +item2 +item3 +item4 +item5 +item6 +item7' + +log notice "test case: ${WHITE}index of" +if ! answer=$(index_of "$array" 'item4'); then + log error "test failed: ${WHITE}error during index_of call" + exit 1 +fi + +is_number "$answer" >/dev/null || { log error "test failed: ${WHITE}answer not a number"; exit 1; } + +if [ "$answer" -ne 4 ]; then + log error "test failed: ${WHITE}wrong answer" + exit 1 +fi + +log notice "test case: ${WHITE}error: item not found" +if answer=$(index_of "$array" 'item10'); then + log error "test failed: ${WHITE} must return an error" + exit 1 +fi + +log notice "test case: ${WHITE}one element" +array='20251104192425-add-info-to-profile' +item='20251104192425-add-info-to-profile' + +if ! answer=$(index_of "$array" "$item"); then + log error "test failed: ${WHITE}error during index_of call" + exit 1 +fi + +if [ "$answer" -ne 1 ]; then + log error "test failed: ${WHITE}wrong answer" + exit 1 +fi + +log notice "test passed" diff --git a/test/package/migrator/test/migrate-up/migration/20251104192425-add-info-to-profile.sql b/test/package/migrator/test/function-migration-list/migration/20251104192425-add-info-to-profile/up.sql similarity index 100% rename from test/package/migrator/test/migrate-up/migration/20251104192425-add-info-to-profile.sql rename to test/package/migrator/test/function-migration-list/migration/20251104192425-add-info-to-profile/up.sql diff --git a/test/package/migrator/test/function-migration-list/run.sh b/test/package/migrator/test/function-migration-list/run.sh new file mode 100644 index 0000000..e964452 --- /dev/null +++ b/test/package/migrator/test/function-migration-list/run.sh @@ -0,0 +1,17 @@ +# shellcheck disable=SC2034 +AS_LIBRARY= +# shellcheck disable=SC1090 +. "$(which migrator)" + +log notice "test case: ${WHITE}migration list" +if ! answer=$(migration_list); then + log error "test failed: ${WHITE}error during migration_list call" + exit 1 +fi + +if [ "$answer" != "20251104192425-add-info-to-profile" ]; then + log error "test failed: ${WHITE}unexpected \`migration list\` answer" + exit 1 +fi + +log notice "test passed" diff --git a/test/package/migrator/test/migrate-up/migration/20251104192425-add-info-to-profile/up.sql b/test/package/migrator/test/migrate-up/migration/20251104192425-add-info-to-profile/up.sql new file mode 100644 index 0000000..818abfc --- /dev/null +++ b/test/package/migrator/test/migrate-up/migration/20251104192425-add-info-to-profile/up.sql @@ -0,0 +1 @@ +ALTER TABLE profile ADD COLUMN info TEXT; diff --git a/test/package/migrator/util.sh b/test/package/migrator/util.sh index ec96425..1dd56d1 100644 --- a/test/package/migrator/util.sh +++ b/test/package/migrator/util.sh @@ -6,3 +6,15 @@ columns() { FROM information_schema.columns WHERE table_name = '"${1};" } + +# is_number(var) +is_number() { + case "$1" in + *[!0-9]*) + return 1 + ;; + *) + return 0 + ;; + esac +}