Created
September 24, 2025 11:06
-
-
Save ponfertato/08b968a59a0ca97ca21a8199b55e3964 to your computer and use it in GitHub Desktop.
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
| #!/bin/bash | |
| set -e | |
| # Функция для выполнения docker compose команды в указанном каталоге, | |
| # если найден файл compose.yaml или docker-compose.yaml | |
| run_docker() { | |
| local dir="$1" | |
| local docker_cmd="$2" | |
| if [ -f "${dir}/compose.yaml" ]; then | |
| echo "Выполнение: docker compose -f ${dir}/compose.yaml ${docker_cmd}" | |
| docker compose -f "${dir}/compose.yaml" ${docker_cmd} | |
| elif [ -f "${dir}/docker-compose.yaml" ]; then | |
| echo "Выполнение: docker compose -f ${dir}/docker-compose.yaml ${docker_cmd}" | |
| docker compose -f "${dir}/docker-compose.yaml" ${docker_cmd} | |
| else | |
| echo "Файл compose.yaml или docker-compose.yaml не найден в ${dir} — пропуск..." | |
| fi | |
| } | |
| # Функция для проверки, настроен ли upstream для git текущей ветки | |
| upstream_exists() { | |
| if git rev-parse --abbrev-ref --symbolic-full-name @{u} >/dev/null 2>&1; then | |
| return 0 | |
| else | |
| return 1 | |
| fi | |
| } | |
| # Функция выполнения git pull для каталога (подпапок второго уровня) | |
| # Если upstream настроен, то делается git pull и обновляются подмодули, | |
| # если в каталоге присутствует файл .gitmodules. | |
| run_git() { | |
| local dir="$1" | |
| if [ -d "${dir}/.git" ]; then | |
| echo "Обнаружен git репозиторий в ${dir}" | |
| ( | |
| cd "$dir" || exit | |
| if upstream_exists; then | |
| echo "Выполнение: git pull в ${dir}" | |
| git pull | |
| if [ -f ".gitmodules" ]; then | |
| echo "Обновление git submodules в ${dir}" | |
| git submodule update --init --recursive | |
| fi | |
| else | |
| echo "Upstream не настроен для текущей ветки в ${dir} — пропуск git pull" | |
| fi | |
| ) | |
| else | |
| echo "Каталог ${dir} не является git репозиторием — пропуск git pull..." | |
| fi | |
| } | |
| # Обход директорий до 2-х уровней вложенности. | |
| # base_dir - базовый каталог (например, "./" с завершающим слешем) | |
| # level - глубина обхода (1 или 2) | |
| # docker_cmd- команда для docker compose | |
| # need_git - "true", если для подпапок второго уровня необходимо выполнить git pull | |
| traverse_dirs() { | |
| local base_dir="$1" | |
| local level="$2" | |
| local docker_cmd="$3" | |
| local need_git="$4" | |
| # Обходим каталоги первого уровня | |
| for dir in ${base_dir}*/; do | |
| [ -d "$dir" ] || continue | |
| dir="${dir%/}" # удаляем завершающий слеш | |
| # Выполнение docker compose для первого уровня | |
| run_docker "$dir" "${docker_cmd}" | |
| if [ "$level" -ge 2 ]; then | |
| # Подкаталоги (второй уровень) | |
| for sub_dir in "${dir}/"*/; do | |
| [ -d "$sub_dir" ] || continue | |
| sub_dir="${sub_dir%/}" | |
| # Если требуется git — выполняем git pull для подпапок | |
| if [ "$need_git" == "true" ]; then | |
| run_git "$sub_dir" | |
| fi | |
| run_docker "$sub_dir" "${docker_cmd}" | |
| done | |
| fi | |
| done | |
| } | |
| # Функция отображения меню с упрощёнными названиями операций | |
| show_menu() { | |
| clear | |
| echo "Доступные операции:" | |
| echo "1. Down (docker compose down)" | |
| echo "2. Up (docker compose up -d)" | |
| echo "3. Pull (docker compose pull + git pull для подпапок)" | |
| echo "4. Refresh (docker compose pull + docker compose up -d)" | |
| echo "5. Full update (docker compose pull + git pull (для подпапок) + docker compose up -d)" | |
| echo "6. Exit" | |
| read -p "Введите номер операции: " option | |
| } | |
| while true; do | |
| show_menu | |
| case "$option" in | |
| 1) | |
| # Down: docker compose down | |
| read -p "Выполнить для (a) конкретного каталога или (b) для всех проектов? [a/b]: " choice | |
| if [ "$choice" == "a" ]; then | |
| read -p "Введите путь к проекту (без завершающего /): " proj_path | |
| run_docker "$proj_path" "down" | |
| else | |
| traverse_dirs "./" 2 "down" "false" | |
| fi | |
| ;; | |
| 2) | |
| # Up: docker compose up -d | |
| read -p "Выполнить для (a) конкретного каталога или (b) для всех проектов? [a/b]: " choice | |
| if [ "$choice" == "a" ]; then | |
| read -p "Введите путь к проекту (без завершающего /): " proj_path | |
| run_docker "$proj_path" "up -d" | |
| else | |
| traverse_dirs "./" 2 "up -d" "false" | |
| fi | |
| ;; | |
| 3) | |
| # Pull: docker compose pull + git pull (для подпапок 2-го уровня) | |
| read -p "Выполнить для (a) конкретного каталога или (b) для всех проектов? [a/b]: " choice | |
| if [ "$choice" == "a" ]; then | |
| read -p "Введите путь к проекту (без завершающего /): " proj_path | |
| run_docker "$proj_path" "pull" | |
| # Для подпапок второго уровня выполняем git pull | |
| for sub_dir in "${proj_path}/"*/; do | |
| [ -d "$sub_dir" ] || continue | |
| sub_dir="${sub_dir%/}" | |
| run_git "$sub_dir" | |
| done | |
| else | |
| traverse_dirs "./" 2 "pull" "true" | |
| fi | |
| ;; | |
| 4) | |
| # Refresh: docker compose pull + docker compose up -d (без git) | |
| read -p "Выполнить для (a) конкретного каталога или (b) для всех проектов? [a/b]: " choice | |
| if [ "$choice" == "a" ]; then | |
| read -p "Введите путь к проекту (без завершающего /): " proj_path | |
| run_docker "$proj_path" "pull" | |
| run_docker "$proj_path" "up -d" | |
| else | |
| traverse_dirs "./" 2 "pull" "false" | |
| traverse_dirs "./" 2 "up -d" "false" | |
| fi | |
| ;; | |
| 5) | |
| # Full update: docker compose pull + git pull (подпапки 2-го уровня) + docker compose up -d | |
| read -p "Выполнить для (a) конкретного каталога или (b) для всех проектов? [a/b]: " choice | |
| if [ "$choice" == "a" ]; then | |
| read -p "Введите путь к проекту (без завершающего /): " proj_path | |
| run_docker "$proj_path" "pull" | |
| for sub_dir in "${proj_path}/"*/; do | |
| [ -d "$sub_dir" ] || continue | |
| sub_dir="${sub_dir%/}" | |
| run_git "$sub_dir" | |
| done | |
| run_docker "$proj_path" "up -d" | |
| else | |
| traverse_dirs "./" 2 "pull" "true" | |
| traverse_dirs "./" 2 "up -d" "false" | |
| fi | |
| ;; | |
| 6) | |
| echo "Выход..." | |
| exit 0 | |
| ;; | |
| *) | |
| echo "Неверный выбор. Попробуйте снова." | |
| ;; | |
| esac | |
| echo "Нажмите Enter для продолжения..." | |
| read | |
| done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment