#!/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 ################################################################################ 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 GitLab API base URL (e.g., https://gitlab.com) -t, --token Private access token -r, --repo Repository path (e.g., group/project) -d, --dest Destination directory for clone / transformation source -f, --transform Path to transform.env file (default: ./transform.env) --gitea-repo 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: ===" 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% -> 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% -> 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||$service_name|g" -e "s||$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// mkdir -p "$DEST_DIR/src/$CONTAINERS_SUBDIR" print_info "Step 2/6: Created directory src/$CONTAINERS_SUBDIR" # 3) Move _src -> src// 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//) 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// 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