Files
italiadatacenter/st2idc/clone-and-transform.sh
T
2026-08-26 10:45:35 +02:00

774 lines
26 KiB
Bash

#!/bin/bash
################################################################################
# Script: clone-and-transform.sh
# Description: Clone GitLab repository using private token and apply
# string substitutions from transform.env
# Usage: ./clone-and-transform.sh <gitlab-url> <token> <repo-path> <dest-dir>
################################################################################
set -e # Exit on error
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to print colored output
print_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
# Function to display usage
usage() {
cat << EOF
Usage: $0 [OPTIONS]
OPTIONS:
-u, --url <URL> GitLab API base URL (e.g., https://gitlab.com)
-t, --token <TOKEN> Private access token
-r, --repo <REPO-PATH> Repository path (e.g., group/project)
-d, --dest <DEST-DIR> Destination directory for clone / transformation source
-f, --transform <FILE> Path to transform.env file (default: ./transform.env)
--gitea-repo <REPO-PATH> Repository path to clone from Gitea (default: same as --repo)
-transformation Skip GitLab clone; run Gitea clone + transform + commit/push
-h, --help Show this help message
Example:
$0 -u https://gitlab.com -t glpat-xxxxx -r mygroup/myproject -d ./cloned-repo
$0 -transformation -d ./existing-repo --gitea-repo mygroup/myproject -f ./transform.env
EOF
exit 1
}
# Default values
GITLAB_URL=""
PRIVATE_TOKEN=""
REPO_PATH=""
DEST_DIR=""
TRANSFORM_FILE="./transform.env"
GITEA_URL="https://git.italiadatacenter.com"
GITEA_TOKEN="65fc5f07365bd3f89c5b9ddca3d2d2e7b3777a88"
GITEA_REPO_PATH=""
GITEA_DEST_DIR="target-repo"
TRANSFORMATION_ONLY=false
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
-u|--url)
GITLAB_URL="$2"
shift 2
;;
-t|--token)
PRIVATE_TOKEN="$2"
shift 2
;;
-r|--repo)
REPO_PATH="$2"
shift 2
;;
-d|--dest)
DEST_DIR="$2"
shift 2
;;
-f|--transform)
TRANSFORM_FILE="$2"
shift 2
;;
--gitea-repo)
GITEA_REPO_PATH="$2"
shift 2
;;
-transformation)
TRANSFORMATION_ONLY=true
shift
;;
-h|--help)
usage
;;
*)
print_error "Unknown option: $1"
usage
;;
esac
done
# Validate required parameters
if [[ "$TRANSFORMATION_ONLY" == true ]]; then
if [[ -z "$DEST_DIR" ]]; then
print_error "Missing required parameter: --dest"
usage
fi
else
if [[ -z "$GITLAB_URL" ]] || [[ -z "$PRIVATE_TOKEN" ]] || [[ -z "$REPO_PATH" ]] || [[ -z "$DEST_DIR" ]]; then
print_error "Missing required parameters"
usage
fi
fi
# Check if transform.env exists
if [[ ! -f "$TRANSFORM_FILE" ]]; then
print_error "Transform file not found: $TRANSFORM_FILE"
exit 1
fi
# Validate transform.env format
if ! grep -Eq '^[[:space:]]*[^#[:space:]].*===.*$' "$TRANSFORM_FILE"; then
print_error "Transform file format invalid. Expected: <old_string>===<new_string>"
exit 1
fi
if [[ "$TRANSFORMATION_ONLY" == true ]]; then
print_info "Mode: transformation only (GitLab clone skipped)"
else
print_info "Starting GitLab repository clone and transformation..."
print_info "GitLab URL: $GITLAB_URL"
print_info "Repository: $REPO_PATH"
fi
print_info "Destination: $DEST_DIR"
print_info "Transform file: $TRANSFORM_FILE"
print_info "Gitea instance: $GITEA_URL"
print_info "Gitea destination: $GITEA_DEST_DIR"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
HTTPROUTE_TEMPLATE_FILE="$SCRIPT_DIR/httproute.yaml"
if [[ "$TRANSFORMATION_ONLY" == false ]]; then
# Build repository URLs
BASE_URL="${GITLAB_URL%/}"
if [[ ! "$BASE_URL" =~ ^https?:// ]]; then
print_error "GitLab URL must start with http:// or https://"
exit 1
fi
TARGET_REPO_URL="${BASE_URL}/${REPO_PATH}.git"
AUTH_REPO_URL="$(printf '%s\n' "$TARGET_REPO_URL" | sed -E "s#^(https?://)#\\1oauth2:${PRIVATE_TOKEN}@#")"
# Always use a fresh clone to avoid stale/outdated repository state
if [[ -e "$DEST_DIR" ]]; then
if [[ -z "$DEST_DIR" || "$DEST_DIR" == "/" || "$DEST_DIR" == "." ]]; then
print_error "Refusing to remove unsafe destination path: $DEST_DIR"
exit 1
fi
print_info "Destination already exists, removing it before clone: $DEST_DIR"
rm -rf -- "$DEST_DIR"
fi
print_info "Cloning repository..."
print_info "Running: git clone $(printf '%s' "$AUTH_REPO_URL" | sed -E 's#(https?://)[^@]+@#\1***@#') $DEST_DIR"
GIT_TERMINAL_PROMPT=0 git clone --quiet "$AUTH_REPO_URL" "$DEST_DIR" 2>/dev/null || {
print_error "Failed to clone repository"
print_info "Ensure your token has 'api' or 'read_repository' scope"
exit 1
}
print_info "Repository cloned successfully"
fi # end TRANSFORMATION_ONLY skip
# Clone additional repository from Gitea into target-repo
if [[ -z "$GITEA_REPO_PATH" ]]; then
GITEA_REPO_PATH="$REPO_PATH"
fi
GITEA_BASE_URL="${GITEA_URL%/}"
if [[ ! "$GITEA_BASE_URL" =~ ^https?:// ]]; then
print_error "Gitea URL must start with http:// or https://"
exit 1
fi
GITEA_TARGET_REPO_URL="${GITEA_BASE_URL}/${GITEA_REPO_PATH}.git"
GITEA_AUTH_REPO_URL="$(printf '%s\n' "$GITEA_TARGET_REPO_URL" | sed -E "s#^(https?://)#\\1${GITEA_TOKEN}@#")"
if [[ -e "$GITEA_DEST_DIR" ]]; then
if [[ -z "$GITEA_DEST_DIR" || "$GITEA_DEST_DIR" == "/" || "$GITEA_DEST_DIR" == "." ]]; then
print_error "Refusing to remove unsafe destination path: $GITEA_DEST_DIR"
exit 1
fi
print_info "Gitea destination already exists, removing it before clone: $GITEA_DEST_DIR"
rm -rf -- "$GITEA_DEST_DIR"
fi
print_info "Cloning additional repository from Gitea..."
print_info "Running: git clone $(printf '%s' "$GITEA_AUTH_REPO_URL" | sed -E 's#(https?://)[^@]+@#\1***@#') $GITEA_DEST_DIR"
GIT_TERMINAL_PROMPT=0 git clone --quiet "$GITEA_AUTH_REPO_URL" "$GITEA_DEST_DIR" 2>/dev/null || {
print_error "Failed to clone additional Gitea repository"
print_info "Check Gitea token permissions and repository path"
exit 1
}
print_info "Additional Gitea repository cloned successfully"
# In transformation-only mode, seed DEST_DIR from the freshly cloned Gitea repo
if [[ "$TRANSFORMATION_ONLY" == true ]]; then
if [[ -e "$DEST_DIR" ]]; then
if [[ -z "$DEST_DIR" || "$DEST_DIR" == "/" || "$DEST_DIR" == "." ]]; then
print_error "Refusing to remove unsafe destination path: $DEST_DIR"
exit 1
fi
print_info "Removing existing DEST_DIR before seeding from Gitea: $DEST_DIR"
rm -rf -- "$DEST_DIR"
fi
print_info "Copying Gitea clone ($GITEA_DEST_DIR) -> $DEST_DIR ..."
cp -R "$GITEA_DEST_DIR" "$DEST_DIR"
print_info "Copy completed"
fi
# Check if target directories exist
DIRS_TO_PROCESS=("kubernetes" "container" "conf" "envs")
FOUND_DIRS=()
for dir in "${DIRS_TO_PROCESS[@]}"; do
if [[ -d "$DEST_DIR/$dir" ]]; then
FOUND_DIRS+=("$dir")
print_info "Found directory: $dir"
fi
done
# Also search for envs directories nested in subdirectories
while IFS= read -r envs_abs; do
envs_rel="${envs_abs#${DEST_DIR}/}"
# Skip top-level envs (already handled above)
if [[ "$envs_rel" != "envs" ]]; then
FOUND_DIRS+=("$envs_rel")
print_info "Found nested envs directory: $envs_rel"
fi
done < <(find "$DEST_DIR" -mindepth 2 -type d -name "envs" 2>/dev/null)
if [[ ${#FOUND_DIRS[@]} -eq 0 ]]; then
print_warning "No target directories (kubernetes/container/conf/envs) found in cloned repository"
fi
# Function to apply transformations to a file
apply_transformations() {
local file="$1"
local temp_file
local changes=0
temp_file="$(mktemp "${file}.tmp.XXXXXX")"
# Create a copy
cp "$file" "$temp_file"
# Apply each transformation from transform.env (format: old_string===new_string)
while IFS= read -r line || [[ -n "$line" ]]; do
# Skip empty lines and comments
[[ -z "$line" ]] && continue
[[ "$line" =~ ^[[:space:]]*# ]] && continue
[[ "$line" != *"==="* ]] && continue
local old_string new_string
old_string="${line%%===*}"
new_string="${line#*===}"
# Trim whitespace
old_string=$(echo "$old_string" | xargs)
new_string=$(echo "$new_string" | xargs)
# Check if substitution would occur
if grep -Fq -- "$old_string" "$temp_file" 2>/dev/null; then
# Use sed with proper escaping for replacement
local old_escaped new_escaped
old_escaped=$(printf '%s\n' "$old_string" | sed 's/[&|\\]/\\&/g')
new_escaped=$(printf '%s\n' "$new_string" | sed 's/[&|\\]/\\&/g')
sed -i "s|${old_escaped}|${new_escaped}|g" "$temp_file"
changes=$((changes + 1))
fi
done < "$TRANSFORM_FILE"
# Compare and update if changes were made
if ! diff -q "$file" "$temp_file" > /dev/null 2>&1; then
mv "$temp_file" "$file"
return 0
else
rm "$temp_file"
return 1
fi
}
# Function to apply automatic placeholder transformation: %string% -> <string>
apply_placeholder_transformations() {
local file="$1"
local temp_file
temp_file="$(mktemp "${file}.tmp.XXXXXX")"
cp "$file" "$temp_file"
# Convert placeholders enclosed in %...% to <...>
sed -i -E 's/%([^%]+)%/<\1>/g' "$temp_file"
if ! diff -q "$file" "$temp_file" > /dev/null 2>&1; then
mv "$temp_file" "$file"
return 0
else
rm "$temp_file"
return 1
fi
}
# Apply transformations to files in target directories
print_info "Applying transformations from $TRANSFORM_FILE..."
total_files=0
modified_files=0
for dir in "${FOUND_DIRS[@]}"; do
target_path="$DEST_DIR/$dir"
print_info "Processing directory: $dir"
# Find all files in the directory and its subdirectories
while IFS= read -r file; do
total_files=$((total_files + 1))
# Skip binary files
if file "$file" | grep -q "binary"; then
print_warning "Skipping binary file: $file"
continue
fi
if apply_transformations "$file"; then
print_info " Modified: $file"
modified_files=$((modified_files + 1))
fi
done < <(find "$target_path" -type f 2>/dev/null)
done
# Apply automatic %string% -> <string> transformation to all files in target directory
print_info "Applying automatic placeholder transformation (%...% -> <...>) in $DEST_DIR..."
placeholder_total_files=0
placeholder_modified_files=0
while IFS= read -r file; do
placeholder_total_files=$((placeholder_total_files + 1))
# Skip binary files
if file "$file" | grep -q "binary"; then
print_warning "Skipping binary file: $file"
continue
fi
if apply_placeholder_transformations "$file"; then
print_info " Placeholder updated: $file"
placeholder_modified_files=$((placeholder_modified_files + 1))
fi
done < <(find "$DEST_DIR" -type f 2>/dev/null)
# Post-transformation directory operations on DEST_DIR
if [[ "$TRANSFORMATION_ONLY" == false ]]; then
print_info "Applying post-transformation directory operations on $DEST_DIR..."
# 1) Rename container -> containers
if [[ -d "$DEST_DIR/container" ]]; then
mv -- "$DEST_DIR/container" "$DEST_DIR/containers"
print_info "Renamed: container -> containers"
else
print_warning "Directory not found, skipping rename: $DEST_DIR/container"
fi
# 2) Rename conf -> env (fail if env already exists)
if [[ -d "$DEST_DIR/conf" ]]; then
if [[ -e "$DEST_DIR/env" ]]; then
print_error "Cannot rename conf -> env: destination $DEST_DIR/env already exists"
exit 1
fi
mv -- "$DEST_DIR/conf" "$DEST_DIR/env"
print_info "Renamed: conf -> env"
else
print_warning "Directory not found, skipping rename: $DEST_DIR/conf"
fi
# 3) Remove .git directory
if [[ -d "$DEST_DIR/.git" ]]; then
rm -rf -- "$DEST_DIR/.git"
print_info "Removed: $DEST_DIR/.git"
else
print_warning "Directory not found, skipping removal: $DEST_DIR/.git"
fi
# 4) Remove .gitlab-ci.yml
if [[ -f "$DEST_DIR/.gitlab-ci.yml" ]]; then
rm -f -- "$DEST_DIR/.gitlab-ci.yml"
print_info "Removed: $DEST_DIR/.gitlab-ci.yml"
else
print_warning "File not found, skipping removal: $DEST_DIR/.gitlab-ci.yml"
fi
# Summary
echo ""
print_info "========== TRANSFORMATION SUMMARY =========="
echo "Total files processed: $total_files"
echo "Files modified: $modified_files"
echo "Placeholder files scanned: $placeholder_total_files"
echo "Placeholder files modified: $placeholder_modified_files"
print_info "=========================================="
if [[ $modified_files -gt 0 ]]; then
print_info "Transformation completed successfully!"
else
print_warning "No files were modified. Check transform.env contents and patterns."
fi
# Rename configuration.txt -> values.env under env directory
if [[ -d "$DEST_DIR/env" ]]; then
print_info "Rinomino configuration.txt -> values.env in $DEST_DIR/env ..."
while IFS= read -r f; do
target_path="$(dirname "$f")/values.env"
mv -- "$f" "$target_path"
print_info " Renamed: $f -> $target_path"
done < <(find "$DEST_DIR/env" -type f -name "configuration.txt")
else
print_warning "Directory $DEST_DIR/env non trovata, skip rename configuration.txt"
fi
# Move env/configuration.env to DEST_DIR root as properties.env
if [[ -f "$DEST_DIR/env/configuration.env" ]]; then
if [[ -f "$DEST_DIR/properties.env" ]]; then
rm -f -- "$DEST_DIR/properties.env"
print_info "Removed existing file: $DEST_DIR/properties.env"
fi
mv -- "$DEST_DIR/env/configuration.env" "$DEST_DIR/properties.env"
print_info "Moved: $DEST_DIR/env/configuration.env -> $DEST_DIR/properties.env"
else
print_warning "File non trovato, skip move: $DEST_DIR/env/configuration.env"
fi
# If an Ingress resource exists in kubernetes YAMLs, generate httproute.yaml from template
# and remove Ingress resource definitions from manifests.
K8S_DIR="$DEST_DIR/kubernetes"
if [[ -d "$K8S_DIR" ]]; then
print_info "Checking Kubernetes manifests for Ingress resources in $K8S_DIR ..."
ingress_found=false
service_name=""
ingress_service_name=""
ingress_port=""
while IFS= read -r -d '' k8s_file; do
if [[ -z "$service_name" ]]; then
service_name="$(awk '
/^[[:space:]]*kind:[[:space:]]*Service([[:space:]]|$)/ { in_service=1; next }
in_service && /^[[:space:]]*kind:[[:space:]]*/ { in_service=0 }
in_service && /^[[:space:]]*name:[[:space:]]*/ {
value=$0
sub(/^[[:space:]]*name:[[:space:]]*/, "", value)
gsub(/[[:space:]]+$/, "", value)
print value
exit
}
' "$k8s_file")"
fi
if grep -Eq '^[[:space:]]*kind:[[:space:]]*Ingress([[:space:]]|$)' "$k8s_file"; then
ingress_found=true
if [[ -z "$ingress_port" ]]; then
ingress_port="$(awk '
/^[[:space:]]*kind:[[:space:]]*Ingress([[:space:]]|$)/ { in_ingress=1; next }
in_ingress && /^[[:space:]]*kind:[[:space:]]*/ { in_ingress=0 }
in_ingress && /^[[:space:]]*number:[[:space:]]*[0-9]+/ {
value=$0
sub(/.*number:[[:space:]]*/, "", value)
gsub(/[^0-9].*$/, "", value)
print value
exit
}
' "$k8s_file")"
fi
if [[ -z "$ingress_service_name" ]]; then
ingress_service_name="$(awk '
/^[[:space:]]*kind:[[:space:]]*Ingress([[:space:]]|$)/ { in_ingress=1; next }
in_ingress && /^[[:space:]]*kind:[[:space:]]*/ { in_ingress=0 }
in_ingress && /^[[:space:]]*name:[[:space:]]*/ {
value=$0
sub(/^[[:space:]]*name:[[:space:]]*/, "", value)
gsub(/[[:space:]]+$/, "", value)
print value
exit
}
' "$k8s_file")"
fi
fi
done < <(find "$K8S_DIR" -type f \( -name "*.yaml" -o -name "*.yml" \) -print0)
if [[ "$ingress_found" == true ]]; then
if [[ ! -f "$HTTPROUTE_TEMPLATE_FILE" ]]; then
print_error "HTTPRoute template not found: $HTTPROUTE_TEMPLATE_FILE"
exit 1
fi
if [[ -z "$service_name" ]]; then
service_name="$ingress_service_name"
fi
if [[ -z "$service_name" ]]; then
print_error "Cannot create HTTPRoute: service name not found in Kubernetes YAML"
exit 1
fi
if [[ -z "$ingress_port" ]]; then
print_error "Cannot create HTTPRoute: ingress port number not found in Kubernetes YAML"
exit 1
fi
httproute_output="$K8S_DIR/httproute.yaml"
sed -e "s|<svc-name>|$service_name|g" -e "s|<port>|$ingress_port|g" "$HTTPROUTE_TEMPLATE_FILE" > "$httproute_output"
print_info "Created HTTPRoute file: $httproute_output"
while IFS= read -r -d '' k8s_file; do
temp_k8s_file="$(mktemp "${k8s_file}.tmp.XXXXXX")"
awk '
function flush_doc() {
if (!doc_started) {
return
}
if (!doc_is_ingress) {
if (output_count > 0) {
printf "---\n"
}
printf "%s", doc
output_count++
}
doc = ""
doc_started = 0
doc_is_ingress = 0
}
/^[[:space:]]*---[[:space:]]*$/ {
flush_doc()
next
}
{
doc_started = 1
doc = doc $0 "\n"
if ($0 ~ /^[[:space:]]*kind:[[:space:]]*Ingress([[:space:]]|$)/) {
doc_is_ingress = 1
}
}
END {
flush_doc()
}
' "$k8s_file" > "$temp_k8s_file"
if [[ ! -s "$temp_k8s_file" ]]; then
rm -f -- "$k8s_file"
rm -f -- "$temp_k8s_file"
print_info "Removed ingress-only manifest file: $k8s_file"
else
mv -- "$temp_k8s_file" "$k8s_file"
fi
done < <(find "$K8S_DIR" -type f \( -name "*.yaml" -o -name "*.yml" \) -print0)
print_info "Ingress resource definitions removed from Kubernetes manifests"
else
print_info "No Ingress resource found in Kubernetes manifests"
fi
# If a PersistentVolume resource exists in kubernetes YAMLs,
# remove PersistentVolume resource definitions from manifests.
pv_found=false
while IFS= read -r -d '' k8s_file; do
if grep -Eq '^[[:space:]]*kind:[[:space:]]*PersistentVolume([[:space:]]|$)' "$k8s_file"; then
pv_found=true
break
fi
done < <(find "$K8S_DIR" -type f \( -name "*.yaml" -o -name "*.yml" \) -print0)
if [[ "$pv_found" == true ]]; then
print_info "PersistentVolume resources found, removing from Kubernetes manifests ..."
while IFS= read -r -d '' k8s_file; do
temp_k8s_file="$(mktemp "${k8s_file}.tmp.XXXXXX")"
awk '
function flush_doc() {
if (!doc_started) {
return
}
if (!doc_is_pv) {
if (output_count > 0) {
printf "---\n"
}
printf "%s", doc
output_count++
}
doc = ""
doc_started = 0
doc_is_pv = 0
}
/^[[:space:]]*---[[:space:]]*$/ {
flush_doc()
next
}
{
doc_started = 1
doc = doc $0 "\n"
if ($0 ~ /^[[:space:]]*kind:[[:space:]]*PersistentVolume([[:space:]]|$)/) {
doc_is_pv = 1
}
}
END {
flush_doc()
}
' "$k8s_file" > "$temp_k8s_file"
if [[ ! -s "$temp_k8s_file" ]]; then
rm -f -- "$k8s_file"
rm -f -- "$temp_k8s_file"
print_info "Removed persistent-volume-only manifest file: $k8s_file"
else
mv -- "$temp_k8s_file" "$k8s_file"
fi
done < <(find "$K8S_DIR" -type f \( -name "*.yaml" -o -name "*.yml" \) -print0)
print_info "PersistentVolume resource definitions removed from Kubernetes manifests"
else
print_info "No PersistentVolume resource found in Kubernetes manifests"
fi
# Normalize line endings to LF for kubernetes manifests.
while IFS= read -r -d '' k8s_file; do
sed -i 's/\r$//' "$k8s_file"
done < <(find "$K8S_DIR" -type f \( -name "*.yaml" -o -name "*.yml" \) -print0)
print_info "Normalized line endings to LF for Kubernetes YAML files"
else
print_warning "Directory not found, skipping Kubernetes ingress conversion: $K8S_DIR"
fi
# Conditional directory restructuring: check if src/ and containers/ exist,
# and if containers/ has exactly 1 subdirectory
print_info "Checking conditions for directory restructuring..."
SRC_PATH="$DEST_DIR/src"
CONTAINERS_PATH="$DEST_DIR/containers"
RESTRUCTURE=false
CONTAINERS_SUBDIR=""
if [[ -d "$SRC_PATH" ]]; then
print_info " ✓ Found: $SRC_PATH"
if [[ -d "$CONTAINERS_PATH" ]]; then
print_info " ✓ Found: $CONTAINERS_PATH"
# Count subdirectories in containers/
subdir_count=0
subdirs=()
while IFS= read -r subdir; do
subdirs+=("$subdir")
subdir_count=$((subdir_count + 1))
done < <(find "$CONTAINERS_PATH" -mindepth 1 -maxdepth 1 -type d)
if [[ $subdir_count -eq 1 ]]; then
CONTAINERS_SUBDIR="${subdirs[0]##*/}" # Extract basename
print_info " ✓ Found exactly 1 subdirectory in containers: $CONTAINERS_SUBDIR"
RESTRUCTURE=true
elif [[ $subdir_count -eq 0 ]]; then
print_warning " ✗ No subdirectories found in $CONTAINERS_PATH"
else
print_warning " ✗ Found $subdir_count subdirectories in $CONTAINERS_PATH (expected 1)"
fi
else
print_warning " ✗ Directory not found: $CONTAINERS_PATH"
fi
else
print_warning " ✗ Directory not found: $SRC_PATH"
fi
if [[ "$RESTRUCTURE" == true ]]; then
print_info "========== STARTING CONDITIONAL DIRECTORY RESTRUCTURING =========="
print_info "Target subdirectory name: $CONTAINERS_SUBDIR"
# 1) Rename src -> _src
if [[ -d "$SRC_PATH" ]]; then
mv -- "$SRC_PATH" "$DEST_DIR/_src"
print_info "Step 1/6: Renamed src -> _src"
fi
# 2) Create src/<containers_subdir>/
mkdir -p "$DEST_DIR/src/$CONTAINERS_SUBDIR"
print_info "Step 2/6: Created directory src/$CONTAINERS_SUBDIR"
# 3) Move _src -> src/<containers_subdir>/
mv -- "$DEST_DIR/_src" "$DEST_DIR/src/$CONTAINERS_SUBDIR/_src"
print_info "Step 3/6: Moved _src -> src/$CONTAINERS_SUBDIR/_src"
# 4) Rename _src -> src (within src/<containers_subdir>/)
mv -- "$DEST_DIR/src/$CONTAINERS_SUBDIR/_src" "$DEST_DIR/src/$CONTAINERS_SUBDIR/src"
print_info "Step 4/6: Renamed _src -> src/$CONTAINERS_SUBDIR/src"
# 5) Move *.json, *.js, .prettierrc from root to src/<containers_subdir>/
print_info "Step 5/6: Moving files from root to src/$CONTAINERS_SUBDIR/..."
# Move *.json files
while IFS= read -r json_file; do
if [[ -f "$json_file" ]]; then
mv -- "$json_file" "$DEST_DIR/src/$CONTAINERS_SUBDIR/"
print_info " Moved: $(basename "$json_file") -> src/$CONTAINERS_SUBDIR/"
fi
done < <(find "$DEST_DIR" -maxdepth 1 -type f -name "*.json")
# Move *.js files
while IFS= read -r js_file; do
if [[ -f "$js_file" ]]; then
mv -- "$js_file" "$DEST_DIR/src/$CONTAINERS_SUBDIR/"
print_info " Moved: $(basename "$js_file") -> src/$CONTAINERS_SUBDIR/"
fi
done < <(find "$DEST_DIR" -maxdepth 1 -type f -name "*.js")
# Move .prettierrc if exists
if [[ -f "$DEST_DIR/.prettierrc" ]]; then
mv -- "$DEST_DIR/.prettierrc" "$DEST_DIR/src/$CONTAINERS_SUBDIR/"
print_info " Moved: .prettierrc -> src/$CONTAINERS_SUBDIR/"
fi
# 6) Move envs/ directory if exists
if [[ -d "$DEST_DIR/envs" ]]; then
mv -- "$DEST_DIR/envs" "$DEST_DIR/src/$CONTAINERS_SUBDIR/"
print_info "Step 6/6: Moved envs directory -> src/$CONTAINERS_SUBDIR/envs"
else
print_warning "Step 6/6: envs directory not found at root, skipping move"
fi
print_info "========== DIRECTORY RESTRUCTURING COMPLETED SUCCESSFULLY =========="
else
print_info "Directory restructuring conditions not met, skipping directory reorganization"
fi
fi # end TRANSFORMATION_ONLY skip for directory operations
# Copy transformed content from source repo to target repo
print_info "Copying transformed content: $DEST_DIR -> $GITEA_DEST_DIR ..."
cp -R "./${DEST_DIR}/." "./${GITEA_DEST_DIR}/"
print_info "Copy completed"
# Commit and push changes on target Gitea repository with skip CI/CD marker
print_info "Preparing commit and push in $GITEA_DEST_DIR ..."
git -C "$GITEA_DEST_DIR" add -A
if git -C "$GITEA_DEST_DIR" diff --cached --quiet; then
print_warning "No changes detected in $GITEA_DEST_DIR, skipping commit and push"
else
COMMIT_MESSAGE="chore: sync transformed content [skip ci]"
git -C "$GITEA_DEST_DIR" commit -m "$COMMIT_MESSAGE"
git -C "$GITEA_DEST_DIR" push
print_info "Commit and push completed"
fi
exit 0