This commit is contained in:
2026-04-27 04:31:32 +03:30
commit 8feb949d7d
8 changed files with 773 additions and 0 deletions
View File
+236
View File
@@ -0,0 +1,236 @@
# اسکریپت‌های مدیریت ماژول‌ها
این ریپو چند اسکریپت کمکی برای مدیریت ماژول‌ها، ساب‌ماژول `Schemas` و اجرای Docker دارد. در این فایل، کاربرد هر اسکریپت و نحوه استفاده از آن به فارسی توضیح داده شده است.
## 1) افزودن همه ماژول‌ها به‌صورت submodule
فایل:
```bash
./add_submodules.sh
```
کار این اسکریپت:
- ماژول‌های `Ai`، `SensorHub`، `Backend`، `Accsess` و `Schemas` را به‌صورت submodule اضافه می‌کند
- branch پیش‌فرض روی `develop` است
- اگر submodule از قبل ثبت شده باشد، همان ماژول را skip می‌کند
استفاده:
```bash
./add_submodules.sh
```
اگر می‌خواهید `git submodule add` با `--force` اجرا شود:
```bash
./add_submodules.sh --force
```
## 2) افزودن `Schemas` به پروژه‌ها
فایل:
```bash
./add_schemas_submodule.sh
```
کار این اسکریپت:
- ساب‌ماژول `Schemas` را داخل پروژه‌های `Ai`، `Backend` و `SensorHub` اضافه می‌کند
- اگر `Schemas` از قبل اضافه شده باشد، آن پروژه را رد می‌کند
- اگر پوشه `Schemas` از قبل وجود داشته باشد، چیزی را overwrite نمی‌کند
استفاده:
```bash
./add_schemas_submodule.sh
```
اگر می‌خواهید `git submodule add` با `--force` اجرا شود:
```bash
./add_schemas_submodule.sh --force
```
فقط برای بعضی پروژه‌ها:
```bash
./add_schemas_submodule.sh Ai Backend
```
ترکیب با `--force`:
```bash
./add_schemas_submodule.sh --force Ai Backend
```
اگر آدرس ریپوی `Schemas` تغییر کرد:
```bash
SCHEMAS_REPO_URL="ssh://git@host:port/path/Schemas.git" ./add_schemas_submodule.sh
```
## 3) pull گرفتن از `Schemas` داخل پروژه‌ها
فایل:
```bash
./pull_schemas_submodule.sh
```
کار این اسکریپت:
- داخل `Ai`، `Backend` و `SensorHub` می‌رود
- اگر `Schemas` به‌عنوان submodule وجود داشته باشد، روی آن `git pull --ff-only` اجرا می‌کند
- اگر submodule هنوز initialize نشده باشد، آن پروژه را رد می‌کند
استفاده:
```bash
./pull_schemas_submodule.sh
```
فقط برای بعضی پروژه‌ها:
```bash
./pull_schemas_submodule.sh Ai SensorHub
```
## 4) pull گرفتن از همه ماژول‌ها
فایل:
```bash
./pull_all_modules.sh
```
کار این اسکریپت:
- روی ماژول‌های اصلی `Accsess`، `Ai`، `Backend`، `Schemas` و `SensorHub` دستور `git pull --ff-only` اجرا می‌کند
- اگر داخل هر ماژول submodule وجود داشته باشد:
- ابتدا `submodule update --init --recursive` اجرا می‌کند
- سپس روی submoduleهای داخلی هم `git pull --ff-only` اجرا می‌کند
استفاده:
```bash
./pull_all_modules.sh
```
فقط برای چند ماژول مشخص:
```bash
./pull_all_modules.sh Ai Backend
```
## 5) اجرای Docker برای ماژول‌ها
فایل:
```bash
./run_docker_modules.sh
```
کار این اسکریپت:
- همه پوشه‌های داخل ریشه پروژه را بررسی می‌کند
- هر پوشه‌ای که فایل Docker Compose داشته باشد اجرا می‌شود
- این فایل‌ها پشتیبانی می‌شوند:
- `docker-compose.yaml`
- `docker-compose.yml`
- `compose.yaml`
- `compose.yml`
- اجرای پیش‌فرض به شکل detached است:
- `docker compose up -d`
استفاده:
```bash
./run_docker_modules.sh
```
فقط برای چند ماژول مشخص:
```bash
./run_docker_modules.sh Ai Backend
```
### اجرای Docker با build
اگر بخواهید قبل از اجرا build هم انجام شود، از فلگ `--build` استفاده کنید:
```bash
./run_docker_modules.sh --build
```
برای چند ماژول مشخص همراه با build:
```bash
./run_docker_modules.sh --build Ai SensorHub
```
### راهنمای اسکریپت Docker
```bash
./run_docker_modules.sh --help
```
## 6) bootstrap کامل ماژول‌ها
فایل:
```bash
./bootstrap_modules.sh
```
کار این اسکریپت:
- در step 1 اسکریپت `add_submodules.sh` را اجرا می‌کند
- در step 2 اسکریپت `add_schemas_submodule.sh` را اجرا می‌کند
- در step 3 اسکریپت `run_docker_modules.sh` را اجرا می‌کند
- می‌تواند `--force` را به اسکریپت‌های add و `--build` را به Docker پاس بدهد
استفاده:
```bash
./bootstrap_modules.sh
```
اجرا فقط تا step 2:
```bash
./bootstrap_modules.sh --step 2
```
اجرا با `--force`:
```bash
./bootstrap_modules.sh --force
```
اجرا با `--force` فقط تا step 2:
```bash
./bootstrap_modules.sh --force --step 2
```
اجرا با build برای Docker:
```bash
./bootstrap_modules.sh --build
```
## نکات مهم
- تمام اسکریپت‌ها طوری نوشته شده‌اند که اگر مسیر موردنظر git repo نباشد یا فایل لازم را نداشته باشد، به‌جای خطای مخرب، آن مورد را skip کنند
- در اسکریپت‌های pull از `--ff-only` استفاده شده تا merge ناخواسته ایجاد نشود
- قبل از اجرا، مطمئن شوید اسکریپت‌ها executable هستند:
```bash
chmod +x add_schemas_submodule.sh
chmod +x pull_schemas_submodule.sh
chmod +x pull_all_modules.sh
chmod +x run_docker_modules.sh
```
+92
View File
@@ -0,0 +1,92 @@
#!/usr/bin/env bash
set -euo pipefail
SCHEMAS_REPO_URL="${SCHEMAS_REPO_URL:-ssh://git@git.crop-logic.ir:2222/sajad-dev/Schemas.git}"
TARGET_BRANCH="${TARGET_BRANCH:-develop}"
FORCE_SUBMODULE_ADD=false
usage() {
cat <<'EOF'
Usage: ./add_schemas_submodule.sh [--force|-f] [repo...]
Options:
-f, --force Pass --force to `git submodule add`
EOF
}
TARGET_REPOS=()
while [[ "$#" -gt 0 ]]; do
case "$1" in
-f|--force)
FORCE_SUBMODULE_ADD=true
;;
-h|--help)
usage
exit 0
;;
--)
shift
while [[ "$#" -gt 0 ]]; do
TARGET_REPOS+=("$1")
shift
done
break
;;
*)
TARGET_REPOS+=("$1")
;;
esac
shift
done
if [[ "${#TARGET_REPOS[@]}" -eq 0 ]]; then
TARGET_REPOS=("Ai" "Backend" "SensorHub")
fi
add_schemas_submodule() {
local repo_dir="$1"
local submodule_path="Schemas"
local submodule_dir="${repo_dir}/${submodule_path}"
local add_args=(-b "$TARGET_BRANCH")
if [[ "$FORCE_SUBMODULE_ADD" == true ]]; then
add_args+=(--force)
fi
if ! git -C "$repo_dir" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "Skipping ${repo_dir}: not a git repository."
return 0
fi
if git -C "$repo_dir" config --file .gitmodules --get-regexp "submodule\\..*\\.path" 2>/dev/null \
| awk '{print $2}' \
| grep -Fxq "$submodule_path"; then
echo "Skipping ${repo_dir}: ${submodule_path} submodule already exists."
return 0
fi
if [[ -e "${repo_dir}/${submodule_path}" ]]; then
echo "Skipping ${repo_dir}: ${repo_dir}/${submodule_path} already exists."
return 0
fi
echo "Adding ${submodule_path} to ${repo_dir} on branch ${TARGET_BRANCH}"
git -C "$repo_dir" submodule add "${add_args[@]}" "$SCHEMAS_REPO_URL"
git -C "$submodule_dir" fetch origin "$TARGET_BRANCH"
if git -C "$submodule_dir" show-ref --verify --quiet "refs/heads/${TARGET_BRANCH}"; then
git -C "$submodule_dir" checkout "$TARGET_BRANCH"
else
git -C "$submodule_dir" checkout -b "$TARGET_BRANCH" "origin/${TARGET_BRANCH}"
fi
echo "Checked out ${submodule_dir} on ${TARGET_BRANCH}"
}
for repo_dir in "${TARGET_REPOS[@]}"; do
add_schemas_submodule "$repo_dir"
done
echo "Done."
+97
View File
@@ -0,0 +1,97 @@
#!/usr/bin/env bash
set -euo pipefail
BASE_URL="ssh://git@git.crop-logic.ir:2222/sajad-dev"
TARGET_BRANCH="${TARGET_BRANCH:-develop}"
FORCE_SUBMODULE_ADD=false
MODULES=(
"Ai"
"SensorHub"
"Backend"
"Accsess"
"Schemas"
)
usage() {
cat <<'EOF'
Usage: ./add_submodules.sh [--force|-f]
Options:
-f, --force Pass --force to `git submodule add`
EOF
}
while [[ "$#" -gt 0 ]]; do
case "$1" in
-f|--force)
FORCE_SUBMODULE_ADD=true
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown argument: $1" >&2
usage >&2
exit 1
;;
esac
shift
done
ensure_gitmodules_file() {
if [[ ! -f ".gitmodules" ]]; then
touch .gitmodules
echo "Created empty .gitmodules"
fi
}
checkout_target_branch() {
local repo_dir="$1"
git -C "$repo_dir" fetch origin "$TARGET_BRANCH"
if git -C "$repo_dir" show-ref --verify --quiet "refs/heads/${TARGET_BRANCH}"; then
git -C "$repo_dir" checkout "$TARGET_BRANCH"
else
git -C "$repo_dir" checkout -b "$TARGET_BRANCH" "origin/${TARGET_BRANCH}"
fi
}
ensure_gitmodules_file
for module in "${MODULES[@]}"; do
repo_url="${BASE_URL}/${module}.git"
add_args=(-b "$TARGET_BRANCH")
if [[ "$FORCE_SUBMODULE_ADD" == true ]]; then
add_args+=(--force)
fi
if git config --file .gitmodules --get-regexp "submodule\\..*\\.path" 2>/dev/null | awk '{print $2}' | grep -Fxq "$module"; then
echo "Skipping ${module}: submodule already exists."
else
echo "Adding ${module} from ${repo_url} on branch ${TARGET_BRANCH}"
git submodule add "${add_args[@]}" "$repo_url"
fi
checkout_target_branch "$module"
echo "Checked out ${module} on ${TARGET_BRANCH}"
env_example_path="${module}/.env.example"
env_path="${module}/.env"
if [[ -f "$env_example_path" ]]; then
if [[ -f "$env_path" ]]; then
echo "Skipping ${module}: .env already exists."
else
cp "$env_example_path" "$env_path"
echo "Created ${env_path} from .env.example"
fi
else
echo "Skipping ${module}: .env.example not found."
fi
done
echo "Done."
+122
View File
@@ -0,0 +1,122 @@
#!/usr/bin/env bash
set -euo pipefail
BUILD_FLAG=0
FORCE_FLAG=0
DOCKER_MODULES=()
MAX_STEP=3
usage() {
cat <<'EOF'
Usage:
./bootstrap_modules.sh [--build] [--force] [--step N] [module ...]
Steps:
1. Run `add_submodules.sh`
2. Run `add_schemas_submodule.sh`
3. Run `run_docker_modules.sh`
Options:
--build Pass `--build` to `run_docker_modules.sh`
--force Pass `--force` to submodule add scripts
--step N Run only up to step N (1, 2, or 3)
-h, --help Show this help message
Examples:
./bootstrap_modules.sh
./bootstrap_modules.sh --step 2
./bootstrap_modules.sh --force
./bootstrap_modules.sh --build
./bootstrap_modules.sh Ai Backend
./bootstrap_modules.sh --build Ai SensorHub
./bootstrap_modules.sh --force --step 2
EOF
}
while [[ "$#" -gt 0 ]]; do
case "$1" in
--build)
BUILD_FLAG=1
shift
;;
--force)
FORCE_FLAG=1
shift
;;
--step)
if [[ "$#" -lt 2 ]]; then
echo "Missing value for --step" >&2
usage
exit 1
fi
MAX_STEP="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
--)
shift
while [[ "$#" -gt 0 ]]; do
DOCKER_MODULES+=("$1")
shift
done
;;
-*)
echo "Unknown option: $1" >&2
usage
exit 1
;;
*)
DOCKER_MODULES+=("$1")
shift
;;
esac
done
if [[ ! "$MAX_STEP" =~ ^[1-3]$ ]]; then
echo "Invalid value for --step: ${MAX_STEP}. Use 1, 2, or 3." >&2
exit 1
fi
run_script() {
local script_path="$1"
shift || true
if [[ ! -x "$script_path" ]]; then
echo "Script is not executable: ${script_path}" >&2
exit 1
fi
echo "Running ${script_path} $*"
"$script_path" "$@"
}
submodule_args=()
if [[ "$FORCE_FLAG" -eq 1 ]]; then
submodule_args+=("--force")
fi
if [[ "$MAX_STEP" -ge 1 ]]; then
run_script "./add_submodules.sh" "${submodule_args[@]}"
fi
if [[ "$MAX_STEP" -ge 2 ]]; then
run_script "./add_schemas_submodule.sh" "${submodule_args[@]}"
fi
docker_args=()
if [[ "$BUILD_FLAG" -eq 1 ]]; then
docker_args+=("--build")
fi
if [[ "${#DOCKER_MODULES[@]}" -gt 0 ]]; then
docker_args+=("${DOCKER_MODULES[@]}")
fi
if [[ "$MAX_STEP" -ge 3 ]]; then
run_script "./run_docker_modules.sh" "${docker_args[@]}"
fi
echo "Bootstrap completed."
+58
View File
@@ -0,0 +1,58 @@
#!/usr/bin/env bash
set -euo pipefail
TARGET_BRANCH="${TARGET_BRANCH:-develop}"
if [[ "$#" -gt 0 ]]; then
TARGET_MODULES=("$@")
else
TARGET_MODULES=("Accsess" "Ai" "Backend" "Schemas" "SensorHub")
fi
checkout_and_pull_branch() {
local repo_dir="$1"
git -C "$repo_dir" fetch origin "$TARGET_BRANCH"
if git -C "$repo_dir" show-ref --verify --quiet "refs/heads/${TARGET_BRANCH}"; then
git -C "$repo_dir" checkout "$TARGET_BRANCH"
else
git -C "$repo_dir" checkout -b "$TARGET_BRANCH" "origin/${TARGET_BRANCH}"
fi
git -C "$repo_dir" pull --ff-only origin "$TARGET_BRANCH"
}
pull_repo() {
local repo_dir="$1"
if ! git -C "$repo_dir" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "Skipping ${repo_dir}: not a git repository."
return 0
fi
echo "Pulling ${repo_dir} on branch ${TARGET_BRANCH}"
checkout_and_pull_branch "$repo_dir"
if [[ -f "${repo_dir}/.gitmodules" ]]; then
echo "Updating nested submodules in ${repo_dir}"
git -C "$repo_dir" submodule update --init --recursive
git -C "$repo_dir" submodule foreach --recursive "
echo \"Updating \${displaypath} on branch ${TARGET_BRANCH}\"
git fetch origin ${TARGET_BRANCH}
if git show-ref --verify --quiet refs/heads/${TARGET_BRANCH}; then
git checkout ${TARGET_BRANCH}
else
git checkout -b ${TARGET_BRANCH} origin/${TARGET_BRANCH}
fi
git pull --ff-only origin ${TARGET_BRANCH}
"
fi
}
for module_dir in "${TARGET_MODULES[@]}"; do
pull_repo "$module_dir"
done
echo "Done."
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env bash
set -euo pipefail
TARGET_BRANCH="${TARGET_BRANCH:-develop}"
if [[ "$#" -gt 0 ]]; then
TARGET_REPOS=("$@")
else
TARGET_REPOS=("Ai" "Backend" "SensorHub")
fi
pull_schemas_submodule() {
local repo_dir="$1"
local submodule_path="Schemas"
local submodule_dir="${repo_dir}/${submodule_path}"
if ! git -C "$repo_dir" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "Skipping ${repo_dir}: not a git repository."
return 0
fi
if ! git -C "$submodule_dir" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "Skipping ${repo_dir}: ${submodule_path} submodule is not initialized."
return 0
fi
echo "Updating ${submodule_path} in ${repo_dir} on branch ${TARGET_BRANCH}"
git -C "$submodule_dir" fetch origin "$TARGET_BRANCH"
if git -C "$submodule_dir" show-ref --verify --quiet "refs/heads/${TARGET_BRANCH}"; then
git -C "$submodule_dir" checkout "$TARGET_BRANCH"
else
git -C "$submodule_dir" checkout -b "$TARGET_BRANCH" "origin/${TARGET_BRANCH}"
fi
git -C "$submodule_dir" pull --ff-only origin "$TARGET_BRANCH"
}
for repo_dir in "${TARGET_REPOS[@]}"; do
pull_schemas_submodule "$repo_dir"
done
echo "Done."
+124
View File
@@ -0,0 +1,124 @@
#!/usr/bin/env bash
set -euo pipefail
BUILD_FLAG=0
TARGET_MODULES=()
usage() {
cat <<'EOF'
Usage:
./run_docker_modules.sh [--build] [module ...]
Options:
--build Run `docker compose up --build -d`
-h, --help Show this help message
Examples:
./run_docker_modules.sh
./run_docker_modules.sh --build
./run_docker_modules.sh Ai Backend
./run_docker_modules.sh --build Ai SensorHub
EOF
}
while [[ "$#" -gt 0 ]]; do
case "$1" in
--build)
BUILD_FLAG=1
shift
;;
-h|--help)
usage
exit 0
;;
--)
shift
while [[ "$#" -gt 0 ]]; do
TARGET_MODULES+=("$1")
shift
done
;;
-*)
echo "Unknown option: $1" >&2
usage
exit 1
;;
*)
TARGET_MODULES+=("$1")
shift
;;
esac
done
find_compose_file() {
local module_dir="$1"
local candidates=(
"docker-compose.yaml"
"docker-compose.yml"
"compose.yaml"
"compose.yml"
)
local candidate
for candidate in "${candidates[@]}"; do
if [[ -f "${module_dir}/${candidate}" ]]; then
printf '%s\n' "${candidate}"
return 0
fi
done
return 1
}
collect_modules_with_compose() {
local dir
for dir in */ ; do
dir="${dir%/}"
[[ -d "$dir" ]] || continue
if find_compose_file "$dir" >/dev/null; then
printf '%s\n' "$dir"
fi
done
}
run_module() {
local module_dir="$1"
local compose_file
local compose_path
if [[ ! -d "$module_dir" ]]; then
echo "Skipping ${module_dir}: directory not found."
return 0
fi
if ! compose_file="$(find_compose_file "$module_dir")"; then
echo "Skipping ${module_dir}: no docker compose file found."
return 0
fi
compose_path="${module_dir}/${compose_file}"
echo "Starting ${module_dir} with ${compose_file}"
if [[ "$BUILD_FLAG" -eq 1 ]]; then
docker compose -f "${compose_path}" up --build -d
else
docker compose -f "${compose_path}" up -d
fi
}
if [[ "${#TARGET_MODULES[@]}" -eq 0 ]]; then
mapfile -t TARGET_MODULES < <(collect_modules_with_compose)
fi
if [[ "${#TARGET_MODULES[@]}" -eq 0 ]]; then
echo "No modules with docker compose files found."
exit 0
fi
for module_dir in "${TARGET_MODULES[@]}"; do
run_module "$module_dir"
done
echo "Done."