1
0
Fork 0

2025-01-31

This commit is contained in:
Gennadiy 2025-01-31 09:24:35 +03:00
parent 4fb8930c3e
commit c008881b5e
17 changed files with 225 additions and 136 deletions

View file

@ -16,10 +16,12 @@
│ ├─ <a href='bash_scripts/info_references.sh'>info_references.sh</a> │ ├─ <a href='bash_scripts/info_references.sh'>info_references.sh</a>
│ ├─ <a href='bash_scripts/info_tree_license.sh'>info_tree_license.sh</a> │ ├─ <a href='bash_scripts/info_tree_license.sh'>info_tree_license.sh</a>
│ ├─ <a href='bash_scripts/repo_compose.sh'>repo_compose.sh</a> │ ├─ <a href='bash_scripts/repo_compose.sh'>repo_compose.sh</a>
│ ├─ <a href='bash_scripts/repo_gitea.tmpl.sh'>repo_gitea.tmpl.sh</a> │ ├─ <a href='bash_scripts/repo_forgejo.tmpl.sh'>repo_forgejo.tmpl.sh</a>
│ ├─ <a href='bash_scripts/repo_forgejo2.tmpl.sh'>repo_forgejo2.tmpl.sh</a>
│ ├─ <a href='bash_scripts/repo_gitlab.tmpl.sh'>repo_gitlab.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_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_pages2.sh'>repo_pages2.sh</a>
│ └─ <a href='bash_scripts/repo_testing.smpl.sh'>repo_testing.smpl.sh</a> │ └─ <a href='bash_scripts/repo_testing.smpl.sh'>repo_testing.smpl.sh</a>
├─ <a href='pictures'>pictures</a> ├─ <a href='pictures'>pictures</a>
│ ├─ <a href='pictures/README.md'>README.md</a> │ ├─ <a href='pictures/README.md'>README.md</a>

View file

@ -1,4 +1,4 @@
© Головин Г.Г., 2021-2024 © Головин Г.Г., 2021-2025
Опубликовано под [Открытой лицензией 1.1](OPEN_LICENSE.txt) Опубликовано под [Открытой лицензией 1.1](OPEN_LICENSE.txt)
@ -8,7 +8,7 @@
--- ---
© Golovin G.G., translation from Russian, 2021-2024 © Golovin G.G., translation from Russian, 2021-2025
Published under the [Open License 1.1](OPEN_LICENSE.txt) Published under the [Open License 1.1](OPEN_LICENSE.txt)

View file

