1
0
Fork 0

2024-12-29

This commit is contained in:
Gennadiy 2024-12-29 10:39:47 +03:00
parent fa7f621960
commit 4fb8930c3e
16 changed files with 225 additions and 224 deletions

View file

@ -19,7 +19,8 @@
│ ├─ <a href='bash_scripts/repo_gitea.tmpl.sh'>repo_gitea.tmpl.sh</a>
│ ├─ <a href='bash_scripts/repo_gitlab.tmpl.sh'>repo_gitlab.tmpl.sh</a>
│ ├─ <a href='bash_scripts/repo_local.tmpl.sh'>repo_local.tmpl.sh</a>
│ └─ <a href='bash_scripts/repo_orchestrate.sh'>repo_orchestrate.sh</a>
│ ├─ <a href='bash_scripts/repo_orchestrate.sh'>repo_orchestrate.sh</a>
│ └─ <a href='bash_scripts/repo_testing.smpl.sh'>repo_testing.smpl.sh</a>
├─ <a href='pictures'>pictures</a>
│ ├─ <a href='pictures/README.md'>README.md</a>
│ ├─ <a href='pictures/color-tomato-theme.jpg'>color-tomato-theme.jpg</a>

View file

@ -71,7 +71,7 @@ time_ms="$(date '+%s%3N')"
# вывод строк массива и вызов функции для каждой из них в параллельном режиме
printf '%s\0' "${array[@]}" | xargs -L1 -0 -P0 bash -c
# время работы в миллисекундах
echo "Общее время выполнения: $(("$(date '+%s%3N')" - "$time_ms")) мс."
echo "Общее время выполнения: $(($(date '+%s%3N') - time_ms)) мс."
```
## Вывод

View file

@ -11,10 +11,11 @@ Creating an archive, switching the domain, composing scripts and creating reposi
| | [info_references.sh](info_references.sh) | Updating the domain of a remote repository in cross-references in descriptions. |
| | [info_tree_license.sh](info_tree_license.sh) | Building a directory tree for each project and copying license files. |
| 3 | [**repo_compose.sh**](repo_compose.sh) | Creating scripts from templates with parameters and saving them in the directories of projects. |
| | [repo_gitea.tmpl.sh](repo_gitea.tmpl.sh) | Script template without parameters to create a remote repository gitea. |
| | [repo_gitlab.tmpl.sh](repo_gitlab.tmpl.sh) | Script template without parameters to create a remote repository gitlab. |
| | [repo_local.tmpl.sh](repo_local.tmpl.sh) | Script template without parameters to create a local repository git. |
| | [repo_gitea.tmpl.sh](repo_gitea.tmpl.sh) | Template of a script without parameters to create a remote repository gitea. |
| | [repo_gitlab.tmpl.sh](repo_gitlab.tmpl.sh) | Template of a script without parameters to create a remote repository gitlab. |
| | [repo_local.tmpl.sh](repo_local.tmpl.sh) | Template of a script without parameters to create a local repository git. |
| 4 | [**repo_orchestrate.sh**](repo_orchestrate.sh) | Parallel execution of scripts and creation of repositories for the directories of projects. |
| | [repo_testing.smpl.sh](repo_testing.smpl.sh) | Sample of a script for testing the accessibility of pages in the web-interface on the server. |
## Directories of projects

View file

@ -15,6 +15,7 @@
| | [repo_gitlab.tmpl.sh](repo_gitlab.tmpl.sh) | Шаблон скрипта без параметров для создания удалённого репозитория gitlab. |
| | [repo_local.tmpl.sh](repo_local.tmpl.sh) | Шаблон скрипта без параметров для создания локального репозитория git. |
| 4 | [**repo_orchestrate.sh**](repo_orchestrate.sh) | Параллельное выполнение скриптов и создание репозиториев для каталогов проектов. |
| | [repo_testing.smpl.sh](repo_testing.smpl.sh) | Образец скрипта для тестирования доступности страниц в вёб-интерфейсе на сервере. |
## Каталоги проектов

View file

@ -1,9 +1,9 @@
#!/bin/bash
echo "Создание общего архива для каталогов проектов на текущую дату."
cd ../.. # выходим из папки и из репозитория
cd ../.. # выход из папки и из репозитория
filename="pomodoro-$(date '+%Y-%m-%d').zip"
# сводная строка исключений для всех проектов из файлов ".gitignore"
exclusions="$(find . -maxdepth 2 -type f -name '.gitignore' -exec \
sed -E "s|^(.*)$|-xr!'\1'|" {} \; | sort | uniq | tr '\n' ' ')"
rm -f "$filename"
eval "7z a -tzip '$filename' . -xr!'.git' $exclusions"
eval "7z a -tzip '$filename' . -xr!'.git' $exclusions" | grep -E '\S'

View file

@ -1,7 +1,7 @@
#!/bin/bash
echo "Удаление файлов и папок из каталогов проектов перед восстановлением архива."
echo "ОТМЕНА" && exit 0 # предохранитель
cd ../.. # выходим из папки и из репозитория
echo "Предохранитель: ОТМЕНА" && exit 0
cd ../.. # выход из папки и из репозитория
time_ms="$(date '+%s%3N')"
# обход всех репозиториев, расположенных на одном уровне с текущим, кроме папки ".idea"
find . -mindepth 1 -maxdepth 1 -type d -not -name ".idea" | while read -r dir; do
@ -9,4 +9,4 @@ find . -mindepth 1 -maxdepth 1 -type d -not -name ".idea" | while read -r dir; d
# внутри репозитория — удаление всех вложенных файлов и папок, кроме папки ".git"
find "$dir" -mindepth 1 -maxdepth 1 -type f,d -not -name ".git" -exec rm -r {} \;
done
echo "Общее время выполнения: $(("$(date '+%s%3N')" - "$time_ms")) мс."
echo "Общее время выполнения: $(($(date '+%s%3N') - time_ms)) мс."

View file

@ -9,8 +9,8 @@ function packaging {
cp -v "pomodoro$1.zip" ..
}
export -f packaging
cd ../.. # выходим из папки и из репозитория
cd ../.. # выход из папки и из репозитория
time_ms="$(date '+%s%3N')"
# запуск параллельной обработки репозиториев всех вёб-сайтов
printf '%s\0' {1..6} | xargs -I{} -n1 -0 -P0 bash -c 'packaging "{}"'
echo "Общее время выполнения: $(("$(date '+%s%3N')" - "$time_ms")) мс."
printf 'packaging "%s"\0' {1..6} | xargs -n1 -0 -P0 bash -c
echo "Общее время выполнения: $(($(date '+%s%3N') - time_ms)) мс."

View file

@ -1,5 +1,5 @@
#!/bin/bash
#!/bin/false
#domain="gitea.com"
domain="git.org.ru"
#domain="hub.mos.ru"
echo "Переключение домена удалённого репозитория: $domain"
echo "Домен удалённого репозитория: $domain"

View file

@ -1,30 +1,23 @@
#!/bin/bash
echo "Обновление домена удалённого репозитория в перекрёстных ссылках в описаниях."
export domain="git.org.ru" && source info_param.sh
domain="git.org.ru" && source info_param.sh
# название домена в верхнем регистре
export DOMAIN="${domain^^}"
# обработка информационных файлов
function references {
echo "$domain => $1"
# сбрасываем значения параметров
sed -i "s|gitea\.com|tmp_stub|g" "$1"
sed -i "s|GITEA\.COM|TMP_STUB|g" "$1"
sed -i "s|git\.org\.ru|tmp_stub|g" "$1"
sed -i "s|GIT\.ORG\.RU|TMP_STUB|g" "$1"
sed -i "s|hub\.mos\.ru|tmp_stub|g" "$1"
sed -i "s|HUB\.MOS\.RU|TMP_STUB|g" "$1"
# устанавливаем значения параметров
sed -i "s|tmp_stub|$domain|g" "$1"
sed -i "s|TMP_STUB|$DOMAIN|g" "$1"
if [ "$domain" == "hub.mos.ru" ]; then
sed -i "s|src/branch|blob|g" "$1"
else
sed -i "s|blob|src/branch|g" "$1"
fi
}
export -f references
cd ../.. # выходим из папки и из репозитория
DOMAIN="${domain^^}"
# шаблоны для подстановки
expr+=("s|gitea\.com|$domain|g")
expr+=("s|GITEA\.COM|$DOMAIN|g")
expr+=("s|git\.org\.ru|$domain|g")
expr+=("s|GIT\.ORG\.RU|$DOMAIN|g")
expr+=("s|hub\.mos\.ru|$domain|g")
expr+=("s|HUB\.MOS\.RU|$DOMAIN|g")
if [ "$domain" == "hub.mos.ru" ]; then
expr+=("s|src/branch|blob|g")
else
expr+=("s|blob|src/branch|g")
fi
cd ../.. # выход из папки и из репозитория
time_ms="$(date '+%s%3N')"
# запуск параллельной обработки информационных файлов "README" в подкаталогах репозиториев
find . -type f -name "README*.md" -print0 | xargs -I{} -n1 -0 -P0 bash -c 'references "{}"'
echo "Общее время выполнения: $(("$(date '+%s%3N')" - "$time_ms")) мс."
# запуск параллельной обработки файлов "README" и подстановка значений по шаблонам
find . -type f -name "README*.md" -printf '%p\0' | xargs -I{} -n1 -0 -P0 bash -c \
"echo '$domain => {}' && sed -i $(printf " -e '%s'" "${expr[@]}") '{}'"
echo "Общее время выполнения: $(($(date '+%s%3N') - time_ms)) мс."

View file

@ -12,17 +12,13 @@ function directory_tree {
local head="$2"
local tail="$3"
# префикс для текущего элемента
if [ "one" == "$4" ]; then
echo -n "/"
else
echo -ne "\n$head"
fi
[ "one" == "$4" ] && printf '%s' "/" || printf '\n%s' "$head"
# текущий элемент дерева
echo -n "<a href='${path#*/}'>${path##*/}</a>"
printf '%s' "<a href='${path#*/}'>${path##*/}</a>"
# рекурсивные вызовы для подкаталогов
if [ -d "$path" ]; then
local list # массив файлов и каталогов
readarray -t list <<<"$(list_directory_contents "$path")"
readarray -t list < <(list_directory_contents "$path")
local size=${#list[@]} # длина массива
local i # счётчик
for ((i = 0; i < size; i++)); do
@ -47,19 +43,15 @@ function tree_license {
cp -f ../pomodoro/CONTRIBUTING.md .
cp -f ../pomodoro/*LICENSE* .
fi
# строка исключений для "ls" из списка ".gitignore" — неотслеживаемые файлы
# строка исключений для "ls" из списка неотслеживаемых файлов ".gitignore"
exclusions="-I'.git' $(sed -E "s|^(.*)$|-I'\1'|" .gitignore | tr '\n' ' ')"
# помещаем дерево в контейнер, добавляем заголовок и выводим в файл
{
echo "## Дерево каталогов"
echo -ne "\n<pre>"
directory_tree .
echo -e "\n</pre>"
} >DIRECTORY_TREE.md
printf '%s\n' "## Дерево каталогов" "" "<pre>" \
"$(directory_tree . | grep '\S')" "</pre>" >DIRECTORY_TREE.md
}
export -f tree_license directory_tree list_directory_contents
cd ../.. # выходим из папки и из репозитория
cd ../.. # выход из папки и из репозитория
time_ms="$(date '+%s%3N')"
# запуск параллельной обработки всех репозиториев, расположенных на одном уровне с текущим, кроме папки ".idea"
find . -mindepth 1 -maxdepth 1 -type d -not -name ".idea" -print0 | xargs -I{} -n1 -0 -P0 bash -c 'tree_license "{}"'
echo "Общее время выполнения: $(("$(date '+%s%3N')" - "$time_ms")) мс."
find . -mindepth 1 -maxdepth 1 -type d -not -name ".idea" -printf 'tree_license "%p"\0' | xargs -n1 -0 -P0 bash -c
echo "Общее время выполнения: $(($(date '+%s%3N') - time_ms)) мс."

View file

@ -2,83 +2,85 @@
echo "Создание скриптов из шаблонов с параметрами и сохранение их в каталогах проектов."
export domain="git.org.ru" && source info_param.sh
export basedir="$PWD" # текущая папка
# обновление списка исключений
function update_gitignore {
# добавляем исключение в список ".gitignore", если оно ещё не добавлено
if [ ! -f "$1/.gitignore" ] || [ "$(grep -cF ".repo_*" "$1/.gitignore")" == 0 ]; then
echo ".repo_*" >>"$1/.gitignore"
echo "Обновлён файл: $1/.gitignore"
fi
}
# создание скриптов из шаблонов с параметрами
function compose {
echo "Обработка: $1"
update_gitignore "$1"
# параметры для шаблонов
dir="${1##*/}"
owner="golovin"
repo="$dir"
description=""
if [[ "$dir" =~ "pomodoro" ]]; then
if [[ "$dir" =~ [[:digit:]] ]]; then
owner="pomodoro"
repo="${dir//[^[:digit:]]/}"
case "$repo" in
"1") description="Трёхмерная графика на JavaScript" ;;
"2") description="Декартово произведение, комбинаторика" ;;
"3") description="Умножение матриц и повороты" ;;
"4") description="Практическая философия, поэзия и юмор" ;;
"5") description="Рисуем картинки текстом" ;;
"6") description="Пустой" ;;
*) return ;; # шесть помидорных вёб-сайтов
esac
description+=" — https://$owner$repo.mircloud.ru"
else
description="Описание и оглавление"
fi
elif [[ "$dir" =~ "color-tomato" ]]; then
description="Тема оформления / Цветной помидор"
elif [[ "$dir" =~ "older-tomato" ]]; then
description="Тема оформления / Старый помидор"
# добавление исключения в список неотслеживаемых файлов, если оно ещё не добавлено
if [ ! -f "$1/.gitignore" ] || [ "$(grep -cF ".repo_*" "$1/.gitignore")" == 0 ]; then
echo ".repo_*" >>"$1/.gitignore" && echo "Обновлён файл: $1/.gitignore"
fi
# значения для параметров
owner="golovin" && repo="$1"
case "$1" in
*[1-6]) owner="pomodoro" && repo="${1//$owner/}" ;;&
*1) description="Трёхмерная графика на JavaScript" ;;&
*2) description="Декартово произведение, комбинаторика" ;;&
*3) description="Умножение матриц и повороты" ;;&
*4) description="Практическая философия, поэзия и юмор" ;;&
*5) description="Рисуем картинки текстом" ;;&
*6) description="Пустой" ;;&
*[1-6]) description+=" — https://$owner$repo.mircloud.ru" ;;
pomodoro) description="Описание и оглавление" ;;
color-tomato*) description="Тема оформления / Цветной помидор" ;;
older-tomato*) description="Тема оформления / Старый помидор" ;;
*) return ;; # шесть помидорных вёб-сайтов и три репозитория пользователя
esac
wiki="" # оглавление по страницам вёб-сайта
if [ -f "$dir/WIKI.md" ]; then
if [ -f "$1/WIKI.md" ]; then
if [ "$domain" == "hub.mos.ru" ]; then
wiki="$(uni2ascii -aU -qpsn "$dir/WIKI.md")"
wiki="$(uni2ascii -aU -qpsn "$1/WIKI.md")"
else
wiki="$(basenc "$dir/WIKI.md" --base64 -w0)"
wiki="$(basenc "$1/WIKI.md" --base64 -w0)"
fi
fi
file="DIRECTORY_TREE.md" # тестирование вёб-интерфейса
if [ "$domain" == "hub.mos.ru" ]; then
folder="blob" && wiki_home="-/wikis/home"
else
folder="src/branch" && wiki_home="wiki"
fi
# одинаковая шапка "shebang" для всех трёх скриптов
echo "#!/bin/bash" | tee "$1/.repo_remote.sh" "$1/.repo_local.sh" >"$1/.repo_testing.sh"
# параметры для удалённого репозитория
param_remote+=("domain='$domain'")
param_remote+=("owner='$owner'")
param_remote+=("user='golovin'")
param_remote+=("repo='$repo'")
param_remote+=("description='$description'")
param_remote+=("wiki='$wiki'")
if [ "$domain" == "hub.mos.ru" ]; then
param_remote+=("token='$(cat "$basedir/.token_gitlab")'")
template_remote="repo_gitlab.tmpl.sh"
else
param_remote+=("token='$(cat "$basedir/.token_gitea")'")
template_remote="repo_gitea.tmpl.sh"
fi
# скрипт для создания удалённого репозитория
{
echo "#!/bin/bash"
echo "domain=\"$domain\""
echo "owner=\"$owner\""
echo "user=\"golovin\""
echo "repo=\"$repo\""
echo "description=\"$description\""
echo "wiki=\"$wiki\""
if [ "$domain" == "hub.mos.ru" ]; then
echo "token=\"$(cat "$basedir/.token_gitlab")\""
cat "$basedir/repo_gitlab.tmpl.sh"
else
echo "token=\"$(cat "$basedir/.token_gitea")\""
cat "$basedir/repo_gitea.tmpl.sh"
fi
} >"$dir/.repo_remote.sh" && chmod +x "$dir/.repo_remote.sh"
printf '%s\n' "${param_remote[@]}" >>"$1/.repo_remote.sh"
tail -n+2 "$basedir/$template_remote" >>"$1/.repo_remote.sh"
chmod +x "$1/.repo_remote.sh"
# параметры для локального репозитория
param_local+=("domain='$domain'")
param_local+=("owner='$owner'")
param_local+=("repo='$repo'")
param_local+=("dir='$1'")
# скрипт для создания локального репозитория
{
echo "#!/bin/bash"
echo "domain=\"$domain\""
echo "owner=\"$owner\""
echo "repo=\"$repo\""
echo "dir=\"$dir\""
cat "$basedir/repo_local.tmpl.sh"
} >"$dir/.repo_local.sh" && chmod +x "$dir/.repo_local.sh"
printf '%s\n' "${param_local[@]}" >>"$1/.repo_local.sh"
tail -n+2 "$basedir/repo_local.tmpl.sh" >>"$1/.repo_local.sh"
chmod +x "$1/.repo_local.sh"
# параметры для тестирования вёб-интерфейса
param_testing+=("'https://$domain/$owner/$repo/$folder/master/$file' '$file'")
if [ "$wiki" ]; then
param_testing+=("'https://$domain/$owner/$repo/$wiki_home' 'Home'")
fi
# скрипт для тестирования вёб-интерфейса
printf 'pages+=("%s")\n' "${param_testing[@]}" >>"$1/.repo_testing.sh"
tail -n+21 "$basedir/repo_testing.smpl.sh" >>"$1/.repo_testing.sh"
chmod +x "$1/.repo_testing.sh"
}
export -f compose update_gitignore
cd ../.. # выходим из папки и из репозитория
export -f compose
cd ../.. # выход из папки и из репозитория
time_ms="$(date '+%s%3N')"
# запуск параллельной обработки всех репозиториев, расположенных на одном уровне с текущим, кроме папки ".idea"
find . -mindepth 1 -maxdepth 1 -type d -not -name ".idea" -print0 | xargs -I{} -n1 -0 -P0 bash -c 'compose "{}"'
echo "Общее время выполнения: $(("$(date '+%s%3N')" - "$time_ms")) мс."
find . -mindepth 1 -maxdepth 1 -type d -not -name ".idea" -printf 'compose "%f"\0' | xargs -n1 -0 -P0 bash -c
echo "Общее время выполнения: $(($(date '+%s%3N') - time_ms)) мс."

View file

@ -1,71 +1,62 @@
if [ -z "$domain" ] || [ -z "$token" ] || [ -z "$owner" ] || [ -z "$repo" ] || [ -z "$description" ] || [ -z "$user" ]; then
#!/bin/false
if [[ -z "$domain" || -z "$token" || -z "$owner" || -z "$repo" || -z "$description" || -z "$user" ]]; then
echo "Не указаны обязательные параметры." && exit 1
fi
if [ -z "$1" ]; then
echo "Создание удалённого репозитория для текущего каталога."
fi
seconds=5
time_ms="$(date '+%s%3N')"
if [ -z "$1" ] || [ "$1" == "delete" ]; then
echo "Удаление старого репозитория."
curl -X DELETE "https://$domain/api/v1/repos/$owner/$repo" \
curl -i -X DELETE "https://$domain/api/v1/repos/$owner/$repo" \
-H "Authorization: token $token" \
-H "Accept: application/json" -i
echo "Ожидание $seconds с."
sleep "$seconds"
-H "Accept: application/json"
fi
if [ -z "$1" ] || [ "$1" == "create" ]; then
echo "Создание нового репозитория пользователя."
curl -X POST "https://$domain/api/v1/user/repos" \
curl -i -X POST "https://$domain/api/v1/user/repos" \
-H "Authorization: token $token" \
-H "Accept: application/json" \
-H "Content-Type: application/json" -d "{ \"name\": \"$repo\", \"description\": \"$description\" }" -i
echo "Ожидание $seconds с."
sleep "$seconds"
-H "Content-Type: application/json" -d "{ \"name\": \"$repo\", \"description\": \"$description\" }"
if [ "$user" != "$owner" ]; then
echo "Перемещение репозитория в группу."
curl -X POST "https://$domain/api/v1/repos/$user/$repo/transfer" \
curl -i -X POST "https://$domain/api/v1/repos/$user/$repo/transfer" \
-H "Authorization: token $token" \
-H "Accept: application/json" \
-H "Content-Type: application/json" -d "{ \"new_owner\": \"$owner\" }" -i
echo "Ожидание $seconds с."
sleep "$seconds"
-H "Content-Type: application/json" -d "{ \"new_owner\": \"$owner\" }"
fi
fi
if [ -z "$1" ] || [ "$1" == "options" ]; then
if [ "$wiki" ]; then
echo "Добавление страницы wiki в репозиторий."
curl -X POST "https://$domain/api/v1/repos/$owner/$repo/wiki/new" \
curl -i -X POST "https://$domain/api/v1/repos/$owner/$repo/wiki/new" \
-H "Authorization: token $token" \
-H "Accept: application/json" \
-H "Content-Type: application/json" -d "{ \"content_base64\": \"$wiki\", \"title\": \"Home\" }" -i
-H "Content-Type: application/json" -d "{ \"content_base64\": \"$wiki\", \"title\": \"Home\" }"
has_wiki=true
else
has_wiki=false
fi
echo "Изменение свойств репозитория / отключение ненужного."
curl -X PATCH "https://$domain/api/v1/repos/$owner/$repo" \
curl -i -X PATCH "https://$domain/api/v1/repos/$owner/$repo" \
-H "Authorization: token $token" \
-H "Accept: application/json" \
-H "Content-Type: application/json" -d "{
\"has_actions\": false,
\"has_issues\": false,
\"has_packages\": false,
\"has_projects\": false,
\"has_pull_requests\": false,
\"has_releases\": false,
\"has_wiki\": $has_wiki }" -i
\"has_projects\": false, \"has_issues\": false,
\"has_releases\": false, \"has_actions\": false,
\"has_packages\": false, \"has_pull_requests\": false,
\"has_wiki\": $has_wiki }"
echo "Добавление аватарки для репозитория."
picture="$repo"
if [ "$user" != "$owner" ]; then
picture="website"
fi
avatar=$(basenc "../pomodoro/pictures/$picture.jpg" --base64 -w0)
curl -X POST "https://$domain/api/v1/repos/$owner/$repo/avatar" \
curl -i -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\" }" -i
-H "Content-Type: application/json" -d "{ \"image\": \"$avatar\" }"
fi
if [ -z "$1" ]; then
echo "Общее время выполнения: $(("$(date '+%s%3N')" - "$time_ms")) мс."
echo "Общее время выполнения: $(($(date '+%s%3N') - time_ms)) мс."
fi

View file

@ -1,35 +1,29 @@
if [ -z "$domain" ] || [ -z "$token" ] || [ -z "$owner" ] || [ -z "$repo" ] || [ -z "$description" ] || [ -z "$user" ]; then
#!/bin/false
if [[ -z "$domain" || -z "$token" || -z "$owner" || -z "$repo" || -z "$description" || -z "$user" ]]; then
echo "Не указаны обязательные параметры." && exit 1
fi
if [ -z "$1" ]; then
echo "Создание удалённого репозитория для текущего каталога."
fi
seconds=5
time_ms="$(date '+%s%3N')"
if [ -z "$1" ] || [ "$1" == "delete" ]; then
echo "Удаление старого репозитория."
curl -i -X DELETE "https://$domain/api/v4/projects/$owner%2F$repo" \
-H "PRIVATE-TOKEN: $token" \
-H "Content-Type: application/json" -d "{\"permanently_remove\": \"true\", \"full_path\": \"$owner/$repo\"}"
-H "Content-Type: application/json" -d "{ \"permanently_remove\": \"true\", \"full_path\": \"$owner/$repo\" }"
echo
echo "Ожидание $seconds с."
sleep "$seconds"
fi
if [ -z "$1" ] || [ "$1" == "create" ]; then
echo "Создание нового репозитория пользователя."
curl -i -X POST "https://$domain/api/v4/projects" \
-H "PRIVATE-TOKEN: $token" \
-H "Content-Type: application/json" -d "{\"name\": \"$repo\", \"description\": \"$description\"}"
-H "Content-Type: application/json" -d "{ \"name\": \"$repo\", \"description\": \"$description\" }"
echo
echo "Ожидание $seconds с."
sleep "$seconds"
if [ "$user" != "$owner" ]; then
echo "Перемещение репозитория в группу."
curl -i -X PUT "https://$domain/api/v4/projects/$user%2F$repo/transfer?namespace=$owner" \
-H "PRIVATE-TOKEN: $token"
echo
echo "Ожидание $seconds с."
sleep "$seconds"
fi
fi
if [ -z "$1" ] || [ "$1" == "options" ]; then
@ -37,7 +31,7 @@ if [ -z "$1" ] || [ "$1" == "options" ]; then
echo "Добавление страницы wiki в репозиторий."
curl -i -X POST "https://$domain/api/v4/projects/$owner%2F$repo/wikis" \
-H "PRIVATE-TOKEN: $token" \
-H "Content-Type: application/json" -d "{\"content\": \"$wiki\", \"title\": \"Home\"}"
-H "Content-Type: application/json" -d "{ \"content\": \"$wiki\", \"title\": \"Home\" }"
echo
has_wiki="enabled"
else
@ -47,40 +41,22 @@ if [ -z "$1" ] || [ "$1" == "options" ]; then
curl -i -X PUT "https://$domain/api/v4/projects/$owner%2F$repo" \
-H "PRIVATE-TOKEN: $token" \
-H "Content-Type: application/json" -d "{
\"emails_disabled\": \"true\",
\"issues_access_level\": \"disabled\",
\"merge_requests_access_level\": \"disabled\",
\"operations_access_level\": \"disabled\",
\"builds_access_level\": \"disabled\",
\"request_access_enabled\": \"false\",
\"keep_latest_artifact\": \"false\",
\"ci_forward_deployment_enabled\": \"false\",
\"ci_separated_caches\": \"false\",
\"ci_allow_fork_pipelines_to_run_in_parent_project\": \"false\",
\"jobs_enabled\": \"false\",
\"public_builds\": \"false\",
\"packages_enabled\": \"false\",
\"merge_requests_enabled\": \"false\",
\"issues_enabled\": \"false\",
\"lfs_enabled\": \"false\",
\"snippets_enabled\": \"false\",
\"container_registry_enabled\": \"false\",
\"wiki_access_level\": \"$has_wiki\",
\"container_registry_access_level\": \"disabled\",
\"security_and_compliance_access_level\": \"disabled\",
\"pages_access_level\": \"disabled\",
\"analytics_access_level\": \"disabled\",
\"forking_access_level\": \"disabled\",
\"releases_access_level\": \"disabled\",
\"requirements_access_level\": \"disabled\",
\"environments_access_level\": \"disabled\",
\"feature_flags_access_level\": \"private\",
\"infrastructure_access_level\": \"private\",
\"monitor_access_level\": \"disabled\",
\"snippets_access_level\": \"disabled\",
\"auto_devops_enabled\": \"false\",
\"shared_runners_enabled\": \"false\",
\"group_runners_enabled\": \"false\"}"
\"emails_disabled\": \"true\", \"issues_access_level\": \"disabled\",
\"merge_requests_access_level\": \"disabled\", \"operations_access_level\": \"disabled\",
\"builds_access_level\": \"disabled\", \"request_access_enabled\": \"false\",
\"keep_latest_artifact\": \"false\", \"ci_forward_deployment_enabled\": \"false\",
\"ci_separated_caches\": \"false\", \"ci_allow_fork_pipelines_to_run_in_parent_project\": \"false\",
\"jobs_enabled\": \"false\", \"public_builds\": \"false\", \"packages_enabled\": \"false\",
\"merge_requests_enabled\": \"false\", \"issues_enabled\": \"false\", \"lfs_enabled\": \"false\",
\"snippets_enabled\": \"false\", \"container_registry_enabled\": \"false\",
\"wiki_access_level\": \"$has_wiki\", \"container_registry_access_level\": \"disabled\",
\"security_and_compliance_access_level\": \"disabled\", \"pages_access_level\": \"disabled\",
\"analytics_access_level\": \"disabled\", \"forking_access_level\": \"disabled\",
\"releases_access_level\": \"disabled\", \"requirements_access_level\": \"disabled\",
\"environments_access_level\": \"disabled\", \"feature_flags_access_level\": \"private\",
\"infrastructure_access_level\": \"private\", \"monitor_access_level\": \"disabled\",
\"snippets_access_level\": \"disabled\", \"auto_devops_enabled\": \"false\",
\"shared_runners_enabled\": \"false\", \"group_runners_enabled\": \"false\" }"
echo
echo "Добавление аватарки для репозитория."
picture="$repo"
@ -93,5 +69,5 @@ if [ -z "$1" ] || [ "$1" == "options" ]; then
echo
fi
if [ -z "$1" ]; then
echo "Общее время выполнения: $(("$(date '+%s%3N')" - "$time_ms")) мс."
echo "Общее время выполнения: $(($(date '+%s%3N') - time_ms)) мс."
fi

View file

@ -1,10 +1,10 @@
if [ -z "$domain" ] || [ -z "$owner" ] || [ -z "$repo" ] || [ -z "$dir" ]; then
#!/bin/false
if [[ -z "$domain" || -z "$owner" || -z "$repo" || -z "$dir" ]]; then
echo "Не указаны обязательные параметры." && exit 1
fi
echo "Создание локального репозитория, подключение к удалённому и передача данных."
seconds=3
time_ms="$(date '+%s%3N')"
# строка исключений для "find" из списка ".gitignore" — неотслеживаемые файлы
# строка исключений для "find" из списка неотслеживаемых файлов ".gitignore"
exclusions="-not -path '*/.git/*' $(sed -E "s|^(.*)$|-not -path '*/\1*'|" .gitignore | tr '\n' ' ')"
# перевести размеры файла в человеко-читаемую строку, отбросить нули из дробной части и добавить пробел
function BKM { numfmt --to=iec --format="%.2f" --suffix="B" "$1" | sed -r 's|,{,1}0{,2}([BKM])| \1|'; }
@ -16,8 +16,6 @@ git commit -m "Инициализация / $dir"
if [ "$domain" == "hub.mos.ru" ]; then
echo "Второй пуш, потому что лингвист с первого раза не срабатывает."
git push -u "$domain" master
echo "Ожидание $seconds с."
sleep $seconds
fi
git add CONTRIBUTING.md
git add \*LICENSE*
@ -49,6 +47,6 @@ while read -r file size; do
echo "Обработка: $file"
git add "$file"
git commit -m "${file#*/} / $(BKM "$size")"
done < <(eval "find . -type f $exclusions -printf '%h/%f %s\n'" | LC_COLLATE=C sort -r)
done < <(eval "find . -type f $exclusions -printf '%p %s\n'" | LC_COLLATE=C sort -r)
git push -u "$domain" master
echo "Общее время выполнения: $(("$(date '+%s%3N')" - "$time_ms")) мс."
echo "Общее время выполнения: $(($(date '+%s%3N') - time_ms)) мс."

View file

@ -1,23 +1,34 @@
#!/bin/bash
echo "Параллельное выполнение скриптов и создание репозиториев для каталогов проектов."
# Для всех репозиториев на одном уровне с текущим формируем скрипт в одну строчку и выполняем эти скрипты в параллельном режиме.
# Скрипт в одну строчку — это выполнение одного из заранее подготовленных других скриптов для локальных и удалённых репозиториев.
# Формируем и выполняем скрипты в несколько шагов с разными параметрами и по дороге сохраняем отчёты о выполнении.
# Параллельное выполнение скриптов на последующем шаге начинается после завершения всех потоков на предыдущем шаге.
cd ../.. # выходим из папки и из репозитория
# выполнение скриптов внутри каталога
function orchestrate {
cd "$1" || return
while true; do
while true; do
# 1 Удаление репозитория на сервере
./.repo_remote.sh "delete" >.repo_remote.log
# 2 Создание репозитория на сервере
./.repo_remote.sh "create" >>.repo_remote.log
# 3 Проверка корректности ответа от сервера при создании репозитория
case "$(tail -n+10 .repo_remote.log | grep -cE '^HTTP/[1,2].{,2}? [4,5]')" in
0) break ;; *) echo "Ошибка 400-500. Невозможно подключение к серверу: $1" ;;
esac
done
# 4 Создание локального репозитория и отправка данных на сервер
./.repo_local.sh >.repo_local.log
# 5 Изменение настроек репозитория на сервере, отключение ненужного
./.repo_remote.sh "options" >>.repo_remote.log
# 6 Проверка доступности вёб-интерфейса на сервере
case "$(./.repo_testing.sh | grep -cF '[91m')" in
0) break ;; *) echo "Ошибка доступности вёб-интерфейса: $1" ;;
esac
done
}
export -f orchestrate
cd ../.. # выход из папки и из репозитория
time_ms="$(date '+%s%3N')"
# 1 Удаление репозиториев на сервере
find . -mindepth 1 -maxdepth 1 -type d -printf \
'cd %h/%f && ./.repo_remote.sh "delete" >.repo_remote.log\0' | xargs -L1 -0 -P0 bash -c
# 2 Создание репозиториев на сервере
find . -mindepth 1 -maxdepth 1 -type d -printf \
'cd %h/%f && ./.repo_remote.sh "create" >>.repo_remote.log\0' | xargs -L1 -0 -P0 bash -c
# 3 Проверка корректности пересоздания репозиториев на сервере — выход в случае ошибки
find . -mindepth 2 -maxdepth 2 -type f -name ".repo_remote.log" -exec grep -cE '^HTTP\/[1,2].{,2}? [4,5]' {} \; |
tr -d '0\n' | xargs -r bash -c 'exit 1' || { echo "Ошибка 400-500. Невозможно подключение к серверу." && exit 1; }
# 4 Создание локальных репозиториев и отправка данных на сервер
# 5 Изменение настроек репозиториев на сервере, отключение ненужного
find . -mindepth 1 -maxdepth 1 -type d -printf \
'cd %h/%f && ./.repo_local.sh >.repo_local.log\0
cd %h/%f && ./.repo_remote.sh "options" >>.repo_remote.log\0' | xargs -L1 -0 -P0 bash -c
echo "Общее время выполнения: $(("$(date '+%s%3N')" - "$time_ms")) мс."
# запуск параллельной обработки всех каталогов проектов, расположенных на одном уровне с текущим
find . -mindepth 1 -maxdepth 1 -type d -printf 'orchestrate "%p"\0' | 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"

View file

@ -0,0 +1,35 @@
#!/bin/bash
echo "Образец скрипта для тестирования доступности страниц в вёб-интерфейсе на сервере."
domain="git.org.ru" && source "info_param.sh"
# две страницы для тестирования
file="DIRECTORY_TREE.md"
if [ "$domain" == "hub.mos.ru" ]; then
folder="blob" && wiki_home="-/wikis/home"
else
folder="src/branch" && wiki_home="wiki"
fi
# подготовка массива строк — адрес страницы и название файла через пробел
for repo in {1..6}; do
#pages+=("'https://$domain/golovin/$repo/$folder/master/$file' '$file'")
pages+=("'https://$domain/pomodoro/$repo/$folder/master/$file' '$file'")
pages+=("'https://$domain/pomodoro/$repo/$wiki_home' 'Home'")
done
for repo in {pomodoro,older-tomato-theme,color-tomato-theme}; do
pages+=("'https://$domain/golovin/$repo/$folder/master/$file' '$file'")
pages+=("'https://$domain/golovin/$repo/$wiki_home' 'Home'")
done
# тестирование доступности страниц
function testing {
# название файла должно находиться в заголовке страницы, иначе сервер должен вернуть ошибку
case "$(curl "$1" 2>/dev/null | grep -oP '(?<=<title>).*(?=</title>)' | grep -cF "$2")" in
0) color="91" ;; # светло-красный цвет для отсутствующих страниц
*) color="0" ;; # обычный цвет для всех остальных страниц
esac
# текст соответствующего цвета и адрес страницы
printf "\e[${color}m%s\e[0m %s\n" "Страница:" "$1"
}
export -f testing
time_ms="$(date '+%s%3N')"
# запуск параллельного тестирования строк массива и сортировка результатов
printf "testing %s\0" "${pages[@]}" | xargs -n1 -0 -P0 bash -c | sort -r -k2
echo "Общее время выполнения: $(($(date '+%s%3N') - time_ms)) мс."