Разбор Crab Mysqldump2Git
Различия
Здесь показаны различия между двумя версиями данной страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
правила_разработки:как_надо_делать:разбор_crab_mysqldump2git [03.09.2018 13:25] admin |
правила_разработки:как_надо_делать:разбор_crab_mysqldump2git [20.05.2019 15:18] (текущий) |
||
---|---|---|---|
Строка 1: | Строка 1: | ||
===== Правим до идеала, спрашиваем все, что непонятно===== | ===== Правим до идеала, спрашиваем все, что непонятно===== | ||
Все неверные решения добавляем в комменты и потом уже правим\\ | Все неверные решения добавляем в комменты и потом уже правим\\ | ||
- | Внимание скрипт не тестировался в продакш, пока идеализируем | ||
<code bash> | <code bash> | ||
#!/bin/bash | #!/bin/bash | ||
- | set -euE | + | |
echo "$0 $@ [$$] START" >&2 | echo "$0 $@ [$$] START" >&2 | ||
+ | set -euE | ||
if [ "${1:---help}" = "--help" ]; then | if [ "${1:---help}" = "--help" ]; then | ||
- | echo "Example: backup: $0 --user=root --password=mypass --host=localhost DB_NAME BACKUP_DIR" | + | echo 'Info: Создает бекап mysql бд и отправляет его в git origin, таблицы пофайлово' |
+ | echo "Usage: $0 --user=root --password=mypass --host=localhost DB_NAME BACKUP_DIR" | ||
echo 'Example: restore: git log; git checkout;' | echo 'Example: restore: git log; git checkout;' | ||
echo 'Example: restore: for f in *.sql.*; do cat $f >>new.sql; done;' | echo 'Example: restore: for f in *.sql.*; do cat $f >>new.sql; done;' | ||
Строка 22: | Строка 23: | ||
ARG_BACKUP_DIR="${5}" | ARG_BACKUP_DIR="${5}" | ||
PREFIX="${ARG_DB_NAME}.sql" | PREFIX="${ARG_DB_NAME}.sql" | ||
- | cd "$BACKUP_DIR" | ||
- | rm -f "$PREFIX.table."* | ||
prepare(){ | prepare(){ | ||
- | ### Присвоение глобальных переменных и ARG_NAME здесь не делаем, делаем в начале скрипта | ||
if [ ! -d .git ]; then | if [ ! -d .git ]; then | ||
git init . | git init . | ||
Строка 33: | Строка 31: | ||
git commit -m init | git commit -m init | ||
fi | fi | ||
+ | if git remote show origin; then | ||
+ | git pull origin master | ||
+ | fi | ||
+ | return 0 | ||
} | } | ||
Строка 44: | Строка 46: | ||
| csplit -n 4 -s -f"$PREFIX.table." - '/-- Table structure for table/' '{*}' | | csplit -n 4 -s -f"$PREFIX.table." - '/-- Table structure for table/' '{*}' | ||
set +o pipefail | set +o pipefail | ||
+ | return 0 | ||
} | } | ||
Строка 58: | Строка 61: | ||
git_commit_push(){ | git_commit_push(){ | ||
+ | local ret | ||
git add . | git add . | ||
- | if ! git status | grep -q 'nothing to commit'; then | + | ret=$( git status ) |
+ | if [[ "$ret" != *'nothing to commit'* ]]; then | ||
git commit -am $(date +%Y-%m-%d_%H-%M) | git commit -am $(date +%Y-%m-%d_%H-%M) | ||
fi | fi | ||
git gc | git gc | ||
if git remote show origin; then | if git remote show origin; then | ||
- | git pull origin master | + | git push origin master |
- | git push origin master | + | |
fi | fi | ||
+ | return 0 | ||
} | } | ||
main(){ | main(){ | ||
- | cd "$BACKUP_DIR" | + | cd "$ARG_BACKUP_DIR" |
rm -f "$PREFIX.table."* | rm -f "$PREFIX.table."* | ||
mysqldump_csplit_per_table | mysqldump_csplit_per_table | ||
table_split_per_size10MB | table_split_per_size10MB | ||
git_commit_push | git_commit_push | ||
+ | return 0 | ||
} | } | ||
main | main | ||
echo "$0 $@ [$$] SUCCESS" >&2 | echo "$0 $@ [$$] SUCCESS" >&2 | ||
- | |||
exit 0 | exit 0 | ||
</code> | </code> | ||
Строка 92: | Строка 97: | ||
### то она должна быть с входными параметрами | ### то она должна быть с входными параметрами | ||
+ | echo "$0 $@ [$$] START" >&2 | ||
### падаем при любых необработанных ошибках | ### падаем при любых необработанных ошибках | ||
set -euE | set -euE | ||
- | echo "$0 $@ [$$] START" >&2 | ||
- | ### Делаем хелп в самом верху скрипта тк он же является и инфо о скрипте и сразу понятно, что делает скрипт | + | ### Делаем --help самом верху скрипта тк он же является и инфо о скрипте и сразу понятно, что делает скрипт |
if [ "${1:---help}" = "--help" ]; then | if [ "${1:---help}" = "--help" ]; then | ||
- | echo "Example: backup: $0 --user=root --password=mypass --host=localhost DB_NAME BACKUP_DIR" | + | echo 'Info: Создает бекап mysql бд и отправляет его в git origin, таблицы пофайлово' |
+ | echo "Usage: $0 --user=root --password=mypass --host=localhost DB_NAME BACKUP_DIR" | ||
echo 'Example: restore: git log; git checkout;' | echo 'Example: restore: git log; git checkout;' | ||
echo 'Example: restore: for f in *.sql.*; do cat $f >>new.sql; done;' | echo 'Example: restore: for f in *.sql.*; do cat $f >>new.sql; done;' | ||
Строка 107: | Строка 113: | ||
### Подготовительная работа | ### Подготовительная работа | ||
### Подготавливаем глобальные переменные, что тождественно приватным property объекта self | ### Подготавливаем глобальные переменные, что тождественно приватным property объекта self | ||
- | ### по сути понимаем, что $USER - это self.user или crab_mysqldump2git.user | + | ### по сути понимаем, что $ARG_USER - это self.user или crab_mysqldump2git.user |
- | ### парсинг аргументов не стандартизован, для простоты кода оставим позиционно зависимый | + | ### все аргументы записываем в ARG_NAME=значение, если это опция ARG_OPTNAME=TRUE, если позиционная в массив ARGV[$ARGC]="$i" |
+ | |||
+ | ### стараемся глобальные переменные устанавливать в начале скрипта так удобней для чтения | ||
+ | # self.ARG_USER="${1/--user=/}" | ||
ARG_USER="${1/--user=/}" | ARG_USER="${1/--user=/}" | ||
+ | # self.ARG_PASSWORD="${2/--password=/}" и т.д. | ||
ARG_PASSWORD="${2/--password=/}" | ARG_PASSWORD="${2/--password=/}" | ||
ARG_DB_HOST="${3/--host=/}" | ARG_DB_HOST="${3/--host=/}" | ||
Строка 115: | Строка 125: | ||
ARG_BACKUP_DIR="${5}" | ARG_BACKUP_DIR="${5}" | ||
PREFIX="${ARG_DB_NAME}.sql" | PREFIX="${ARG_DB_NAME}.sql" | ||
- | cd "$BACKUP_DIR" | ||
- | rm -f "$PREFIX.table."* | ||
- | ### подготовительная работа инициализация каталога при необходимости | + | ### подготовительная работа действия, инициализация каталога при необходимости и тп |
prepare(){ | prepare(){ | ||
### Присвоение глобальных переменных и ARG_NAME здесь не делаем, делаем в начале скрипта | ### Присвоение глобальных переменных и ARG_NAME здесь не делаем, делаем в начале скрипта | ||
Строка 127: | Строка 135: | ||
git commit -m init | git commit -m init | ||
fi | fi | ||
+ | if git remote show origin; then | ||
+ | git pull origin master | ||
+ | fi | ||
+ | return 0 | ||
} | } | ||
Строка 132: | Строка 144: | ||
### Описание пользовательских команд(методов) и функций | ### Описание пользовательских команд(методов) и функций | ||
### метод может работать с глобальными переменным без входящих значений | ### метод может работать с глобальными переменным без входящих значений | ||
- | ### если эти переменные это атрибут объекта self-script или его CONF_NAME переменные | + | ### если эти переменные это атрибут объекта self-script или его ARG_NAME CONF_NAME переменные |
### но если это иные переменные, то обязательно делать через входные значения | ### но если это иные переменные, то обязательно делать через входные значения | ||
- | ### например Только аргументом если мы обрабатываем файлы, | + | ### например ТОЛЬКО аргументом если мы обрабатываем файлы циклом, |
### через for file in /tmp/mysql/*; do funct_name "$file"; done | ### через for file in /tmp/mysql/*; do funct_name "$file"; done | ||
+ | # self.mysqldump_csplit_per_table() | ||
mysqldump_csplit_per_table(){ | mysqldump_csplit_per_table(){ | ||
set -o pipefail | set -o pipefail | ||
Строка 146: | Строка 159: | ||
| csplit -n 4 -s -f"$PREFIX.table." - '/-- Table structure for table/' '{*}' | | csplit -n 4 -s -f"$PREFIX.table." - '/-- Table structure for table/' '{*}' | ||
set +o pipefail | set +o pipefail | ||
- | ### return 0 всегда обязательно, иначе вызов функции может упасть тк вернется не ноль после цикла или if, | ||
- | ### а код возврата от последней команды даже если мы его обработали и он не приведет к локальному падению | ||
return 0 | return 0 | ||
} | } | ||
+ | # self.table_split_per_size10MB() | ||
table_split_per_size10MB(){ | table_split_per_size10MB(){ | ||
local table="" | local table="" | ||
Строка 159: | Строка 171: | ||
fi | fi | ||
done | done | ||
+ | ### return 0 всегда обязательно, иначе вызов функции может упасть тк вернется не ноль после цикла или if, | ||
+ | ### а код возврата от последней команды даже если мы его обработали и он не приведет к локальному падению | ||
return 0 | return 0 | ||
} | } | ||
git_commit_push(){ | git_commit_push(){ | ||
+ | local ret | ||
git add . | git add . | ||
- | if ! git status | grep -q 'nothing to commit'; then | + | ret=$( git status ) |
+ | if [[ "$ret" != *'nothing to commit'* ]]; then | ||
git commit -am $(date +%Y-%m-%d_%H-%M) | git commit -am $(date +%Y-%m-%d_%H-%M) | ||
fi | fi | ||
git gc | git gc | ||
if git remote show origin; then | if git remote show origin; then | ||
- | git pull origin master | + | git push origin master |
- | git push origin master | + | |
fi | fi | ||
+ | return 0 | ||
} | } | ||
Строка 178: | Строка 194: | ||
main(){ | main(){ | ||
### КОМАНДА №1 | ### КОМАНДА №1 | ||
- | cd "$BACKUP_DIR" | + | cd "$ARG_BACKUP_DIR" |
### КОМАНДА №2 | ### КОМАНДА №2 | ||
rm -f "$PREFIX.table."* | rm -f "$PREFIX.table."* | ||
Строка 187: | Строка 203: | ||
### КОМАНДА №5 - это Команда-Метод | ### КОМАНДА №5 - это Команда-Метод | ||
git_commit_push | git_commit_push | ||
+ | return 0 | ||
} | } | ||
- | |||
main | main | ||
echo "$0 $@ [$$] SUCCESS" >&2 | echo "$0 $@ [$$] SUCCESS" >&2 | ||
- | ### обязательно ставим exit 0, | + | ### exit 0 обязателен потому что, если в конце будет условие или выход из цикла и забудешь написать exit 0, то вернется не ноль и все упадет. Всегда надо делать exit 0 и return 0 и не думать каждый раз - это позволит избежать кучу проблем и освобождает мозг. |
- | ### Иначе не гарантии кода возврата 0 даже если скрип выполнился успешно, в конце может быть if или цикл | + | ### Если нужно вернуть не 0 делаем явно [ $ret != 0 ] && exit $ret |
- | ### тк скрипт может вернуть НЕ 0, а например последний резалт от grep и тп | + | |
- | ### даже если мы его отловили | + | |
- | ### при этом не нужно думать, что скрипт всегда вернет 0, | + | |
- | ### скрипт вернет 0 только если все команды успешно выполнилось. | + | |
- | ### другими словами: exit 0 обязателен потому что, если в конце будет условие или выход из цикла и забудешь написать exit 0, то вернется не ноль и все упадет. Всегда надо делать exit 0 и return 0 и не думать каждый раз - это позволит избежать кучу проблем и освобождает мозг. | + | |
exit 0 | exit 0 | ||
</code> | </code> | ||
{(rater>id=1|name=правила_разработки:как_надо_делать:разбор_crab_mysqldump2git|type=vote|trace=user|tracedetails=1)} | {(rater>id=1|name=правила_разработки:как_надо_делать:разбор_crab_mysqldump2git|type=vote|trace=user|tracedetails=1)} | ||
+ | |||
+ | |||
+ | ~~OWNERAPPROVE~~ | ||