@ -6,7 +6,7 @@ JavaScript and open license RF instead of MIT — there are a lot of changes and
remains the same — nothing has changed. Series of static websites «Pomodori» — not to be bored and not to remains the same — nothing has changed. Series of static websites «Pomodori» — not to be bored and not to
forget how to write programs, when there is no work. forget how to write programs, when there is no work.
- [gitea&period;com](https://gitea&period;com/pomodoro) — latest version. - [codeberg&period;org](https://codeberg&period;org/pomodoro) — latest version.
- [git&period;org&period;ru](https://git&period;org&period;ru/pomodoro) — history of changes. - [git&period;org&period;ru](https://git&period;org&period;ru/pomodoro) — history of changes.
- [hub&period;mos&period;ru](https://hub&period;mos&period;ru/pomodoro) — history of changes. - [hub&period;mos&period;ru](https://hub&period;mos&period;ru/pomodoro) — history of changes.
@ -76,4 +76,4 @@ provided free of charge, but without any guarantees, and the author of the progr
--- ---
© Golovin G.G., Code with comments, translation from Russian, 2021-2024 © Golovin G.G., Code with comments, translation from Russian, 2021-2025

View file

@ -5,7 +5,7 @@
открытая лицензия РФ вместо MIT — изменений много и везде, но суть осталась прежней — ничего не изменилось. Серия открытая лицензия РФ вместо MIT — изменений много и везде, но суть осталась прежней — ничего не изменилось. Серия
статических вёб-сайтов «Помидоры» — чтобы не скучать и чтобы не забыть, как программы писать, когда работы нет. статических вёб-сайтов «Помидоры» — чтобы не скучать и чтобы не забыть, как программы писать, когда работы нет.
- [gitea&period;com](https://gitea&period;com/pomodoro) — последняя версия. - [codeberg&period;org](https://codeberg&period;org/pomodoro) — последняя версия.
- [git&period;org&period;ru](https://git&period;org&period;ru/pomodoro) — история изменений. - [git&period;org&period;ru](https://git&period;org&period;ru/pomodoro) — история изменений.
- [hub&period;mos&period;ru](https://hub&period;mos&period;ru/pomodoro) — история изменений. - [hub&period;mos&period;ru](https://hub&period;mos&period;ru/pomodoro) — история изменений.
@ -73,4 +73,4 @@
--- ---
© Головин Г.Г., Код с комментариями, 2021-2024 © Головин Г.Г., Код с комментариями, 2021-2025

13
WIKI.md
View file

@ -1,7 +1,5 @@
<hr>
<details open> <details open>
<summary><h3>Оглавление</h3></summary> <summary><b>Оглавление / Contents</b></summary>
<hr> <hr>
@ -33,13 +31,6 @@
- [График функции в консоли](https://pomodoro5.mircloud.ru/ru/2023/02/05/function-graph-in-console.html) — 05.02.2023. - [График функции в консоли](https://pomodoro5.mircloud.ru/ru/2023/02/05/function-graph-in-console.html) — 05.02.2023.
- [Рисуем простую капчу](https://pomodoro5.mircloud.ru/ru/2023/01/03/drawing-simple-captcha.html) — 03.01.2023. - [Рисуем простую капчу](https://pomodoro5.mircloud.ru/ru/2023/01/03/drawing-simple-captcha.html) — 03.01.2023.
</details>
<hr>
<details open>
<summary><h3>Contents</h3></summary>
<hr> <hr>
1. Three-dimensional graphics in JavaScript. 1. Three-dimensional graphics in JavaScript.
@ -68,5 +59,3 @@
- [Drawing simple captcha](https://pomodoro5.mircloud.ru/en/2023/01/04/drawing-simple-captcha.html) — 04.01.2023. - [Drawing simple captcha](https://pomodoro5.mircloud.ru/en/2023/01/04/drawing-simple-captcha.html) — 04.01.2023.
</details> </details>
<hr>

View file

@ -11,10 +11,12 @@ 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_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. | | | [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. | | 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) | Template of a script without parameters to create a remote repository gitea. | | | [repo_forgejo.tmpl.sh](repo_forgejo.tmpl.sh) | Template of a script without parameters to create a remote repository forgejo. |
| | [repo_forgejo2.tmpl.sh](repo_forgejo2.tmpl.sh) | Template of a script without parameters to deploy a website on the server codeberg. |
| | [repo_gitlab.tmpl.sh](repo_gitlab.tmpl.sh) | Template of a script without parameters to create a remote repository gitlab. | | | [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. | | | [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. | | 4 | [**repo_orchestrate.sh**](repo_orchestrate.sh) | Parallel execution of scripts and creation of repositories for the directories of projects. |
| | [repo_pages2.sh](repo_pages2.sh) | Parallel execution of scripts and deploying the websites on the server codeberg. |
| | [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. | | | [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 ## Directories of projects
@ -22,7 +24,7 @@ Creating an archive, switching the domain, composing scripts and creating reposi
Local project directories are located on the same level. On the server, Local project directories are located on the same level. On the server,
repositories with websites are moved to a separate group, and the rest repositories with websites are moved to a separate group, and the rest
of the repositories remain with the user. The directory structure for of the repositories remain with the user. The directory structure for
[gitea&period;com](https://gitea&period;com/golovin), [codeberg&period;org](https://codeberg&period;org/golovin),
[git&period;org&period;ru](https://git&period;org&period;ru/golovin) and [git&period;org&period;ru](https://git&period;org&period;ru/golovin) and
[hub&period;mos&period;ru](https://hub&period;mos&period;ru/golovin). [hub&period;mos&period;ru](https://hub&period;mos&period;ru/golovin).

View file

@ -11,10 +11,12 @@
| | [info_references.sh](info_references.sh) | Обновление домена удалённого репозитория в перекрёстных ссылках в описаниях. | | | [info_references.sh](info_references.sh) | Обновление домена удалённого репозитория в перекрёстных ссылках в описаниях. |
| | [info_tree_license.sh](info_tree_license.sh) | Построение дерева каталогов для каждого проекта и копирование файлов лицензии. | | | [info_tree_license.sh](info_tree_license.sh) | Построение дерева каталогов для каждого проекта и копирование файлов лицензии. |
| 3 | [**repo_compose.sh**](repo_compose.sh) | Создание скриптов из шаблонов с параметрами и сохранение их в каталогах проектов. | | 3 | [**repo_compose.sh**](repo_compose.sh) | Создание скриптов из шаблонов с параметрами и сохранение их в каталогах проектов. |
| | [repo_gitea.tmpl.sh](repo_gitea.tmpl.sh) | Шаблон скрипта без параметров для создания удалённого репозитория gitea. | | | [repo_forgejo.tmpl.sh](repo_forgejo.tmpl.sh) | Шаблон скрипта без параметров для создания удалённого репозитория forgejo. |
| | [repo_forgejo2.tmpl.sh](repo_forgejo2.tmpl.sh) | Шаблон скрипта без параметров для развёртывания вёб-сайта на сервере codeberg. |
| | [repo_gitlab.tmpl.sh](repo_gitlab.tmpl.sh) | Шаблон скрипта без параметров для создания удалённого репозитория gitlab. | | | [repo_gitlab.tmpl.sh](repo_gitlab.tmpl.sh) | Шаблон скрипта без параметров для создания удалённого репозитория gitlab. |
| | [repo_local.tmpl.sh](repo_local.tmpl.sh) | Шаблон скрипта без параметров для создания локального репозитория git. | | | [repo_local.tmpl.sh](repo_local.tmpl.sh) | Шаблон скрипта без параметров для создания локального репозитория git. |
| 4 | [**repo_orchestrate.sh**](repo_orchestrate.sh) | Параллельное выполнение скриптов и создание репозиториев для каталогов проектов. | | 4 | [**repo_orchestrate.sh**](repo_orchestrate.sh) | Параллельное выполнение скриптов и создание репозиториев для каталогов проектов. |
| | [repo_pages2.sh](repo_pages2.sh) | Параллельное выполнение скриптов и развёртывание вёб-сайтов на сервере codeberg. |
| | [repo_testing.smpl.sh](repo_testing.smpl.sh) | Образец скрипта для тестирования доступности страниц в вёб-интерфейсе на сервере. | | | [repo_testing.smpl.sh](repo_testing.smpl.sh) | Образец скрипта для тестирования доступности страниц в вёб-интерфейсе на сервере. |
## Каталоги проектов ## Каталоги проектов
@ -22,7 +24,7 @@
Локальные каталоги проектов расположены на одном уровне. На сервере Локальные каталоги проектов расположены на одном уровне. На сервере
репозитории с вёб-сайтами переходят в отдельную группу, а остальные репозитории с вёб-сайтами переходят в отдельную группу, а остальные
репозитории остаются у пользователя. Структура каталогов для репозитории остаются у пользователя. Структура каталогов для
[gitea&period;com](https://gitea&period;com/golovin), [codeberg&period;org](https://codeberg&period;org/golovin),
[git&period;org&period;ru](https://git&period;org&period;ru/golovin) и [git&period;org&period;ru](https://git&period;org&period;ru/golovin) и
[hub&period;mos&period;ru](https://hub&period;mos&period;ru/golovin). [hub&period;mos&period;ru](https://hub&period;mos&period;ru/golovin).

View file

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

View file

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

View file

@ -4,8 +4,8 @@ domain="git.org.ru" && source info_param.sh
# название домена в верхнем регистре # название домена в верхнем регистре
DOMAIN="${domain^^}" DOMAIN="${domain^^}"
# шаблоны для подстановки # шаблоны для подстановки
expr+=("s|gitea\.com|$domain|g") expr+=("s|codeberg\.org|$domain|g")
expr+=("s|GITEA\.COM|$DOMAIN|g") expr+=("s|CODEBERG\.ORG|$DOMAIN|g")
expr+=("s|git\.org\.ru|$domain|g") expr+=("s|git\.org\.ru|$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")

View file

@ -1,30 +1,31 @@
#!/bin/bash #!/bin/bash
echo "Построение дерева каталогов для каждого проекта и копирование файлов лицензии." echo "Построение дерева каталогов для каждого проекта и копирование файлов лицензии."
# отсортированный список файлов и каталогов
function list_directory_contents {
# сначала заглавные буквы, потом строчные, сначала каталоги, потом файлы
eval "LC_COLLATE=C ls -A --group-directories-first $exclusions $1"
}
# дерево каталогов со ссылками # дерево каталогов со ссылками
function directory_tree { function directory_tree {
# аргументы # аргументы
local path="$1" local path="$1"
local head="$2" local head="$2"
local tail="$3" local tail="$3"
# префикс для текущего элемента # получить содержимое каталога
[ "one" == "$4" ] && printf '%s' "/" || printf '\n%s' "$head" if [ -d "$path" ]; then
# текущий элемент дерева # сначала заглавные буквы, потом строчные, сначала каталоги, потом файлы
ls_sorted="LC_COLLATE=C ls -A --group-directories-first $exclusions $path"
# отсортированный массив файлов и каталогов
local list && readarray -t list < <(eval "$ls_sorted")
# длина массива
local size=${#list[@]}
# пропустить пустой каталог
[ "$size" == 0 ] && return
fi
# префикс текущего элемента, сворачивать синглтоны в одну строку
[ "$4" == "one" ] && printf '%s' "/" || printf '\n%s' "$head"
# текущий элемент дерева — относительная гиперссылка
printf '%s' "<a href='${path#*/}'>${path##*/}</a>" printf '%s' "<a href='${path#*/}'>${path##*/}</a>"
# рекурсивные вызовы для подкаталогов # рекурсивные вызовы для подкаталогов
if [ -d "$path" ]; then if [ -d "$path" ]; then
local list # массив файлов и каталогов
readarray -t list < <(list_directory_contents "$path")
local size=${#list[@]} # длина массива
local i # счётчик local i # счётчик
for ((i = 0; i < size; i++)); do for ((i = 0; i < size; i++)); do
if [ -z "${list[$i]}" ]; then if ((size == 1)); then
continue # пропустить пустой каталог
elif ((size == 1)); then
directory_tree "$path/${list[$i]}" "$tail" "$tail" "one" directory_tree "$path/${list[$i]}" "$tail" "$tail" "one"
elif ((i < size - 1)); then elif ((i < size - 1)); then
directory_tree "$path/${list[$i]}" "$tail├─ " "$tail" directory_tree "$path/${list[$i]}" "$tail├─ " "$tail"
@ -40,8 +41,8 @@ function tree_license {
cd "$1" || return cd "$1" || return
# копирование файлов из этого репозитория во все остальные # копирование файлов из этого репозитория во все остальные
if [ "$1" != "./pomodoro" ]; then if [ "$1" != "./pomodoro" ]; then
cp -f ../pomodoro/CONTRIBUTING.md . cp --remove-destination ../pomodoro/CONTRIBUTING.md .
cp -f ../pomodoro/*LICENSE* . cp --remove-destination ../pomodoro/*LICENSE* .
fi fi
# строка исключений для "ls" из списка неотслеживаемых файлов ".gitignore" # строка исключений для "ls" из списка неотслеживаемых файлов ".gitignore"
exclusions="-I'.git' $(sed -E "s|^(.*)$|-I'\1'|" .gitignore | tr '\n' ' ')" exclusions="-I'.git' $(sed -E "s|^(.*)$|-I'\1'|" .gitignore | tr '\n' ' ')"
@ -49,7 +50,7 @@ function tree_license {
printf '%s\n' "## Дерево каталогов" "" "<pre>" \ printf '%s\n' "## Дерево каталогов" "" "<pre>" \
"$(directory_tree . | grep '\S')" "</pre>" >DIRECTORY_TREE.md "$(directory_tree . | grep '\S')" "</pre>" >DIRECTORY_TREE.md
} }
export -f tree_license directory_tree list_directory_contents export -f tree_license directory_tree
cd ../.. # выход из папки и из репозитория cd ../.. # выход из папки и из репозитория
time_ms="$(date '+%s%3N')" time_ms="$(date '+%s%3N')"
# запуск параллельной обработки всех репозиториев, расположенных на одном уровне с текущим, кроме папки ".idea" # запуск параллельной обработки всех репозиториев, расположенных на одном уровне с текущим, кроме папки ".idea"

View file

@ -2,15 +2,16 @@
echo "Создание скриптов из шаблонов с параметрами и сохранение их в каталогах проектов." echo "Создание скриптов из шаблонов с параметрами и сохранение их в каталогах проектов."
export domain="git.org.ru" && source info_param.sh export domain="git.org.ru" && source info_param.sh
export basedir="$PWD" # текущая папка export basedir="$PWD" # текущая папка
# создание скриптов из шаблонов с параметрами # создание скриптов внутри каталога
function compose { function compose {
echo "Обработка: $1" echo "Обработка: $1"
# добавление исключения в список неотслеживаемых файлов, если оно ещё не добавлено cd "$1" || return
if [ ! -f "$1/.gitignore" ] || [ "$(grep -cF ".repo_*" "$1/.gitignore")" == 0 ]; then # добавление скриптов в список неотслеживаемых файлов, если ещё не добавлено
echo ".repo_*" >>"$1/.gitignore" && echo "Обновлён файл: $1/.gitignore" if [[ ! -f ".gitignore" || "$(grep -cF ".repo_*" ".gitignore")" == 0 ]]; then
echo ".repo_*" >>".gitignore" && echo "Обновлён файл: $1/.gitignore"
fi fi
# значения для параметров # подготовка значений для параметров
owner="golovin" && repo="$1" user="golovin" && owner="$user" && repo="$1"
case "$1" in case "$1" in
*[1-6]) owner="pomodoro" && repo="${1//$owner/}" ;;& *[1-6]) owner="pomodoro" && repo="${1//$owner/}" ;;&
*1) description="Трёхмерная графика на JavaScript" ;;& *1) description="Трёхмерная графика на JavaScript" ;;&
@ -20,63 +21,67 @@ function compose {
*5) description="Рисуем картинки текстом" ;;& *5) description="Рисуем картинки текстом" ;;&
*6) description="Пустой" ;;& *6) description="Пустой" ;;&
*[1-6]) description+=" — https://$owner$repo.mircloud.ru" ;; *[1-6]) description+=" — https://$owner$repo.mircloud.ru" ;;
pomodoro) description="Описание и оглавление" ;; pomodoro) description="Описание и управление" ;;
color-tomato*) description="Тема оформления / Цветной помидор" ;; color*) description="Тема оформления / Цветной помидор" ;;
older-tomato*) description="Тема оформления / Старый помидор" ;; older*) description="Тема оформления / Старый помидор" ;;
*) return ;; # шесть помидорных вёб-сайтов и три репозитория пользователя *) return ;; # шесть помидорных вёб-сайтов и три сопутствующих проекта
esac esac
wiki="" # оглавление по страницам вёб-сайта
if [ -f "$1/WIKI.md" ]; then
if [ "$domain" == "hub.mos.ru" ]; then if [ "$domain" == "hub.mos.ru" ]; then
wiki="$(uni2ascii -aU -qpsn "$1/WIKI.md")" [ -f "WIKI.md" ] && wiki="$(uni2ascii -aU -qpsn "WIKI.md")"
model="gitlab" && folder="blob" && wiki_home="-/wikis/home"
else else
wiki="$(basenc "$1/WIKI.md" --base64 -w0)" [ -f "WIKI.md" ] && wiki="$(basenc "WIKI.md" --base64 -w0)"
model="forgejo" && folder="src/branch" && wiki_home="wiki"
fi fi
if [ "$domain" == "codeberg.org" ]; then
if [ -f "WIKI.md" ]; then
wiki="$(sed 's|mircloud\.ru|codeberg.page|g' WIKI.md | basenc --base64 -w0)"
fi fi
file="DIRECTORY_TREE.md" # тестирование вёб-интерфейса [[ "$1" =~ [1-6] ]] && description="${description//mircloud.ru/codeberg.page}"
if [ "$domain" == "hub.mos.ru" ]; then
folder="blob" && wiki_home="-/wikis/home"
else
folder="src/branch" && wiki_home="wiki"
fi fi
# одинаковая шапка "shebang" для всех трёх скриптов file="DIRECTORY_TREE.md"
echo "#!/bin/bash" | tee "$1/.repo_remote.sh" "$1/.repo_local.sh" >"$1/.repo_testing.sh" # создание трёх скриптов в каталоге проекта с одинаковой шапкой для всех
echo "#!/bin/bash" | tee ".repo_remote.sh" ".repo_local.sh" >".repo_testing.sh"
chmod +x ".repo_remote.sh" ".repo_local.sh" ".repo_testing.sh"
# параметры для удалённого репозитория # параметры для удалённого репозитория
param_remote+=("domain='$domain'") param_remote+=("domain='$domain'")
param_remote+=("owner='$owner'") param_remote+=("owner='$owner'")
param_remote+=("user='golovin'") param_remote+=("user='$user'")
param_remote+=("repo='$repo'") param_remote+=("repo='$repo'")
param_remote+=("description='$description'") param_remote+=("description='$description'")
param_remote+=("wiki='$wiki'") param_remote+=("wiki='$wiki'")
if [ "$domain" == "hub.mos.ru" ]; then param_remote+=("token='$(head -n+1 "$basedir/.token_$model")'")
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
# скрипт для создания удалённого репозитория # скрипт для создания удалённого репозитория
printf '%s\n' "${param_remote[@]}" >>"$1/.repo_remote.sh" printf '%s\n' "${param_remote[@]}" >>".repo_remote.sh"
tail -n+2 "$basedir/$template_remote" >>"$1/.repo_remote.sh" tail -n+2 "$basedir/repo_$model.tmpl.sh" >>".repo_remote.sh"
chmod +x "$1/.repo_remote.sh"
# параметры для локального репозитория # параметры для локального репозитория
param_local+=("domain='$domain'") param_local+=("domain='$domain'")
param_local+=("owner='$owner'") param_local+=("owner='$owner'")
param_local+=("repo='$repo'") param_local+=("repo='$repo'")
param_local+=("dir='$1'") param_local+=("dir='$1'")
# скрипт для создания локального репозитория # скрипт для создания локального репозитория
printf '%s\n' "${param_local[@]}" >>"$1/.repo_local.sh" printf '%s\n' "${param_local[@]}" >>".repo_local.sh"
tail -n+2 "$basedir/repo_local.tmpl.sh" >>"$1/.repo_local.sh" tail -n+2 "$basedir/repo_local.tmpl.sh" >>".repo_local.sh"
chmod +x "$1/.repo_local.sh"
# параметры для тестирования вёб-интерфейса # параметры для тестирования вёб-интерфейса
param_testing+=("'https://$domain/$owner/$repo/$folder/master/$file' '$file'") param_testing+=("'https://$domain/$owner/$repo/$folder/master/$file' '$file'")
if [ "$wiki" ]; then [ "$wiki" ] && param_testing+=("'https://$domain/$owner/$repo/$wiki_home' 'Home'")
param_testing+=("'https://$domain/$owner/$repo/$wiki_home' 'Home'")
fi
# скрипт для тестирования вёб-интерфейса # скрипт для тестирования вёб-интерфейса
printf 'pages+=("%s")\n' "${param_testing[@]}" >>"$1/.repo_testing.sh" printf 'pages+=("%s")\n' "${param_testing[@]}" >>".repo_testing.sh"
tail -n+21 "$basedir/repo_testing.smpl.sh" >>"$1/.repo_testing.sh" tail -n+21 "$basedir/repo_testing.smpl.sh" >>".repo_testing.sh"
chmod +x "$1/.repo_testing.sh" if [[ "$domain" == "codeberg.org" && "$1" =~ [1-6] ]]; then
# параметры для развёртывания вёб-сайта
param_pages+=("#!/bin/bash")
param_pages+=("domain='$domain'")
param_pages+=("owner='$owner$repo'")
param_pages+=("user='$user'")
param_pages+=("repo='pages'")
param_pages+=("description='$description'")
param_pages+=("token='$(head -n+1 "$basedir/.token_forgejo")'")
# скрипт для развёртывания вёб-сайта
printf '%s\n' "${param_pages[@]}" >".repo_pages2.sh"
tail -n+2 "$basedir/repo_forgejo2.tmpl.sh" >>".repo_pages2.sh"
chmod +x ".repo_pages2.sh"
fi
} }
export -f compose export -f compose
cd ../.. # выход из папки и из репозитория cd ../.. # выход из папки и из репозитория

View file

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

View file

@ -0,0 +1,60 @@
#!/bin/false
if [[ -z "$domain" || -z "$token" || -z "$owner" || -z "$repo" || -z "$description" || -z "$user" ]]; then
echo "Не указаны обязательные параметры." && exit 1
elif [ "$domain" != "codeberg.org" ]; then
echo "Некорректно указан сервер." && exit 1
fi
cd _site || exit 1
if [ -z "$1" ]; then
echo "Развёртывание копии вёб-сайта на сервере 'codeberg.page'."
fi
time_ms="$(date '+%s%3N')"
if [[ -z "$1" || "$1" == "remote" ]]; then
echo "Удаление старого репозитория на сервере."
curl -i -X DELETE "https://$domain/api/v1/repos/$owner/$repo" \
-H "Authorization: token $token" \
-H "Accept: application/json"
echo "Создание нового репозитория в группе на сервере."
curl -i -X POST "https://$domain/api/v1/orgs/$owner/repos" \
-H "Authorization: token $token" \
-H "Accept: application/json" \
-H "Content-Type: application/json" -d "{
\"name\": \"$repo\", \"description\": \"$description\" }"
echo "Изменение свойств репозитория / отключение ненужного."
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_projects\": false, \"has_issues\": false,
\"has_releases\": false, \"has_actions\": false,
\"has_packages\": false, \"has_pull_requests\": false,
\"has_wiki\": false }"
echo "Добавление аватарки для репозитория."
avatar=$(basenc "../../pomodoro/pictures/website.jpg" --base64 -w0)
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\" }"
fi
if [[ -z "$1" || "$1" == "local" ]]; then
echo "Пересоздание локального репозитория и отправка данных на сервер."
rm -rf ".git" # удаление старого репозитория
git init -b "master"
git remote add "$domain" "git@$domain:$owner/$repo.git"
git add --all
git commit -m "$(date '+%Y-%m-%d')"
git push -u "$domain" "master"
fi
if [ -z "$1" ]; then
echo "Ожидание 3 секунды." && sleep 3
fi
if [[ -z "$1" || "$1" == "testing" ]]; then
echo "Получение списка коммитов для удалённого репозитория."
param="stat=false&verification=false&files=false"
curl -i -X GET "https://$domain/api/v1/repos/$owner/$repo/commits?$param" \
-H "Authorization: token $token" \
-H "Accept: application/json"
fi
if [ -z "$1" ]; then
echo "Общее время выполнения: $(($(date '+%s%3N') - time_ms)) мс."
fi

View file

@ -6,14 +6,14 @@ if [ -z "$1" ]; then
echo "Создание удалённого репозитория для текущего каталога." echo "Создание удалённого репозитория для текущего каталога."
fi fi
time_ms="$(date '+%s%3N')" time_ms="$(date '+%s%3N')"
if [ -z "$1" ] || [ "$1" == "delete" ]; then if [[ -z "$1" || "$1" == "delete" ]]; then
echo "Удаление старого репозитория." echo "Удаление старого репозитория."
curl -i -X DELETE "https://$domain/api/v4/projects/$owner%2F$repo" \ curl -i -X DELETE "https://$domain/api/v4/projects/$owner%2F$repo" \
-H "PRIVATE-TOKEN: $token" \ -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
fi fi
if [ -z "$1" ] || [ "$1" == "create" ]; then if [[ -z "$1" || "$1" == "create" ]]; then
echo "Создание нового репозитория пользователя." echo "Создание нового репозитория пользователя."
curl -i -X POST "https://$domain/api/v4/projects" \ curl -i -X POST "https://$domain/api/v4/projects" \
-H "PRIVATE-TOKEN: $token" \ -H "PRIVATE-TOKEN: $token" \
@ -26,17 +26,8 @@ if [ -z "$1" ] || [ "$1" == "create" ]; then
echo echo
fi fi
fi fi
if [ -z "$1" ] || [ "$1" == "options" ]; then if [[ -z "$1" || "$1" == "options" ]]; then
if [ "$wiki" ]; then [ "$wiki" ] && has_wiki="enabled" || has_wiki="disabled"
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\" }"
echo
has_wiki="enabled"
else
has_wiki="disabled"
fi
echo "Изменение свойств репозитория / отключение ненужного." echo "Изменение свойств репозитория / отключение ненужного."
curl -i -X PUT "https://$domain/api/v4/projects/$owner%2F$repo" \ curl -i -X PUT "https://$domain/api/v4/projects/$owner%2F$repo" \
-H "PRIVATE-TOKEN: $token" \ -H "PRIVATE-TOKEN: $token" \
@ -58,11 +49,15 @@ if [ -z "$1" ] || [ "$1" == "options" ]; then
\"snippets_access_level\": \"disabled\", \"auto_devops_enabled\": \"false\", \"snippets_access_level\": \"disabled\", \"auto_devops_enabled\": \"false\",
\"shared_runners_enabled\": \"false\", \"group_runners_enabled\": \"false\" }" \"shared_runners_enabled\": \"false\", \"group_runners_enabled\": \"false\" }"
echo echo
echo "Добавление аватарки для репозитория." if [ "$wiki" ]; then
picture="$repo" echo "Добавление страницы wiki в репозиторий."
if [ "$user" != "$owner" ]; then curl -i -X POST "https://$domain/api/v4/projects/$owner%2F$repo/wikis" \
picture="website" -H "PRIVATE-TOKEN: $token" \
-H "Content-Type: application/json" -d "{ \"content\": \"$wiki\", \"title\": \"Home\" }"
echo
fi fi
echo "Добавление аватарки для репозитория."
[ "$user" != "$owner" ] && picture="website" || picture="$repo"
curl -i -X PUT "https://$domain/api/v4/projects/$owner%2F$repo" \ curl -i -X PUT "https://$domain/api/v4/projects/$owner%2F$repo" \
-H "PRIVATE-TOKEN: $token" \ -H "PRIVATE-TOKEN: $token" \
-F "avatar=@../pomodoro/pictures/$picture.jpg" -F "avatar=@../pomodoro/pictures/$picture.jpg"

View file

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

34
bash_scripts/repo_pages2.sh Executable file
View file

@ -0,0 +1,34 @@
#!/bin/bash
echo "Параллельное выполнение скриптов и развёртывание вёб-сайтов на сервере codeberg."
# обработка репозитория вёб-сайта
function pages2 {
echo "Обработка: $1"
cd "./$1" || return
for ((time_ms = "$(date '+%s%3N')"; $(date '+%s%3N') - time_ms < 10000; )); do
# 1 Создание удалённого репозитория
./.repo_pages2.sh "remote" 2>/dev/null >.repo_pages2.log
# 2 Проверка корректности ответов от сервера при создании репозитория
case "$(tail -n+10 .repo_pages2.log | grep -cE '^HTTP/[1,2].{,2}? [4,5]')" in
0) remote=true && break ;; *) echo "Ошибка 400-500 при подключении к серверу: $1" ;;
esac
done
if [ "$remote" != true ]; then echo "Ожидание более 10 секунд: $1" && return; else
# 3 Создание локального репозитория и отправка данных на сервер
./.repo_pages2.sh "local" 2>/dev/null >>.repo_pages2.log
fi
for ((time_ms = "$(date '+%s%3N')"; $(date '+%s%3N') - time_ms < 10000; )); do
# 4 Проверка корректности получения данных на сервере
case "$(./.repo_pages2.sh "testing" 2>/dev/null | grep -cE '^HTTP/[1,2].{,2}? [4,5]')" in
0) testing=true && break ;; *) echo "Ожидание данных на сервере: $1" && sleep 1 ;;
esac
done
if [ "$testing" != true ]; then echo "Ожидание более 10 секунд: $1"; fi
}
export -f pages2
cd ../.. # выход из папки и из репозитория
time_ms="$(date '+%s%3N')"
# запуск параллельной обработки репозиториев всех вёб-сайтов
printf 'pages2 "pomodoro%s"\0' {1..6} | 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"