#!/bin/bash echo "Копирование данных из репозиториев на сервер 'git.org.ru'." #-----------------------------------------------------------------------------------------------; prompt="Подтверждение (да/нет): " && read -erp "$prompt" line && echo -ne "\033[1A$prompt\033[K" case "${line,,}" in y | yes | д | да) echo "ПОДТВЕРЖДЕНИЕ" ;; *) echo "ОТМЕНА" && exit 0 ;; esac #-----------------------------------------------------------------------------------------------; export domain="git.org.ru" export owner="pictures" export user="golovin" export token && token="$(cat ".token1")" export basedir="$PWD" export bash="$PWD/avatars/bash.jpg" export picture="$PWD/avatars/picture.jpg" #-----------------------------------------------------------------------------------------------; time_ms="$(date '+%s%3N')" # копирование данных function repo_copy1 { repo="${1#*:}" && red="\e[91m" && green="\e[92m" && norm="\e[0m" # соответствующая строка для вывода сообщений по ходу выполнения функции num="${1%:*}" && pre="\e[${num}A${repo}: " && aft="\e[K\e[${num}B\r" cd "$repo" || { printf "${pre}${red}%s${norm}${aft}" "Не найден каталог." && return 1; } # подготовка значений для параметров avatar="$picture" && private="" case "$repo" in "creativity") description="Фотографии без компьютерных эффектов" ;; "creativity3") description="Фотографии и картинки со смыслом и с юмором" ;; "dispatcher") description="Управление репозиториями" && avatar="$bash" ;; "icons") description="Иконки по темам" ;; "wallpapers") description="Обои для рабочего стола" && private="\"private\": true," ;; "wallpapers2") description="Обои для рабочего стола" ;; *) return ;; # никаких лишних каталогов esac avatar="$(basenc "$avatar" --base64 -w0)" # 1. Создание удалённого репозитория на сервере Gitea. # 2. Отправка данных из локального репозитория git на сервер Gitea. # 3. Проверка корректности получения данных на сервере Gitea. for ((ms1 = "$(date '+%s%3N')"; $(date '+%s%3N') - ms1 < 60000; pass = 0)); do for ((ms2 = "$(date '+%s%3N')"; $(date '+%s%3N') - ms2 < 10000; remote = 0)); do [ "$remote" != 0 ] && printf "${pre}%s${aft}" "Удаление старого репозитория на сервере." curl -f -X DELETE "https://$domain/api/v1/repos/$owner/$repo" \ -H "Authorization: token $token" \ -H "Accept: application/json" &>/dev/null \ || { printf "${pre}%s${aft}" "Не удалось удалить репозиторий на сервере."; } [ "$remote" != 0 ] && printf "${pre}%s${aft}" "Создание нового репозитория пользователя." curl -f -X POST "https://$domain/api/v1/user/repos" \ -H "Authorization: token $token" \ -H "Accept: application/json" \ -H "Content-Type: application/json" -d "{ $private \"name\": \"${owner}_${repo}\", \"description\": \"$description\" }" &>/dev/null \ || { printf "${pre}%s${aft}" "Не удалось создать репозиторий на сервере."; } [ "$remote" != 0 ] && printf "${pre}%s${aft}" "Перемещение репозитория в группу." curl -f -X POST "https://$domain/api/v1/repos/$user/${owner}_${repo}/transfer" \ -H "Authorization: token $token" \ -H "Accept: application/json" \ -H "Content-Type: application/json" -d "{ \"new_owner\": \"$owner\" }" &>/dev/null \ || { printf "${pre}%s${aft}" "Не удалось переместить репозиторий в группу." && continue; } [ "$remote" != 0 ] && printf "${pre}%s${aft}" "Переименование репозитория на сервере." curl -f -X PATCH "https://$domain/api/v1/repos/$owner/${owner}_${repo}" \ -H "Authorization: token $token" \ -H "Accept: application/json" \ -H "Content-Type: application/json" -d "{ \"has_projects\": false, \"has_issues\": false, \"has_releases\": false, \"has_actions\": false, \"has_packages\": false, \"has_pull_requests\": false, \"has_wiki\": false, \"name\": \"$repo\" } " &>/dev/null \ || { printf "${pre}%s${aft}" "Не удалось переименовать репозиторий на сервере." && continue; } [ "$remote" != 0 ] && printf "${pre}%s${aft}" "Добавление аватарки для репозитория" curl -f -X POST "https://$domain/api/v1/repos/$owner/$repo/avatar" \ -H "Authorization: token $token" \ -H "Accept: application/json" \ -H "Content-Type: application/json" -d "{ \"image\": \"$avatar\" }" &>/dev/null \ || { printf "${pre}%s${aft}" "Не удалось добавить аватарку для репозитория." && continue; } # завершение цикла remote=1 && break done case "$remote" in 1) printf "${pre}%s${aft}" "Отправка данных на сервер." ;; *) printf "${pre}%s${aft}" "Создание на сервере более 10 секунд." && continue ;; esac git remote add "$domain" "git@$domain:$owner/$repo.git" &>/dev/null git push -u "$domain" "master" &>/dev/null printf "${pre}%s${aft}" "Проверка доступности данных." for ((ms2 = "$(date '+%s%3N')"; $(date '+%s%3N') - ms2 < 10000; testing = 0)); do param="stat=false&verification=false&files=false" curl -f -X GET "https://$domain/api/v1/repos/$owner/$repo/commits?$param" \ -H "Authorization: token $token" \ -H "Accept: application/json" &>/dev/null \ || { printf "${pre}%s${aft}" "Ожидание данных на сервере." && continue; } # завершение цикла testing=1 && break done case "$testing" in 1) pass=1 && break ;; *) printf "${pre}%s${aft}" "Проверка данных более 10 секунд." ;; esac done case "$pass" in 1) printf "${pre}${green}%s${norm}${aft}" "Выполнено." ;; *) printf "${pre}${red}%s${norm}${aft}" "Ожидание более 60 секунд." ;; esac } export -f repo_copy1 cd .. # выход из репозитория # поиск всех каталогов на одном уровне с текущим, кроме папки ".idea", сортировка и добавление порядковых номеров для строк readarray -t folders < <(find . -mindepth 1 -maxdepth 1 -type d -not -name ".idea" -printf '%P\n' | sort -r | grep -n '\S') # смещение курсора вниз на соответствующее количество строк printf '%s\n' "${folders[@]#*:}" | sort # вывод строк массива и параллельный запуск функции для каждого каталога printf 'repo_copy1 "%s"\0' "${folders[@]}" | xargs -n1 -0 -P0 bash -c # замер продолжительности выполнения в миллисекундах, пересчёт в минуты, секунды и миллисекунды tms="$(($(date '+%s%3N') - time_ms))" && min="$((tms / 1000 / 60))" && sec="$((tms / 1000 % 60))" ms="$((tms % 1000))" && printf 'Общее время выполнения: %02d:%02d.%03d мс.\n' "$min" "$sec" "$ms"