From 111db5a1ca2900da21ae062aaa5cee5ef742c068 Mon Sep 17 00:00:00 2001 From: yukkop Date: Tue, 4 Nov 2025 12:15:29 +0000 Subject: [PATCH] feat(package): `migrator`: create new migration --- package/migrator/migrator.sh | 63 ++++++++++++---- .../package/migrator/test/create-migration.sh | 72 +++++++++++++++++++ test/package/migrator/test/placeholder | 0 3 files changed, 123 insertions(+), 12 deletions(-) create mode 100644 test/package/migrator/test/create-migration.sh delete mode 100644 test/package/migrator/test/placeholder diff --git a/package/migrator/migrator.sh b/package/migrator/migrator.sh index 5464f18..e53ded0 100644 --- a/package/migrator/migrator.sh +++ b/package/migrator/migrator.sh @@ -6,11 +6,14 @@ if ! command -v psql >/dev/null; then fi MIGRATION_DIR="${MIGRATION_DIR:-migration}" +quote() { printf "'%s'" "$(printf %s "$1" | sed "s/'/'\\\\''/g")"; } +REMAINING_ARS= while [ $# -gt 0 ]; do + log debug "$1" case $1 in migrate|create|fetch) - [ -n "$SUBCOMMAND" ] || (printf 'ambiguous subcommand, decide %s or %s' "$SUBCOMMAND" "$1"; exit 1) + [ "${SUBCOMMAND+x}" ] && { printf 'ambiguous subcommand, decide %s or %s\n' "$SUBCOMMAND" "$1"; exit 1; } SUBCOMMAND=$1 shift ;; @@ -22,15 +25,12 @@ while [ $# -gt 0 ]; do INHERITS_LIST="${INHERITS_LIST:+$INHERITS_LIST }$2" shift 2 ;; - --*|-*) ;; # skip all unrecognized arguments - *) - printf 'subcommand %s does not exists' "$1" - exit 1 - ;; + --*|-*) REMAINING_ARS="$REMAINING_ARS $(quote "$1")"; shift ;; # unknown global -> pass through + *) REMAINING_ARS="$REMAINING_ARS $(quote "$1")"; shift ;; esac done -[ -z "$SUBCOMMAND" ] || (log error "no subcomand specified"; exit 1) +[ "${SUBCOMMAND+x}" ] || { log error "no subcomand specified"; exit 1; } help() { # inherits: List one or more tables the migration table must inherit from @@ -57,7 +57,7 @@ migrate() { shift 2 ;; --*|-*) - printf 'argument %s does not exists' "$1" + printf 'migrate argument %s does not exists' "$1" exit 1 ;; *) @@ -87,10 +87,10 @@ migrate() { fs_migration=$(echo "$fs_migrations" | sed -n "$((i+1))p") if [ -z "$fs_migration" ] || [ "$fs_migration" != "$db_migration" ]; then if [ -z "$FORCE" ]; then - echo "Unrelated migration tree detected. Use --force to proceed." >&2 + log error "unrelated migration tree detected. Use --force to proceed." exit 2 else - echo "Unrelated migration tree forced. Proceeding..." >&2 + log error "unrelated migration tree forced. Proceeding..." break fi fi @@ -99,15 +99,36 @@ migrate() { } create() { + local time_stamp name file_name file_path + while [ $# -gt 0 ]; do case $1 in --name|-n) # shellcheck disable=SC2034 - NAME=$2 + MIGRATION_NAME=$2 shift 2 ;; + --*|-*) + log error "create argument $1 does not exists" + exit 1 + ;; + *) + log error "create subcommand $1 does not exists" + exit 1 + ;; esac done + + mkdir -p "$MIGRATION_DIR" 2>/dev/null + + time_stamp="$(date '+%Y%m%d%H%M%S')" + name="${MIGRATION_NAME:-$(generate_word)}" + file_name="${time_stamp}-${name}.sql" + file_path="${MIGRATION_DIR}/${file_name}" + + printf '%s Write your migration SQL here\n' '--' > "$file_path" + + log notice "created migration: ${WHITE}${file_path}${NC}" } fetch() { @@ -122,4 +143,22 @@ fetch() { done } -"$SUBCOMMAND" +generate_word() { + C="b c d f g h j k l m n p r s t v w z" + V="a e i o u" + N=${N:-5} + + w= + for i in $(seq 3); do + c=$(echo "$C" | tr ' ' '\n' | shuf -n1) + v=$(echo "$V" | tr ' ' '\n' | shuf -n1) + w="${w}${c}${v}" + done + printf '%s' "$w" +} + +log debug "subcommand: $SUBCOMMAND" +log debug "subcommand args: $REMAINING_ARS" + +eval "set -- $REMAINING_ARS" +"$SUBCOMMAND" "$@" diff --git a/test/package/migrator/test/create-migration.sh b/test/package/migrator/test/create-migration.sh new file mode 100644 index 0000000..50cf4ab --- /dev/null +++ b/test/package/migrator/test/create-migration.sh @@ -0,0 +1,72 @@ +# +# first migration +# + +if ! migrator create; then + log error "test failed: error on migration creation" + exit 1 +fi + +if ! [ -d ./migration ]; then + log error "test failed: migration directory not created" + exit 1 +fi + +if [ "$(find ./migration -maxdepth 1 -type f | wc -l)" -eq 0 ]; then + log error "test failed: migration not created" + exit 1 +fi + +# +# next migration +# + +if ! migrator create; then + log error "test failed: error on migration creation" + exit 1 +fi + +if [ "$(find ./migration -maxdepth 1 -type f | wc -l)" -eq 1 ]; then + log error "test failed: migration not created" + exit 1 +fi + +# +# migration with custom name +# + +if ! migrator create --name test; then + log error "test failed: error on migration creation" + exit 1 +fi + +if [ "$(find ./migration -maxdepth 1 -type f | wc -l)" -eq 2 ]; then + log error "test failed: migration not created" + exit 1 +fi + +if ! find ./migration -maxdepth 1 -type f -name '*test.sql' \ + | grep -Eq '/[0-9]{14}-test\.sql$'; then + log eror "test failed: migration have unexpected name" +fi + +# +# migration with custom name that contains space +# + +if ! migrator create --name 'test name'; then + log error "test failed: error on migration creation" + exit 1 +fi + +if [ "$(find ./migration -maxdepth 1 -type f | wc -l)" -eq 3 ]; then + log error "test failed: migration not created" + exit 1 +fi + +if ! find ./migration -maxdepth 1 -type f -name '*test name.sql' \ + | grep -Eq '/[0-9]{14}-test name\.sql$'; then + log eror "test failed: migration have unexpected name" +fi + +log notice "test passed" diff --git a/test/package/migrator/test/placeholder b/test/package/migrator/test/placeholder deleted file mode 100644 index e69de29..0000000