Last active
March 15, 2018 15:03
-
-
Save aks/9ac0404e3e523e6c4c4032f54c63a78c to your computer and use it in GitHub Desktop.
Bash script to run rails migrations singly interactively
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # run-migrations-singly | |
| PROG=${0##*/} | |
| DIR=${0%/*} | |
| export PATH=$PATH:$HOME/bin:$HOME/lib | |
| # see github.com/aks/bash-lib | |
| source talk-utils.sh | |
| source run-utils.sh | |
| status_log=migration_statuses.log | |
| usage() { | |
| cat 1>&2 <<EOF | |
| usage: $PROG [-hnv] [STARTDATE [ENDDATE]] | |
| Run rails migrations from STARTDATE until ENDDATE, if given. If a date is | |
| omitted, all available down migrations are used. | |
| Options | |
| -h show this help | |
| -n no run; show commands but don't run them | |
| -v be verbose | |
| EOF | |
| exit | |
| } | |
| migration_statuses() { | |
| talk "Fetching migration statuses in $status_log .." | |
| safe_run "bundle exec rake db:migrate:status" | |
| } | |
| prompt_yes_or_no() { | |
| local ans= | |
| while [[ -z "$ans" ]]; do | |
| read -e -p "Run? [yNq]" ans | |
| [[ -z "$ans" ]] && ans=no | |
| case "$ans" in | |
| yes|y|YES|Y) | |
| return 0 ;; | |
| no|n|NO|n) | |
| return 1 ;; | |
| quit|q|QUIT|q) | |
| talk "Quit!" | |
| exit ;; | |
| *) | |
| ans= | |
| talk "Please answer yes or no" ;; | |
| esac | |
| done | |
| } | |
| start_yet() { | |
| test_limit '>' "$@" | |
| } | |
| not_done_yet() { | |
| test_limit '<' "$@" | |
| } | |
| # test_limit ver lim op | |
| test_limit() { | |
| local op="$1" ver="$2" lim="$3" | |
| if eval "[[ -z \"$lim\" || ( \"$ver\" $op \"$lim\" || \"$ver\" = \"$lim\" ) ]]" ; then | |
| return 0 | |
| else | |
| return 1 | |
| fi | |
| } | |
| skipped_line() { | |
| if (( skipping )) ; then | |
| if (( verbose )) ; then | |
| talkf "%s (skipped)\n" "$line" | |
| fi | |
| return 0 | |
| fi | |
| skipping=1 | |
| return 1 | |
| } | |
| skipping_msg() { | |
| (( verbose )) || return 0 | |
| talk "$line" | |
| talk "$1" | |
| } | |
| # up 20180309183346 Add index to site instruction type | |
| # down 20180312232945 Change alternate formats table all ids to bigints stage 1 | |
| run_migrations_up_iteratively() { | |
| local startdate="$1" | |
| local enddate="$2" | |
| local line skipping=0 | |
| local updown version message | |
| exec 3<$status_log # open fd 3 on the status log | |
| while read -u 3 line ; do | |
| if [[ "$line" =~ (down|up)\ *([0-9]{14})\ *([^\ ].*)$ ]] ; then | |
| updown="${BASH_REMATCH[1]}" | |
| version="${BASH_REMATCH[2]}" | |
| message="${BASH_REMATCH[2]}" | |
| case "$updown" in | |
| down) | |
| if start_yet "$version" "$startdate" ; then | |
| if not_done_yet "$version" "$enddate" ; then | |
| talk "$line" | |
| if prompt_yes_or_no ; then | |
| run_migration "$version" | |
| else | |
| talk "Skipped $version" | |
| fi | |
| else # done | |
| skipped_line && continue | |
| skipping_msg "Skipping this and remaining migrations" || break | |
| fi | |
| else # not started yet? | |
| skipped_line && continue | |
| skipping_msg "Skipping this and others until $startdate .." || break | |
| fi | |
| ;; | |
| up) | |
| (( verbose )) && talk "$line" | |
| ;; | |
| esac | |
| else | |
| (( verbose )) && talk "$line" | |
| fi | |
| done | |
| exec 3<&- # close fd 3 | |
| } | |
| run_migration() { | |
| run "bundle exec rake db:migrate:up VERSION=\"$1\"" | |
| } | |
| norun= verbose= | |
| while getopts 'hnv' opt ; do | |
| case "$opt" in | |
| h) usage ;; | |
| n) norun=1 ;; | |
| v) verbose=1 ;; | |
| esac | |
| done | |
| shift $(( OPTIND - 1 )) | |
| case $# in | |
| 2) startdate="$1" enddate="$2" ;; | |
| 1) startdate="$1" enddate= ;; | |
| 0) startdate= enddate= ;; | |
| esac | |
| if [[ ! -e $status_log ]] || find $status_log -mtime +1 1 >& /dev/null ; then | |
| migration_statuses >$status_log | |
| fi | |
| run_migrations_up_iteratively "$startdate" "$enddate" | |
| exit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment